megacolorboy

Abdush Shakoor's Weblog

Writings, experiments & ideas.

Learning C# 10 and .NET Core 6

Getting back into the old roots again.

To those who haven't been following me a lot, I used to build games on Unity 3D and build desktop applications on .NET and C# during my university days.

Ever since I discovered PHP and Laravel, I never went back to .NET and now after taking a look at the Fortune benchmarks for .NET Core 6 vs Laravel, I decided to take some time out to learn it again.

I started two weeks ago and the learning curve seemed quite familiar due to previous development experiences. I don't know if it's me but I felt like Laravel might have borrowed a few concepts from .NET Core Framework but hey, everyone needs some sort of inspiration, right?

Unlike .NET, Laravel is usually and still is a "batteries included" type of framework and that helps you get the job done. However, from what I have researched, applications built on .NET seems to be more performant than applications built on Laravel.

So, what's the current progress?

Well, I haven't touched the ASP.MVC part yet as I'm geting myself familiar with the coding conventions, static typing (yes, it does take sometime to get used to) by writing some test console-based applications and solving Project Euler problems.

Hopefully, I'll be able to share about what I have learnt using the framework on this blog by either building new applications or rewriting some of my Laravel projects.

Stay tuned for more!

Containerize your Laravel application for Development

A short tutorial on how to containerize your Laravel application and use it for testing and development purposes.

Since I started exploring Docker containers during my spare time, I learnt how to containerize a Laravel application using Docker Compose.

In this guide, I'll show you how to containerize your application and by the end of this tutorial, you'll have your application running on four separate service containers:

  • App service running php7.4-fpm.
  • A database service running mysql-80.
  • An NGINX service.
  • A phpMyAdmin service for you to view and manage your database.

Prerequisites

  • You need to have Docker and Docker Compose installed on your system
  • A non-root user with sudo privileges (If you are using any UNIX-based environment).
  • An existing working Laravel project.

I tried this on my personal laptop that runs on Fedora Workstation 36 and hopefully, it should work on Windows and macOS as well. If you are a Windows user, I would recommend you to try WSL2 with Ubuntu installed in it.

Configure your app service

First, you need to create a Dockerfile for your app service in your project's root directory:

touch Dockerfile
vim Dockerfile

In this tutorial, I'll be using PHP7.4 but you can use any version that you need. Here you go:

FROM php:7.4-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid 

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Create system user to run Composer and Artisan Commands
RUN useradd -G www-data,root -u $uid -d /home/$user $user
RUN mkdir -p /home/$user/.composer && \
    chown -R $user:$user /home/$user

# Set working directory
WORKDIR /var/www

USER $user

So, what's happening in the configuration above is that, it pulls a PHP7.4-FPM image from Docker Hub. Next, it'll define the user of the service and install all the necessary dependencies that are given above and set the working directory to /var/www/. The last step will change to the newly created user, which would make sure that you are using the service as a normal user.

Again, if you are a bit playful, try configuring it to however you want it and see if it works.

Set up NGINX and MySQL

I have been following some tutorials and I liked the idea of creating dedicated directories to organize your files related to configuring each service container.

Create a directory named .docker in your project's root directory:

mkdir -p .docker

NGINX

Go to .docker directory and create nginx directory:

mkdir -p nginx

Now let's set up the NGINX service by creating a .conf file:

touch myservice.conf

Now, copy the following configuration to your .conf file:

server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

MySQL

Since this is a Laravel application, you can skip this step by running migrations and seeding your database or you can try creating a directory inside the .docker folder to store your MySQL related configuration:

mkdir -p mysql

Once created, create a file named init_db.sql that would contain your entire database dump to be seeded once you run your docker service.

Set up multiple containers using Docker Compose

This the configuration I have used to create four separate services, please take a look and feel free to modify it based on your requirements.

In this configuration, all services will share a bridge network named yourapp which is defined at the bottom of this configuration.

Here is the configuration:

version: '3.8'
services:
  # PHP Service
  app:
    build:
      args:
        user: username
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: yourapp 
    container_name: yourapp-app
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./:/var/www
    networks:
      - yourapp

  # MySQL Service
  db: 
    image: mysql:8.0
    container_name: yourapp-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev 
      SERVICE_NAME: mysql
    volumes:
      - ./.docker/mysql:/docker-entrypoint-initdb.d
    healthcheck:
      test: mysqladmin ping -h 127.0.0.1 -u ${DB_USERNAME} --password=${DB_PASSWORD}
      interval: 5s
      retries: 10
    networks:
      - yourapp

  # NGINX Service
  nginx:
    image: nginx:alpine
    container_name: yourapp-nginx
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./:/var/www
      - ./.docker/nginx:/etc/nginx/conf.d/
    networks:
      - yourapp

  # phpMyAdmin service
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:5
    ports:
      - 8080:80
    environment:
      PMA_HOST: db
    depends_on:
      db: 
        condition: service_healthy
    networks:
      - yourapp

