<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ahmed A. Elkhalifa</title>
    <description>The latest articles on DEV Community by Ahmed A. Elkhalifa (@ahmedwadod).</description>
    <link>https://dev.to/ahmedwadod</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F800466%2F858dd5c5-6ec9-4b8c-bff7-b2f984de6051.jpg</url>
      <title>DEV Community: Ahmed A. Elkhalifa</title>
      <link>https://dev.to/ahmedwadod</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahmedwadod"/>
    <language>en</language>
    <item>
      <title>From Ubuntu + VSCode to Arch + Neovim</title>
      <dc:creator>Ahmed A. Elkhalifa</dc:creator>
      <pubDate>Mon, 29 Jan 2024 07:15:00 +0000</pubDate>
      <link>https://dev.to/ahmedwadod/from-ubuntu-vs-code-to-arch-neovim-13lc</link>
      <guid>https://dev.to/ahmedwadod/from-ubuntu-vs-code-to-arch-neovim-13lc</guid>
      <description>&lt;p&gt;There are various motivations for ditching Ubuntu for Arch Linux, whether it's the thrill of distro hopping or the noble quest to vanquish bloatware. Having made the leap myself an year ago, I aim to guide potential Arch adventurers through this process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Before you embark on the Arch Linux journey, ask yourself "why?" Your reason will fuel your determination when things get tricky. For me, the switch stemmed from three desires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A better understanding of my operating system, I wanted to know how packages on my system work together to give me my final experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;More skills with Linux, as my job envolves working a lot with Linux servers, I wanted to have more skills with bare-skin Linux systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A lighter system, my 4-years Ubuntu installation was now idling at 1.1GB RAM usage with tens of packages that I don't even remember installing or ever using and I felt that needed to change.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The following parts of this article are steps crafted out from my personal experience, some of them I've tried and worked best for me, some are things I wish I had done, follow whatever makes sense to you, in the end this is your personal journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Getting your feet wet
&lt;/h2&gt;

&lt;p&gt;Going ahead and installing Arch Linux on your main PC right away is of course a foolish move, you'll need to install Arch Linux on a virtual machine first, and I recommend following the &lt;a href="https://wiki.archlinux.org/title/installation_guide"&gt;Offical Arch Linux Installation Guide &lt;/a&gt;, the process might seem tidious at first, specially that it's a terminal-based installation process rather than a graphical one, but following this process you will make you understand a lot about the underlying parts of the Linux operating system.&lt;/p&gt;

&lt;p&gt;I recommend that you install Arch Linux 2 or 3 times on a virtual machine first, taking notes each time of the packages you installed and the problems you faced.&lt;/p&gt;

&lt;p&gt;I would also recommend installing and trying different &lt;a href="https://wiki.archlinux.org/title/desktop_environment"&gt;desktop environments&lt;/a&gt; during this phase, this will help you understand how different DEs work and you will find what suits you better.&lt;/p&gt;

&lt;p&gt;At this point, install the programs and packages you are already familiar with, try changing only the parts that make your operating system (desktop environments, wifi control interface, etc) but keep using the same programs (browser, text editor, etc) you're already using, this way you can test your workflow against the amalgamation of an OS that you have made.&lt;/p&gt;

&lt;p&gt;Start shifting some of your workload from your main PC to your Arch Linux virtual machine, I recommend you start with simple tasks like browsing the web or coding side projects. Move at a pace that suits you, and when you feel accustomed to your OS then take a leap of faith and install Arch Linux on your rig.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Harnessing the power of Linux
&lt;/h2&gt;

&lt;p&gt;Linux, or I should say GNU/Linux is a very powerful operating system, and it has a lot of "built-in" features and tools that you can use, since you've come to Arch Linux land, you might as well dedicate some time into learning how to use the operating system to a good extend.&lt;/p&gt;

&lt;p&gt;You've probably used the terminal a lot by now, but if you're using the terminal only when needed or when there is no other option, I would recommend starting to use it more, start using the terminal for file managment, use the basic commands &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;mkdir&lt;/code&gt;, &lt;code&gt;touch&lt;/code&gt;, &lt;code&gt;rm&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt; and &lt;code&gt;cp&lt;/code&gt; as your main method of dealing with files, also start using commands like &lt;code&gt;grep&lt;/code&gt; and &lt;code&gt;find&lt;/code&gt; for searching, you can keep a GUI file explorer just in case you get stuck, but try to rely on the terminal more, and you might be intersted to read about the &lt;a href="https://www.linuxfoundation.org/blog/blog/classic-sysadmin-understanding-linux-file-permissions"&gt;Linux File Permissions&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;I would also recommend learning more about &lt;a href="https://wiki.archlinux.org/title/systemd"&gt;systemd&lt;/a&gt; and how you may use it to create your own services.&lt;/p&gt;