networks:
  yourapp:
    driver: bridge

Configure your application

Open your current .env file of your laravel project and just add the necessary database configuration:

DB_HOST=yourapp-db
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user_name
DB_PASSWORD=your_database_password

Build the application image

After you are done with configuring, run the following command to build your application image:

docker-compose build yourapp

Depending on your network speed, it might take a few minutes to build your image.

Run the application

Once the build is complete, execute the following command:

docker-compose up -d

The following command will run your containers in the background. To display your information about the state of your docker services:

docker-compose ps

Install your application's dependencies:

docker-compose exec yourapp rm -rf vendor composer.lock
docker-compose exec yourapp composer install

And then run the following commands to run your Laravel application:

docker-compose exec yourapp php artisan key:generate
docker-compose exec yourapp php artisan config:clear
docker-compose exec yourapp php artisan cache:clear
docker-compose exec yourapp php artisan view:clear
docker-compose exec yourapp php artisan route:clear
docker-compose exec yourapp php artisan storage:link 

Now, you can go to your browser, type your http://localhost:8000 to access your application.

Conclusion

If you've come to this part, give yourself a pat in the back!

From now onwards, you don't really need to install and set up a local web server and database to run and test your application.

Furthermore, you'll be having a disposable environment in your hand, which means you can easily replicate and distribute it to other developers in your team, so that no one says "It works on my machine and not on yours!"

Hope you liked this tutorial!

My thoughts on using Visual Studio Code

My experiences on what made me like using Visual Studio Code.

Ever since my university days, I've always used Sublime Text for any sort of text editing and programming tasks, in general.

Despite the annoying "Subscription" dialog box, I like it because it's lightweight, simple and had nice keybindings that made it much more productive.

This week, I thought of taking Visual Studio Code for a drive, not because many developers are using it but personally, I wanted to know if it can be better than Sublime Text.

The answer is yes, it is and here's what I have experienced so far.

Portability

What I like at first is that, it's cross-platform and has support for different operating systems in various architectures. At work, I use Windows 10 and at home, I use Fedora 35 Workstation and it runs fine on both operating systems.

Intellisense, Intellisense, Intellisense...

Intellisense is a term used by Microsoft that includes various features like: code completion, code hinting, method parameter information and more. By default, the editor supports Intellisense for JavaScript, TypeScript, HTML and CSS. But if you install different programming language extensions like Python, PHP, Golang and so on, you'll be able to configure your editor to have a much more richer experience.

At work, I write PHP code and use Laravel framework to develop web applications, I installed the following extensions to make my coding experience much more productive:

  1. PHP Intelephense (bmewburn.vscode-intelephense-client)
  2. phpfmt (kokororin.vscode-phpfmt)
  3. Laravel Snippets (onecentlin.laravel-blade)

Sublime Text and Vim Keybindings

If you've never used Vim, please go ahead and try. I believe that every programmer should try using VIM instead of fearing the keybindings (like :q) as they were developed for a reason.

But unlike Vim, Sublime Text keybindings are quite fun especially when you want to duplicate a line of code, indent lines of code, matching multiple instances of the same keyword and modifying them with multiple cursors at the same time.

Try installing these extensions and see if you like them:

  1. Vim Emulation for Visual Studio Code (vscodevim.vim)
  2. Sublime Text Keymap and Settings Importer (ms-vscode.sublime-keybindings)

Integrated Terminal

You can use different type of shells like Windows Powershell, Command Prompt, Git Bash and much more. Besides IMO, I found that using the integrated terminal was quite productive as I didn't have to switch windows in between.

Looks minimal

When it comes to UI/UX, the word minimalism is often subjective but I guess Microsoft embraced the principles of minimalism for this editor.

Lots of extensions and great support

Thanks to the open source community, there are hundreds and thousands of extensions out there. By installing various extensions, you can make it your own editor and that part fascinates me.

Besides, it's developed by Microsoft, so it definitely has a strong support and community out there.

Conclusion

I guess the simplicity and flexibility of this editor is what made it more powerful amongst the developer community.

Now, I'm not going to say that it's a flawless editor, just like every other pieces of software, it does have it's cons. However, I decided to try out Visual Studio Code for a while and see how it goes for me.

If it doesn't then maybe I might write a post about why I didn't like using it, in the future.

Hope you liked reading this article.

Built a new generative art pattern generator

Thought of giving a colorful touch to the site.

Ten days ago, I launched a new makeover for the blog and I felt that it needed a little bit of a colorful yet unique touch.

Recently, I started playing around with the concept of Generative Art and have been studying a lot of about various patterns like:

  • Bauhaus
  • Truchet Tiles
  • Piet Mondrian

So, I thought of writing a new pattern generator using CSS and JavaScript that would assign each article a unique, colorful pattern. Though, it's not yet quite complete, I would consider it to be an experimental feature to see if it goes well with the site.

What do you think about it? Does it look good? What kind of patterns should I add to my generator?

Interested on how it's implemented? Have a look at the source code.

Hope you found this article to be inspiring!

A new makeover for 2022

Function over fashion. Minimal. Scraped out the redundant and added some new features.

I have been reading a lot of articles and blogs than writing these days, thanks to my hectic schedule, I barely get the time to work on my blog.

Initially, I thought of porting my blog to Django or Hugo but I decided to tune up my blog engine by adding new features like Tags/Categories and Archives, optimizing the time-taken to convert Markdown to HTML files and making it more flexible for the future.

Also, I revamped the entire blog's layout by writing a new theme and making it a bit more responsive than it previously was. However, I retained the colors and the fonts used. Thank you Rasmus for the amazing Inter font ❤.

Still got some work to do

Yes, new layout and all but there's still few left in pending and hopefully, I'd complete it by the end of July 2022. But here's what's left:

  • Thanks to Simon Willison's Blog, I took the idea of Blogmarks and it's basically a collection of articles and quotes that I find interesting and would share it here.
  • Planning to move all project/widget based posts to a section called "Projects", which would also have a different layout.
  • Book reviews and a new resume template
  • Dark theme with a better color palette (I wasn't happy with the color scheme that I wrote previously.)

Wait, where's megacolorboy?

For the time being, I thought of removing my username "megacolorboy" from the Masthead for the sake of professionalism and hey, I ain't a kid no more, so time to grow up, you know?

I'd like to thank my beautiful wife for letting me work on my passion even though it might annoy her at times, I love her for that ❤!

Hope you like the new makeover!

I switched to Fedora 35

Switched from Void Linux to Fedora 35

Yes, I distro-hopped again but I guess it's a meaningful decision.

I was using Void Linux with an i3wm tiling manager setup to see if it would improve my programming productivity.

I've got to say that i3wm is an amazing tiling manager and if you are into tiling windows, this should be something worth of your time.

On the other hand, I thought of trying out Void Linux because I was tired of Ubuntu and it's bloat, whereas Void Linux is quite minimal and lightweight.

Then, why leave it?

It has a good package manager that is similar to Arch's AUR repository but the lack of documentation and updates made me feel that there's barely contributions for it.

I had issues using docker and virtualbox in it, often giving me compatibility issues at times, which left me frustrated.

Hello, Fedora!

When I decided to distro-hop, I had to give myself some time and research as to which distro would really suit me as a programmer and that would just work out of the box.

I wanted something that:

  • is developer-oriented.
  • stable but bleeding-edge.
  • just works out-of-the-box.
  • has a minimal and clean looking interface.

That's when Fedora came into the picture and according to what I have researched especially on forums like Reddit, it's directed towards programmers and sysadmins.

Another sellout point for me was RedHat because I use CentOS at my workplace to configure and deploy web applications.

RedHat developers are really dedicated and ensure that they push the stable yet bleeding-edge releases.

The installation process was smooth and the new Gnome 41 is a bliss.

I didn't want to use i3wm this time because I felt that I always tiled multiple terminal windows, so I thought I would replace that with tmux instead. And besides, I don't really want to spend a lot of time tinkering each and every part of my UI, I'd rather spend that time writing code that solves problems instead.

Let's see how long Fedora would last!

Until next time, then!

Is SELinux complicated?

If you turn off SELinux for a living, try this.

This might look a rant post but hear me out, okay?

Ever deployed an application on CentOS and tried to figure out why it isn't working when it's caused due to some permission issue by SELinux enabled?

Yeah, I know how annoying that is. So, whenever I go on StackOverflow, many people suggest to completely turn it off.

Well, it might be tempting to type sudo setenforce 0 (which sets SELinux to Permissive mode), I wouldn't really recommend you to edit the SELinux config and disable it completely.

I recently read a blog post on CentOS's official blog and I'd like to quote them for asking this:

But why do articles feel the need to outright deactivate SELinux rather than help readers work through any problems they might have? Is SELinux that hard?

Good question. Is it really that hard or is it because we don't really understand it? I think it's the latter.

But why so?

I guess, as users, we really need some sort of user interface to receive feedback because not everyone is really good at the terminal and most importantly, not good at memorizing options and flag combinations.

Here's a sample error that I would face sometimes while deploying a Laravel web application on CentOS 7:

[Mon May 16 11:39:32.996441 2016] [:error] [pid 2434] [client XXX.XXX.XXX.XXX:8080] PHP Fatal error:  Uncaught UnexpectedValueException: The stream or file "/var/www/html/MYSITE/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in /var/www/html/MYSITE/bootstrap/cache/compiled.php:13701
Stack trace:
#0 /var/www/html/MYSITE/bootstrap/cache/compiled.php(13635): Monolog\\Handler\\StreamHandler->write(Array)
#1 /var/www/html/MYSITE/bootstrap/cache/compiled.php(13396): Monolog\\Handler\\AbstractProcessingHandler->handle(Array)
#2 /var/www/html/MYSITE/bootstrap/cache/compiled.php(13494): Monolog\\Logger->addRecord(400, Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)
#3 /var/www/html/MYSITE/bootstrap/cache/compiled.php(13189): Monolog\\Logger->error(Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)
#4 /var/www/html/MYSITE/bootstrap/cache/compiled.php(13160): Illuminate\\Log\\Writer->writeLog('error', Object(Symfony\\Component\\Debug\\Exception\\FatalErrorException), Array)
# in /var/www/html/MYSITE/bootstrap/cache/compiled.php on line 13701

By looking at this error, you do understand it's permission-related but it doesn't really indicate that it's an SELinux problem because there could be thousands of reasons why there could be such an error. And of course, when I look it up on Google, I do find many people facing the same issue due to SELinux being enabled.

Instead of disabling it completely, I would try doing this:

chcon -R -t httpd_sys_rw_content_t storage

And off goes the error and the application didn't give any permission-related issues again.

Is it worth disabling SELinux? No.

But does SELinux have an issue of being user friendly? I guess, yes.

I'm just like you, sometimes, I do switch off SELinux at times when it's critical to deploy the application so that I can leave home early but that's not really a good practice.

Conclusion

I do wish that the open source developers of SELinux could do something to make much more friendlier to use? Or maybe, some way that let's the user know what to do instead of letting the user chmod-ing and chown-ing files and directories endlessly. Or worse, completely disabling SELinux!

Hope you found this article interesting!

Stay tuned for more.

On learning new technologies

Sharing my tips on how I learn new technologies at work and home nowadays.

If you're a programmer, you already know that it's quite a daunting task to keep up with the latest stream of technologies:

  • Frameworks
  • Libraries
  • Programming Languages
  • Programming Paradigms

And there's never an end to it, it's just an ever-growing thing.

So, whenever I'm walking or commuting, sometimes, these questions pop up in my head:

  1. How can I learn something new without wasting my free-time?
  2. How can I learn all of the existing technologies out there? Is it possible?

Well, it's technically impossible for me to know about everything — in and out. Computer Science is such a broad field and has a lot of branches and sub-branches.

However, you can learn a piece of technology just enough to know that it exists and know when to learn more about it when the time arises.

Don't try to learn everything out there

In my years of developing web applications, I have seen two types of programmers:

  1. One who has deep knowledge of a particular technology
  2. An all-rounder but also not-so-deep knowledge about multiple technologies

Where do I fall ? Personally, I feel that I belong to the latter kind because I believe that spending a lot of time trying to specialize or being an expert in one technology is just too time-consuming and given the fact that everyday there's a new framework or programming language released out there, it's better to put yourself in the middle ground.

Why you ask? Here's why:

  1. Technology dies fast. For example, there was a time when jQuery used to be really popular amongst the Front End Developers but today, most of them move towards libraries like ReactJS, VueJS and NextJS to build their projects and sooner or later, another framework will come out to replace ReactJS and become the next thing.
  2. I don't think most of the technologies out there are relevant to the problem that you are trying to solve. Like why do I need to look into an API about geospatial analytics unless I'm trying to build an application that needs such a requirement, you get it right?

Basically, trying to learn every single piece of technology out there, it's just basically wasting time.

Ways and source of learning new stuff

Whenever I wanted to learn a new programming language, I would often go to Project Euler to flex my skills and that would help me learn more about it's features. Recently, I started LeetCode and Advent of Code - 2021. It's quite interesting solving these challenges as it helps you to learn more about the technology and feels good after solving a problem.

The next thing I would recommend is following a tech news feed like Hacker News but it can get quite addicting and distracting at times. Another good source of information are weekly newsletters. If you don't really know which one to follow, here's a repository filled with Awesome Newsletters that spans various areas like DevOps, Front end, Back end and Data Science. Try signing up on one of them and see how it goes.

Time is costly, use it wisely

The brain can only do so much in about 9 to 10 hours a day and in order for you to be efficient and productive in learning new stuff, try the following:

  1. Spend an hour learning, reading or practicing a new tool.
  2. Interesting stuff but not needed yet? Try bookmarking or make a note of it, so that you can revisit it again.
  3. If it fits your needs and project requirements, then go ahead and learn it!

If you found this article useful, please share it with your friends and colleagues.

Stay tuned for more!