&lt;p&gt;Linux comes bundled with great utilities that might come in handy to do a lot of simple tasks that occurs a lot in one's workflow, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You might have a &lt;code&gt;csv&lt;/code&gt; file called &lt;code&gt;data.csv&lt;/code&gt; that contains data about the employees at your company: &lt;em&gt;ID&lt;/em&gt;, &lt;em&gt;Name&lt;/em&gt;, &lt;em&gt;Department&lt;/em&gt;, &lt;em&gt;Deductions&lt;/em&gt; and &lt;em&gt;Salary&lt;/em&gt;, and you want to generate another file called &lt;code&gt;processed.csv&lt;/code&gt; that contains only the &lt;em&gt;ID&lt;/em&gt; and &lt;em&gt;Total&lt;/em&gt; in which &lt;em&gt;Total&lt;/em&gt; is the calculated amount from the equation &lt;code&gt;Salary - Deductions&lt;/code&gt;. You could do this manually using a spread sheet program, or even better by writing a python script since this would be a monthly problem, both ways work, but if you know your Linux, you can solve this problem with a single line command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ awk -F',' 'NR == 1 {print "ID,Total"} NR != 1 {print $1 "," $5-$4}' data.csv &amp;gt; processed.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although this might seem bizarre, it's a really simple &lt;a href="https://www.gnu.org/software/gawk/manual/gawk.html"&gt;Awk&lt;/a&gt; command that you yourself would be able to fully understand after watching a 20 minute video on YouTube, and what's great about it (beside it's literally one line) is that it can be ran on virtually any Linux machine without installing any new packages or dependencies!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Another great example of using Linux tools is dealing with &lt;code&gt;baseUrl&lt;/code&gt; in CI/CD pipelines. If you're responsible of making a CI/CD pipeline for a web project that involve dealing with the website running on sub-path you may find yourself in a position to deal with a &lt;code&gt;baseUrl&lt;/code&gt; or a &lt;code&gt;basePath&lt;/code&gt; variable that could be different in production than in the developers' local environment, and you might solve this issue in serveral ways that may include setting a policy to never checkout the file containing the &lt;code&gt;baseUrl&lt;/code&gt; variable (Spoiler alert: someone will) or you might set a script to change the variable in production, another easy way to do so is using the Linux &lt;a href="https://www.gnu.org/software/sed/manual/sed.html"&gt;sed&lt;/a&gt; command to do an inline change to the file during the CI/CD pipeline, something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sed -i "s;baseUrl='/';baseUrl='/some-path';" index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a lot of amazing Linux commands and utilities, I recommend exploring them as they might come in handy.&lt;/p&gt;

&lt;p&gt;I recommend reading the &lt;a href="https://www.kernel.org/doc/man-pages/"&gt;Linux man-pages&lt;/a&gt; and the &lt;a href="https://wiki.archlinux.org/"&gt;Arch Wiki&lt;/a&gt; as those are two of the greatest sources of Linux knowledge ever, I've personally learned more from reading the Arch Wiki for one day than I have learned from googling my way through Ubuntu for four years.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: The Dungeons of Vim
&lt;/h1&gt;

&lt;p&gt;Now a few weeks have passed since you switched to Arch Linux and things are looking great, maybe it is time to start using the ultimate text editor.. Vim (or more precisely Neovim).&lt;/p&gt;

&lt;p&gt;The transition from a text editor like VS Code to Vim might seem hard, and rightfully it is, but it's not imposible!&lt;/p&gt;

&lt;p&gt;I would recommend a few steps that will help you make this transition as smoothly as possible:&lt;/p&gt;

&lt;p&gt;Start with bare-skin Vim: don't install Neovim yet, start by learning the basics of Vim specially Vim Motions, I recommend checking out the &lt;code&gt;vimtutor&lt;/code&gt; to get used to everything.&lt;/p&gt;

&lt;p&gt;Moving away from the GUI: A lot of people will recommend using your text editor (aka VS Code) with a vim motions plugin to learn vim motions better, while this is true, vim has a lot more to offer than just motions, so I would recommend using vim to write readme files or for taking notes just to get familiar with the entire program.&lt;/p&gt;

&lt;p&gt;After a week or so from using vim you will feel great! you will have this burning desire to use vim motions everywhere! on your browser, on your email client, just everywhere!. Althought some people seek that path &lt;em&gt;(Looking at you ThePrimeagen)&lt;/em&gt; I would recommend you refrain from it, at the end you are propably the "Tech-support guy" of your family and friends, so you still need to know how to use a computer like a normal human being.&lt;/p&gt;

&lt;p&gt;When you feel that the only thing holding you from using vim as your primary text editor is the tooling (auto-compelete, error messages, etc.) that would be the perfect time to &lt;code&gt;sudo pacman -Syu neovim&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Neovim is basically Vim on steroids. To start with Neovim some people might recommend using pre-made configuration like &lt;a href="https://nvchad.com/"&gt;NvChad&lt;/a&gt; or &lt;a href="https://www.lazyvim.org/"&gt;LazyVim&lt;/a&gt;, but I would recommend the opposite, start configuring Neovim on your own, you will need a little bit of Lua and a tutorial, it might feel overwhelming at first, but don't worry, it gets easier with time and you will learn a lot throughout the process.&lt;/p&gt;

&lt;p&gt;One great tutorial on how to setup NeoVim is &lt;a href="https://youtu.be/w7i4amO_zaE?si=rCOJbWT-iVhZhnUv"&gt;this one&lt;/a&gt; by ThePrimeagen, I highly recommend that you watch it.&lt;/p&gt;

&lt;p&gt;After you setup Neovim the way you like it, start moving all your work to NeoVim, it might be a little bit difficult at first but once you get the grip of it you will wonder how have you been living without it before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Epilogue
&lt;/h3&gt;

&lt;p&gt;This journey is not an easy one, it took me one year to feel comfortable about my system and setup, it can take you longer or shorter depending on how you like this system to be, but always remember that you need to make it yours, and that's the only thing that matters.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>vim</category>
      <category>archlinux</category>
      <category>neovim</category>
    </item>
    <item>
      <title>x64 Assembly: Multithreading from Scratch Part 2: Threads</title>
      <dc:creator>Ahmed A. Elkhalifa</dc:creator>
      <pubDate>Thu, 16 Mar 2023 23:36:02 +0000</pubDate>
      <link>https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-2-threads-11g1</link>
      <guid>https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-2-threads-11g1</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-1-hello-world-59p3"&gt;Part 1&lt;/a&gt; of this series we have looked into how to use &lt;code&gt;fork&lt;/code&gt; system call to spawn a child process and branch out on the child process to do a different code path. In this part we will look into how we can implement a more functional way to do multithreading in assembly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal
&lt;/h2&gt;

&lt;p&gt;We want to use any function/subroutine in our assembly code as a thread, meaning that we want a way to call a function and this function will run on a different thread, then we need a way to wait (on the parent process) for the threads we create.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;We will create a file &lt;code&gt;lib/thread.asm&lt;/code&gt; that will have two functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;thread_run&lt;/code&gt;: It will take a pointer to the code we want to execute (stored in &lt;code&gt;rax&lt;/code&gt;) and then it will pass along the registers &lt;code&gt;rdi&lt;/code&gt;, &lt;code&gt;rsi&lt;/code&gt;, &lt;code&gt;rdx&lt;/code&gt; and &lt;code&gt;r8&lt;/code&gt; unchanged to the function now running on the child thread it will create. This function will call &lt;code&gt;fork&lt;/code&gt; and then on the child thread it will jump to the code pointed at by &lt;code&gt;rax&lt;/code&gt;, on the parent it will return the PID of the child process in &lt;code&gt;rax&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;thread_wait&lt;/code&gt;: This function takes a single argument in &lt;code&gt;rax&lt;/code&gt; which is a PID of a child process, it will wait for that child process to finish executing then it returns the exit code of that child process in &lt;code&gt;rax&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;thread_run&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lib/thread.asm

.intel_syntax
.section .text

# thread_run
# A function to start running the given code on a child process
#
# Arguments:
#   rax: Pointer to function(label)
#   rdi, rsi, rdx, rcx, r8 : The arguments to the function
#
# Returns:
#   rax: Child process id
#
.global thread_run
thread_run:
    push %rax # Push rax value to the stack

    # Fork this process
    mov %rax, 0x39
    syscall

    cmp %rax, 0x00 # Compare the returned PID
    mov %r10, %rax # Store the PID in r10 temporarily
    pop %rax # Get back rax value (Function pointer)
    je _invoke # Jump if this is the child process

    # If this is the parent process then return 
    mov %rax, %r10 # Restore the PID
    ret

_invoke:
    # Jump to the pointer of the function
    call %rax

    # Safe exit
    mov %rax, 0x3c
    mov %rdi, 0x00
    syscall

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, the function starts by storing (pushing) the pointer that is in &lt;code&gt;rax&lt;/code&gt; to the stack because we need the &lt;code&gt;rax&lt;/code&gt; register to make a &lt;code&gt;fork&lt;/code&gt; system call, then we compare the return of &lt;code&gt;fork&lt;/code&gt; to zero and store the PID (the current value of &lt;code&gt;rax&lt;/code&gt;) in &lt;code&gt;r10&lt;/code&gt; register temporarly, and put back the function pointer in &lt;code&gt;rax&lt;/code&gt; register and jump conditionally to the &lt;code&gt;_invoke&lt;/code&gt; function/subroutine if the value of the earliy comparison is correct, other-wise we restore the PID in &lt;code&gt;rax&lt;/code&gt; and return. &lt;code&gt;_invoke&lt;/code&gt; subroutine will call the function in the address stored in &lt;code&gt;rax&lt;/code&gt; and then exit safetly with the &lt;code&gt;exit&lt;/code&gt; syscall.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;thread_wait&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lib/thread.asm

...

# thread_wait
# Wait for a process to exit
#
# Arguments: 
#   rax: Process PID
#
# Returns:
#   rax: Exit code
#
.global thread_wait
thread_wait:
    # Allocate space in the stack to store the exit code
    sub %rsp, 4

    mov %rdi, %rax # Move the PID to %rdi for wait4 syscall
    mov %rax, 0x3d # wait4 syscall
    mov %rsi, %rsp # Pointer to the exit code space
    mov %rdx, 0x00 # Flags
    mov %r10, 0x00 # NULL pointer
    syscall

    # Store the exit code in EAX (4 byte value of rax)
    mov %eax, [%rsp]
    add %rsp, 4

    ret

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code we start by allocating 4 bytes of memory on the stack, then we call the &lt;a href="https://man7.org/linux/man-pages/man2/wait4.2.html"&gt;wait4&lt;/a&gt; system call, we basically give it the PID of the child process in &lt;code&gt;rdi&lt;/code&gt; and a pointer to 4 bytes in memory to store the exit value of the child process that exited (We give it the 4 bytes we just allocated on the stack). After &lt;code&gt;wait4&lt;/code&gt; syscall returns, we get the return value from the stack and deallocate that memory from the stack.&lt;/p&gt;

&lt;p&gt;NOTE: The last step could be achived using &lt;code&gt;pop DWORD %rax&lt;/code&gt; but for some reason using &lt;code&gt;gas&lt;/code&gt; it didn't want to assemble, but I assume it will work fine on &lt;code&gt;MASM&lt;/code&gt; or another assembler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assembly
&lt;/h3&gt;

&lt;p&gt;Now we will assemble this code the same way we did with &lt;code&gt;util.asm&lt;/code&gt; using the following commad:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ as lib/thread.asm -o thread.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If eveything works fine we will now have a &lt;code&gt;thread.o&lt;/code&gt; file that we will link our code with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Driver Code
&lt;/h2&gt;

&lt;p&gt;To demonstrate how these two functions work, we will create a new directory &lt;code&gt;hello_threads&lt;/code&gt; in the root of our project and put a &lt;code&gt;main.asm&lt;/code&gt; file inside of it.&lt;/p&gt;

&lt;p&gt;In this file we will write a program that will execute a thread to run the &lt;code&gt;print&lt;/code&gt; function we wrote in &lt;code&gt;util.asm&lt;/code&gt; last time and wait for the thread to finish executing, and then print from the main (parent) process.&lt;br&gt;
Then the program will execute another thread with the &lt;code&gt;print&lt;/code&gt; function and continue running the main (parent) process without waiting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# hello_threads/main.asm

.global _start
.intel_syntax
.section .text

# The external functions we need
.extern thread_run
.extern thread_wait
.extern print

_start:
    # Create a thread
    call _log
    lea %rax, [%rip + print]
    lea %rdi, [%rip + thread_msg]
    mov %rsi, OFFSET thread_msg_len
    call thread_run

    # Wait for the process (PID is in rax) then print
    call thread_wait
    call _pmsg

    # Create a thread
    call _log
    lea %rax, [%rip + print]
    lea %rdi, [%rip + thread2_msg]
    mov %rsi, OFFSET thread2_msg_len
    call thread_run

    # Print without waiting
    call _pmsg

    # Exit
    jmp _exit


_pmsg:
    # Print 'parent_msg'
    lea %rdi, [%rip + parent_msg]
    mov %rsi, OFFSET parent_msg_len
    call print
    ret

_log:
    # Print 'log_msg'
    lea %rdi, [%rip + log_msg]
    mov %rsi, OFFSET log_msg_len
    call print
    ret

_exit:
    # Exit safetly with status code 0
    mov %rax, 0x3c
    mov %rdi, 0x00
    syscall

.section .data
    log_msg:
        .ascii "\nCreating a thread..\n" # 20
        log_msg_len = . - log_msg
    thread_msg:
        .ascii "Hello from thread 1!\n" #19
        thread_msg_len = . - thread_msg
    thread2_msg:
        .ascii "Hello from thread 2!\n" #19
        thread2_msg_len = . - thread2_msg
    parent_msg:
        .ascii "Hello from parent!!\n" #20
        parent_msg_len = . - parent_msg

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we assemble our code and link the resulting object file with both &lt;code&gt;lib/util.o&lt;/code&gt; and &lt;code&gt;lib/thread.o&lt;/code&gt; with the following commads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ as hello_threads/main.asm -o hello_threads/hello_threads.o
$ ld hello_threads/hello_threads.o lib/util.o lib/thread.o -o hello_threads/hello_threads.elf -nostdlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes well, we should now have a &lt;code&gt;hello_threads.elf&lt;/code&gt; in &lt;code&gt;hello_threads&lt;/code&gt; directory, if we execute the file we should see an output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Creating a thread..
Hello from thread 1!
Hello from parent!!

Creating a thread..
Hello from parent!!
Hello from thread 2!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the first thread executes before the main (parent) thread due to us using the &lt;code&gt;thread_wait&lt;/code&gt; function that we defined earlier. But in the second theard case it is different, the parent executes first -for most of the time- since it does not have to wait for the thread to finish executing.&lt;/p&gt;

&lt;p&gt;Now that we have a functional way to spwan and wait for threads we will need a way for threads to communicate and share data with each other, so in the next part we will look into how we can allocate and share memory between threads. &lt;/p&gt;

&lt;p&gt;The code is available on the Github &lt;a href="https://github.com/ahmedwadod/x64_asm_multithreading_from_scratch"&gt;repository&lt;/a&gt; if you want to check it out.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>multithreading</category>
      <category>assembly</category>
    </item>
    <item>
      <title>x64 Assembly: Multithreading from Scratch Part 1: Hello World!</title>
      <dc:creator>Ahmed A. Elkhalifa</dc:creator>
      <pubDate>Wed, 15 Mar 2023 14:21:13 +0000</pubDate>
      <link>https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-1-hello-world-59p3</link>
      <guid>https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-1-hello-world-59p3</guid>
      <description>&lt;h2&gt;
  
  
  Content of The Series
&lt;/h2&gt;

&lt;p&gt;In this series of tutorials we will look into how to implement multithreading techniques in x86_64 Assembly from scratch without using the standard library.&lt;/p&gt;

&lt;p&gt;Part 1: Hello World! from Scratch&lt;br&gt;
   Writing a simple program to print to the standard output from two different processes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/ahmedwadod/x64-assembly-multithreading-from-scratch-part-2-threads-11g1"&gt;Part 2: Threads&lt;/a&gt;&lt;br&gt;
   Implementing a functional way of creating and waiting for threads.&lt;/p&gt;

&lt;p&gt;Part 3: Shared Memory&lt;br&gt;
   Implementing memory managment functions and showing how we can share memory between threads.&lt;/p&gt;

&lt;p&gt;Part 4: Mutexes&lt;br&gt;
   Implementing a mutex to control memory access between threads.&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow along with this tutorial you wil need a basic knowledge in assembly. You will also need a linux environment as we will implement everything from scratch using only the kernel system calls.&lt;/p&gt;
&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;In this tutorial I'm using the &lt;a href="https://gcc.gnu.org/"&gt;GNU&lt;/a&gt; assembler &lt;code&gt;gas&lt;/code&gt; with &lt;code&gt;intel syntax&lt;/code&gt; along the the GNU linker.&lt;/p&gt;

&lt;p&gt;Using other assemblers like &lt;code&gt;MASM&lt;/code&gt; or &lt;code&gt;NASM&lt;/code&gt; should be fine, just make sure to review the differences in syntax between the code shown in this series of tutorials with the code you intend to write, take a look at this &lt;a href="https://stackoverflow.com/tags/intel-syntax/info"&gt;link&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Hello, World! from scratch
&lt;/h2&gt;

&lt;p&gt;Since we won't be linking against the standard library (Linking with &lt;code&gt;-nostdlib&lt;/code&gt;) we will not have access to commonly used functions like &lt;code&gt;printf&lt;/code&gt; or &lt;code&gt;malloc&lt;/code&gt; and will have to implement them from scratch using the &lt;a href="https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md"&gt;x86_64 linux system calls&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Project structure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Project Folder
  |
  |-- lib/   # The directory for our reusable code
  |   |
  |   |-- util.asm   # utilities (print, malloc, etc..)
  |   |....
  |
  |-- hello_world/
      |
      | -- main.asm # Our code for Part 1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Print function
&lt;/h3&gt;

&lt;p&gt;Now we will need to implement a simple function to print to the standard output &lt;code&gt;STDOUT&lt;/code&gt; using the &lt;a href="https://man7.org/linux/man-pages/man2/write.2.html"&gt;write&lt;/a&gt; system call.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;print&lt;/code&gt; function will take 2 arguments: &lt;code&gt;ptr&lt;/code&gt; and &lt;code&gt;len&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ptr&lt;/code&gt;: The address of the string (passed in register &lt;code&gt;rdi&lt;/code&gt;)&lt;br&gt;
&lt;code&gt;len&lt;/code&gt;: The length of the string (passed in register &lt;code&gt;rsi&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# lib/util.asm


.intel_syntax
.section .text

# print function that takes (ptr, len)
# as arguments (rdi, rsi)
.global print
print:
    mov %rdx, %rsi # move the length to rdx
    mov %rsi, %rdi # move the pointer (rdi) to rsi
    mov %rax, 0x01 # write syscall on x64 Linux
    mov %rdi, 0x01 # STDOUT file descriptor
    syscall
    ret


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function that we defined above takes 2 arguments using the &lt;code&gt;rdi&lt;/code&gt; and &lt;code&gt;rsi&lt;/code&gt; registers then rearrange the registers to call the &lt;code&gt;write&lt;/code&gt; syscall on the &lt;code&gt;STDOUT&lt;/code&gt; file descriptor.&lt;/p&gt;

&lt;p&gt;Now lets assemble it with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ as lib/util.asm -o lib/util.o
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should have an object file &lt;code&gt;lib/util.o&lt;/code&gt; that we will link against to have access to our utility functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;fork&lt;/code&gt; System Call
&lt;/h3&gt;

&lt;p&gt;Throughout this series we will be making heavy use of the &lt;a href="https://man7.org/linux/man-pages/man2/fork.2.html"&gt;fork&lt;/a&gt; system call which basically tell the OS to create a child process of the current process, this child process is an exact copy of the parent and it will start executing from the next instruction of the parent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing the Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# hello_world/main.asm


.intel_syntax
.global _start
.section .text

.extern print # Use our print function

_start:
    # Call the 'fork' syscall
    mov %rax, 0x39 # fork syscall on x64 Linux
    syscall
    cmp %rax, 0 # 'fork' will return 0 to the child process
    je _child

_parent:
    # Print 'Hello from parent!'
    lea %rdi, [%rip + msg1]
    mov %rsi, OFFSET msg1len
    call print
    jmp _exit

_child:
    # Print 'Hello from child!'
    lea %rdi, [%rip + msg2]
    mov %rsi, OFFSET msg2len
    call print

_exit:
    # Call the 'exit' syscall
    mov %rax, 0x3c # exit syscall on x64 Linux
    mov %rdi, 0x0 # Exit code
    syscall

.section .data
msg1:
    .ascii "Hello from parent!\n"
    msg1len = . - msg1
msg2:
    .ascii "Hello from child!\n"
    msg2len = . - msg2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we have 2 different functions: &lt;code&gt;_parent&lt;/code&gt; which will print &lt;code&gt;Hello from parent!&lt;/code&gt; and exit, and function &lt;code&gt;_child&lt;/code&gt; which will print &lt;code&gt;Hello from child!&lt;/code&gt; and exit. On the main function &lt;code&gt;_start&lt;/code&gt; we will make a &lt;code&gt;fork&lt;/code&gt; system call which will create a copy of the current process and store a value in the register &lt;code&gt;rax&lt;/code&gt;, this value will be &lt;code&gt;0&lt;/code&gt; on the child process and will be the PID of the child process on the parent, so we will make use of this information. We will compare the value of register &lt;code&gt;rax&lt;/code&gt; to zero, if it is zero we will jump to the &lt;code&gt;_child&lt;/code&gt; function, if not, we will continue to execute the &lt;code&gt;_parent&lt;/code&gt; function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assembling and Linking
&lt;/h3&gt;

&lt;p&gt;We will assemble the code and link it with &lt;code&gt;util.o&lt;/code&gt; object file containing the &lt;code&gt;print&lt;/code&gt; function without linking the standard library using the following commads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ as hello_world/main.asm -o hello_world/hello_world.o
$ ld hello_world/hello_world.o lib/util.o -o hello_world/hello_world.elf -nostdlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes well we should have an executable &lt;code&gt;hello_world/hello_world.elf&lt;/code&gt; and if we execute it we should see the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./hello_world/hello_world.elf
Hello from parent!
Hello from child!
$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! we have successfully written an x86_64 assembly program to execute 2 deifferent code pieces from two different threads. Next, we will look into how to implement a more functional solution to make it easy create and wait for threads.&lt;/p&gt;

&lt;p&gt;The code for this tutorial is available in this &lt;a href="https://github.com/ahmedwadod/x64_asm_multithreading_from_scratch"&gt;repository&lt;/a&gt;. The code repository will be updated with every new part of the series.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>multithreading</category>
      <category>assembly</category>
    </item>
    <item>
      <title>Node.js and Docker: Write, Build and Publish</title>
      <dc:creator>Ahmed A. Elkhalifa</dc:creator>
      <pubDate>Sat, 22 Jan 2022 15:01:12 +0000</pubDate>
      <link>https://dev.to/ahmedwadod/nodejs-and-docker-write-build-and-publish-h4f</link>
      <guid>https://dev.to/ahmedwadod/nodejs-and-docker-write-build-and-publish-h4f</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this tutorial we aim to create a simple Node.js app with Express.js and containerize it with Docker then publish it to &lt;a href="https://hub.docker.com/"&gt;Docker Hub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;This will be a practical tutorial so I will not be explaining any concepts such as Node.js, containerization or Docker. And I will also assume you already have &lt;code&gt;node&lt;/code&gt; and &lt;code&gt;docker&lt;/code&gt; installed on your machine. But if you want me to write an article explaining those concepts, let me know in the comments.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Sections
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Write the Node.js App&lt;/li&gt;
&lt;li&gt;Containerize the App with Docker&lt;/li&gt;
&lt;li&gt;Publish the Image to Docker Hub&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Write the Node.js App
&lt;/h2&gt;

&lt;p&gt;We will first create a simple Node js app that we will then work with. Follow these steps to create the app:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a new directory for the project&lt;/strong&gt;&lt;br&gt;
Create a new directory for the project with whatever name you like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir nodejs_docker_tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and &lt;code&gt;cd&lt;/code&gt; into it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd nodejs_docker_tutorial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Initialize the project&lt;/strong&gt;&lt;br&gt;
I'm gonna be using npm but you can use whatever package manager that suits you. To initialize the project with npm run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fill out the information and set &lt;code&gt;entry point&lt;/code&gt; to be &lt;code&gt;src/app.js&lt;/code&gt;&lt;br&gt;
the final &lt;code&gt;package.json&lt;/code&gt; should be something like&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "nodejs_docker_tutorial",
  "version": "1.0.0",
  "description": "",
  "main": "src/app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Install the packages&lt;/strong&gt;&lt;br&gt;
We are going to need these packages: &lt;br&gt;
&lt;a href="https://www.npmjs.com/package/express"&gt;express&lt;/a&gt;, &lt;a href="https://www.npmjs.com/package/cors"&gt;cors&lt;/a&gt; and (as an optional dev dependency) &lt;a href="https://www.npmjs.com/package/nodemon"&gt;nodemon&lt;/a&gt;&lt;br&gt;
run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm i express cors
$ npm i -D nodemon # Optional
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Create the files and directories&lt;/strong&gt;&lt;br&gt;
Create the following files and directories so that the project tree should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── package.json
├── package-lock.json
└── src
    ├── app.js
    └── routes
        └── home.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Use nodemon to watch for changes (Optional)&lt;/strong&gt;&lt;br&gt;
Installing and using &lt;code&gt;nodemon&lt;/code&gt; is optional and I've included it in the tutorial just as an example to simulate a real-life scenario.&lt;br&gt;
In the &lt;code&gt;scripts&lt;/code&gt; section in &lt;code&gt;package.json&lt;/code&gt; add the &lt;code&gt;dev&lt;/code&gt; script as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
"scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1",
    "dev": "nodemon src/app.js"
  },
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and now in a terminal session you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it will watch for changes in your source code and rerun the app every time a change is made&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Write the code&lt;/strong&gt;&lt;br&gt;
Now we are going to write our actual application.&lt;br&gt;
The goal is to make a simple web server that listens on port &lt;code&gt;8080&lt;/code&gt; and have 2 endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /
Responses:
200 Hello from Docker!

GET /greetings/:name
Responses:
200 Hello, {name}!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now in your favorite text editor edit the source code as follows:&lt;/p&gt;

&lt;p&gt;The source code for &lt;code&gt;src/app.js&lt;/code&gt; will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')
const cors = require('cors')
const app = express()

// Use CORS with default options to allow all origins
app.use(cors())

// Import the home router
const homeRouter = require('./routes/home')

// Use the home router
app.use('/', homeRouter)

// Define the port to listen on
const port = 8080

// Start the server and log a message after it starts
app.listen(port, 
    () =&amp;gt; console.log(`Server listening on port: ${port}`)
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and for &lt;code&gt;src/routes/home.js&lt;/code&gt; it will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express')

// Create the router
const router = express.Router()

// Configure the endpoint for the router
router
    .get('/', (req, res) =&amp;gt; res.send('Hello from Docker!'))
    .get('/greetings/:name',
            (req, res) =&amp;gt; res.send(`Hello, ${req.params.name}`))

// Export the router
module.exports = router
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Test the app&lt;/strong&gt;&lt;br&gt;
Now we are going to test if our code works or not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are using &lt;code&gt;nodemon&lt;/code&gt; just head to &lt;code&gt;http://localhost:8080&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If you are &lt;strong&gt;not&lt;/strong&gt; using &lt;code&gt;nodemon&lt;/code&gt; just run:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ node src/app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and then head to &lt;code&gt;http://localhost:8080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should see a web page as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmf85rvpbhvqw0xeqr7v7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmf85rvpbhvqw0xeqr7v7.png" alt="First Output" width="382" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And if you go to &lt;code&gt;http://localhost:8080/greetings/Ahmed&lt;/code&gt; you will see something like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl48yxc3crw56fl47x711.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl48yxc3crw56fl47x711.png" alt="Second output" width="413" height="255"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Congrats! Now the app is done and we can move to the docker stuff!&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Containerize the App with Docker
&lt;/h2&gt;

&lt;p&gt;Now that our app is ready we can use Docker to create an image of our app.&lt;br&gt;
To create an image for your app follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Stop the running node app&lt;/strong&gt;&lt;br&gt;
First thing to avoid port conflicts later on, we need to stop the app for now, use &lt;code&gt;Ctrl+C&lt;/code&gt; on the terminal session where you started your app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create a Dockerfile&lt;/strong&gt;&lt;br&gt;
In the root directory of the project create a file named &lt;code&gt;Dockerfile&lt;/code&gt;, for example you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Dockerfile code&lt;/strong&gt;&lt;br&gt;
In the &lt;code&gt;Dockerfile&lt;/code&gt; you just created put the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Base image
FROM node:alpine

# The working directory inside the container
WORKDIR /App

# Copy the package.json file
COPY package.json package.json

# Install the packages for production environment
RUN npm i --production --omit dev

# Copy the source files
COPY src/ src/

# The main entry point of the container
CMD [ "node", "src/app.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Dockerfile is divided into steps, each line represents a step (lines starting with &lt;code&gt;#&lt;/code&gt; are comments)&lt;br&gt;
So I'll explain each line/step:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 1: Import base image&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:alpine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We select the base image to use for the custom image we want to create, here we are using the &lt;a href="https://hub.docker.com/_/node"&gt;Official Node Image&lt;/a&gt; with the &lt;code&gt;alpine&lt;/code&gt; tag which will basically import the &lt;code&gt;Alpine Linux&lt;/code&gt; image with Node installed in it. I'm using &lt;code&gt;Alpine&lt;/code&gt; image just because it is lightweight, but you can use any other image you like and you can specify what version of node you want, for example you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM node:14.18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To use node version 14.18.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 2: Select the working directory&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WORKDIR /App
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We specify a directory -inside the container- to put our app inside of it, you can use anything you like.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 3: Copy package.json to our working directory&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY package.json package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will copy our &lt;code&gt;package.json&lt;/code&gt; file to the working directory we specified in the above step. Note that you don't need to navigate or write the path of the working directory after you specified it with &lt;code&gt;WORKDIR&lt;/code&gt; instruction.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 4: Instal node modules for production&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RUN npm i --production --omit dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will basically run &lt;code&gt;npm install&lt;/code&gt; with the &lt;code&gt;--production&lt;/code&gt; and &lt;code&gt;--omit dev&lt;/code&gt; flags. You can use any other flags but this is what I personally use for production apps.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 5: Copy the source files to the working directory&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;COPY src/ src/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we will copy out source code files to the working directory we specified on &lt;em&gt;Step 2&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Step 6: Run the node app as the entry point of the image&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CMD [ "node", "src/app.js" ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the command that will be run when we spin up a container with our image and we just want to run &lt;code&gt;node src/app.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So that's it, we are done with our Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Build the Docker image&lt;/strong&gt;&lt;br&gt;
Now we want to build the actual image that we will use to spin up containers of our app.&lt;br&gt;
In the terminal run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; &lt;em&gt;You might need to run the docker commands with &lt;code&gt;sudo&lt;/code&gt; if you haven't done the Docker &lt;a href="https://docs.docker.com/engine/install/linux-postinstall/"&gt;Post-installation Steps&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After the command is done you should see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
Successfully built 33482f9f2921
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Get the Image ID&lt;/strong&gt;&lt;br&gt;
We will need the Image ID so we can use it since we didn't specify any tags for it. You can copy the ID from the above &lt;code&gt;docker build&lt;/code&gt; output on your terminal or you can list all the images you have using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker image list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
&amp;lt;none&amp;gt;       &amp;lt;none&amp;gt;    33482f9f2921   1 minute ago   177MB
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now copy the &lt;code&gt;IMAGE ID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Run a container with the new image&lt;/strong&gt;&lt;br&gt;
Now we can run a container to test our image, in the terminal run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -d -p 8080:8080 &amp;lt;IMAGE_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;IMAGE_ID&amp;gt;&lt;/code&gt; with the ID of your image.&lt;br&gt;
The flag &lt;code&gt;-d&lt;/code&gt; is used to run the container in &lt;code&gt;Detached Mode&lt;/code&gt;(in the background).&lt;br&gt;
The flag &lt;code&gt;-p&lt;/code&gt; will expose a port from the container on the host machine. It uses the syntax &lt;code&gt;-p hostPort:containerPort&lt;/code&gt;.&lt;br&gt;
You can read more about these flags in the &lt;a href="https://docs.docker.com/engine/reference/run/"&gt;Docker Run Reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The output should be a hash, something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;70f36364143abafd4ce2a4f338b20d97015fda400a0bcfd86fd819e86ee39752
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It means that you are up and running. If you go to &lt;code&gt;http://localhost:8080&lt;/code&gt; you should find the app running!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Stop the container&lt;/strong&gt;&lt;br&gt;
You can stop the currently running container using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker stop &amp;lt;CONTAINER_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;CONTAINER_ID&amp;gt;&lt;/code&gt; with the output of the previous step or run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get a list of the running containers and then copy the &lt;code&gt;CONTAINER ID&lt;/code&gt; from the output.&lt;/p&gt;

&lt;p&gt;Now we know our image is ready and we can publish it to a &lt;code&gt;Container Registry&lt;/code&gt; to use it from anywhere we want!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Publish the Image to Docker Hub
&lt;/h2&gt;

&lt;p&gt;Now we have completed developing our app and we built a Docker image of it, now we need a way to distribute/publish our image either publicly or privately.&lt;/p&gt;

&lt;p&gt;Docker Hub is a Container Image Library or a Container Registry where people can push(publish) their images to repositories and make those repositories either public for anyone to view and pull(download) or private where only those authorized can view it or pull it to spin up containers.&lt;br&gt;
We will be pushing our image to a public repository on Docker Hub where we can pull it and use it from anywhere.&lt;/p&gt;

&lt;p&gt;To do that, follow these steps:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a Docker Hub account&lt;/strong&gt;&lt;br&gt;
If you don't already have an account go to &lt;a href="https://hub.docker.com/"&gt;hub.docker.com&lt;/a&gt; and create an account.&lt;br&gt;
Note that your &lt;code&gt;username&lt;/code&gt; on Docker Hub will be your namespace for your repositories, for example mine is &lt;code&gt;ahmedwadod&lt;/code&gt; so my images will be &lt;code&gt;ahmedwadod/image_name:tag&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create a repository&lt;/strong&gt;&lt;br&gt;
In your account home page click on &lt;code&gt;Create Repository&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvs5lw0qe5a6x5t5wcyz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgvs5lw0qe5a6x5t5wcyz.png" alt="Create Repo" width="800" height="163"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now fill out the details of your repository, we will be setting the visability to &lt;code&gt;Public&lt;/code&gt;, if you set it to &lt;code&gt;Private&lt;/code&gt; you are going to need to login with your credentials on Docker whenever you want to pull the image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovvhwqnhexwt5yn00j3v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovvhwqnhexwt5yn00j3v.png" alt="Creating Repo" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click &lt;code&gt;Create&lt;/code&gt; and you will have your repository set to go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Tagging the image&lt;/strong&gt;&lt;br&gt;
Now we need to rebuild our image with the appropriate tags, the tag for your image will be: &lt;code&gt;YOUR_USERNAME/REPO_NAME:TAG&lt;/code&gt; for the &lt;code&gt;:TAG&lt;/code&gt; we will use &lt;code&gt;latest&lt;/code&gt; as it is the default. The &lt;code&gt;:TAG&lt;/code&gt; can be used to when you want to upload different versions of your app for example it can be &lt;code&gt;:v1.0&lt;/code&gt; or &lt;code&gt;:v2.0&lt;/code&gt; or it can be used for different variants of the base image used, for example &lt;code&gt;:v1.0-alpine&lt;/code&gt; or &lt;code&gt;:v1.0-ubuntu&lt;/code&gt;.&lt;br&gt;
In my case the tag will be: &lt;code&gt;ahmedwadod/nodejs-docker-tutorial:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To build the image go to your project's root directory and in the terminal run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker build -t YOUR_USERNAME/REPO_NAME:TAG .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
Successfully built 33482f9f2921
Successfully tagged ahmedwadod/nodejs-docker-tutorial:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Login to Docker Hub&lt;/strong&gt;&lt;br&gt;
Now to publish our image we need to first login into Docker Hub from the terminal, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker login -u &amp;lt;YOUR_USERNAME&amp;gt;
Password: # Enter your password and press enter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Login Succeeded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Push the image to Docker Hub&lt;/strong&gt;&lt;br&gt;
Now all we have to do is push the image, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker push YOUR_USERNAME/REPO_NAME:TAG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output will be something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The push refers to repository [docker.io/ahmedwadod/nodejs-docker-tutorial]
a62d27597b40: Pushed 
c8b55b75e003: Pushed 
d6605a78d13e: Pushed 
86145b7dbdcb: Pushed 
25c4d12b64e7: Mounted from library/node 
1d454e07796f: Mounted from library/node 
970073eeaee3: Mounted from library/node 
8d3ac3489996: Mounted from library/node 
latest: digest: sha256:49d70d1032b3389b465db6691c7e402f146d366b71df9f2b2196301af86116c2 size: 1990
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if you go to the repository in Docker Hub and then to the &lt;code&gt;tags&lt;/code&gt; tab you will find the tag &lt;code&gt;latest&lt;/code&gt; available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzuj2p6k2wa3v1ddgksw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzuj2p6k2wa3v1ddgksw.png" alt="Pushed" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Run the image from anywhere!&lt;/strong&gt;&lt;br&gt;
Now you can go to any server with docker installed on it and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ docker run -d -p 8080:8080 YOUR_USERNAME/REPO_NAME:TAG
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it will spin up a container with your Node js App!&lt;/p&gt;

&lt;h2&gt;
  
  
  Closure
&lt;/h2&gt;

&lt;p&gt;Now that you have containerized your app, you can deploy it. I will be posting in the future about deploying web apps with Dcoker, so follow me to stay tuned.&lt;/p&gt;

&lt;p&gt;You can find this tutorial's &lt;a href="https://github.com/ahmedwadod/nodejs_docker_tutorial"&gt;code on my Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have faced any problems with these steps, comment down below and I will try to help you fix it.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>node</category>
      <category>docker</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
