How to install Docker and Docker Compose on Oracle Linux 7

I have a need to install Docker and Docker Compose on Oracle Linux 7. Here is my note for future reference.

sudo yum -y update
sudo yum install -y docker-engine
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER

Now, logout and log back in and execute a docker command to see if you don’t need sudo to execute it.

docker ps -a

Now install Docker Compose.

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Now check if docker-compose was successfully installed.

docker-compose -v

How to Set Default User for WSL (Ubuntu)

I have Ubuntu for WSL (Windows Subsystem for Linux). I’m not sure how it happened, but when I started the terminal, it started to default to the root user. I wanted to default the user to the one that’s not the root user.

ubuntu config --default-user hiriumi

Make sure to run it either from the Windows command line or PowerShell. Next time when you open Ubuntu terminal, it goes straight to the user you specified.

Missed Demo for the Japanese Students I Gave Speech to

I had an opportunity to give a speech to students who are looking to become engineers in Japan last Friday. It was great to meet them though it was online. They seemed eager to learn what takes to be engineers. I was honored to give speech to them. They were also learning English, so this may be good for them.

Due to my unpreparedness on my side, I missed one demo. I was basically compiling Java code and decomplie it with IntelliJ. I would like to show how it can be done here in this blog for their view.

First, create a text file (helloworld.java) with the following code. It’s just a simple hello world program in Java.

public class helloworld {
    public static void main(String args[])
    {
        System.out.println("Hello World");
    }
}

Once you have the file, compile it like the following from your terminal (command line).

javac helloworld.java

The javac (Java compiler) compiles the text file to Java byte code (helloworld.class). You can execute the hello world program like the following.

java helloworld

Output:

Hello World

When you open helloworld.class file with IntelliJ, you can decompile it.

Decompilation is not really a useful technique anymore because of the current trend of open source but if the source code is closed but you want to learn how the Java program works, it’s still an interesting technique to use especially while you are learning how program works.

I believe JetBrain provides students with free license so you may be able to use the IDEs for free.

The reason why I could not find the helloworld.class file at the time of demo was because I was using WSL 2 on Windows. I had the file on the Linux side of the OS but I had forgotten to copy the file on the Windows side. I’m so sorry about it.

There was so much more I wanted to talk to everyone about but our time was limited. I wish all of you successful careers and bright future. 🙂

Batch Processing with Python Multithreading

I want to execute 5 threads at a time but I have 23 things I want to run in total. Here is the code I came up with.

import threading
from multiprocessing import Pool
import time


class MyThread(threading.Thread):
    def run(id):
        print(f"thread {id}")
        time.sleep(3)


if __name__ == '__main__':
    start_time = time.time()
    threads = []
    batch_size = 5
    for i in range(23):
        threads.append(MyThread.run)

    batch_index = 1
    thread_index = 1
    while len(threads) > 0:
        pool = Pool()
        print(f"Batch {batch_index}")
        for j in range(batch_size):
            if threads:
                t = threads.pop()
                pool.apply_async(t, (thread_index,))
                thread_index += 1
        pool.close()
        pool.join()
        batch_index += 1

    elapsed_time = time.time() - start_time
    print(f"Took {elapsed_time}")

Output:

Batch 1
thread 1
thread 2
thread 3
thread 4
thread 5
Batch 2
thread 6
thread 7
thread 8
thread 9
thread 10
Batch 3
thread 11
thread 12
thread 13
thread 14
thread 15
Batch 4
thread 16
thread 17
thread 18
thread 19
thread 20
Batch 5
thread 21
thread 22
thread 23
Took 15.523964166641235

Each thread takes 3 seconds. If I executed the function sequentially, it would take at least 60 seconds but with the 5 threads at a time, it ended up with only 12 seconds. This is a huge improvement.

Another thing to note is that I declared threads variable as list. List has pop() method in Python. This returns the item (thread object in this case) and removes it from the list. This way, you can use the list to keep track on the threads.

I also needed to add if threads: to check if the threads still has items in case the number of threads is not divisible by 5. If I had 23 threads I want to execute, it attempts to execute 20, 21, 22, 23, 24, 25. 24 and 25 do not exist in the list so it errors out. To prevent such a situation, the if statement is necessary.

Multithread Processing with Python

I did fair amount of multithreading programming with C# in the past but never tried it with Python. Let’s imagine a function that takes 3 seconds. You want to execute it 3 times. The total execution time should be 9 seconds like the following.

import threading
import time


class MyThread(threading.Thread):
    def run():
        # Long running process
        time.sleep(3)
        print('Done')


if __name__ == '__main__':
    start_time = time.time()
    MyThread.run()
    MyThread.run()
    MyThread.run()
    elapsed_time = time.time() - start_time
    print(f"Took {elapsed_time}")

Output:

Done
Done
Done
Took 9.006911993026733

If you can run the functions in 3 different threads at the same time, you could save time. Here is the multithread sample in Python.

import threading
from multiprocessing import Pool
import time


class MyThread(threading.Thread):
    def run():
        time.sleep(3)
        print('hoge')


if __name__ == '__main__':
    start_time = time.time()
    pool = Pool()
    pool.apply_async(MyThread.run)
    pool.apply_async(MyThread.run)
    pool.apply_async(MyThread.run)
    pool.close()
    pool.join()
    elapsed_time = time.time() - start_time
    print(f"Took {elapsed_time}")

Here is the output:

hoge
hoge
hoge
Took 3.179738998413086

It should take 9 seconds if those processes run sequentially but it only took 3.17 seconds. It’s because the 3 threads run at the same time like the following image.

It’s not too difficult to do multithreading in Python. There is one more thing I am thinking about. What if you need to run 100 processes but you want to limit the number of threads to 5 at a time? I will write about it after this blog article.

Cheapest Way to Blog with Your Own Domain

Most of the hosting services want you to buy domain and host your site there. As I was working on my blog site, I’ve learned how I could change DNS record to point to my free tier host on Oracle Cloud Infrastructure. I wanted to do it because iPage.com was too slow for me.

Then, I thought what if I could use a service that allows me to just buy domains and manage my own DNS records without any hosting and host my site on OCI’s free tier?

When I was watching Scott Hanselman‘s YouTube video, I noticed something. He was using DNSimple for his DNS management. So this is a site where you can buy domains and manage DNS records and SSL certs.

So I pay $6 every month for the service and I pay $16 every year for my domain. $6×12+$16=$88 My blog site is hosted at OCI’s free tier host, so it does not cost anything. So I can have my own blog with my domain name for $88 per year. I think it’s quite reasonable.

Of course, this method requires pretty good knowledge of DNS, Web Server and SSL but if you are an engineer or planning to be one, I’d highly recommend it.

zsh

I like z shell. z shell (zsh) is built on top of bash, so your bash script should run without any modification. Here is how you can install zsh.

sudo apt install zsh

Here is how you can make zsh your default shell.

sudo sh -c "echo $(which zsh) >> /etc/shells" && chsh -s $(which zsh)

You may be prompted to create ~/.zshrc (equivalent to ~/.bashrc) when you start your terminal with zsh.

Once you have zsh installed, it’s time to install oh-my-zsh. It’s another cool open source project that allows you to have cool prompt on your terminal.

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

We don’t stop here. To make your prompt even cooler especially for your git operations, we install p10k.

Install p10k manually.

git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc

Close your terminal and restart it.

Now you get a prompt like the following. It doesn’t show the right glyphs because you don’t have the right fonts and set to be used on your terminal.

Let’s download and install Nerd Fonts. First, clone this repo.

git clone https://github.com/ryanoasis/nerd-fonts.git

It takes some time for the whole repo to be downloaded.

Install the fonts by running the script.

cd nerd-fonts
./install.sh FiraCode

Now change your font of your terminal profile to FiraCode Nerd Font Mono Regular and then run the following command.

p10k configure

If you run through the wizard, you get your cool prompt! 🙂

Linux is Ready for Prime Time

Over the years, I have had a lot of interest in Linux. I would download and install some distribution on my PC or virtual machines to try them out but it was hard mostly because of issues with drivers. And the desktop environments were not there yet.

About 5 to 6 years ago, I wanted a media PC for my TV and I gave Linux Mint a try. It was a great pleasant surprise that I didn’t have to struggle with drivers and the software I needed. I also tried Hacintosh for 10 years, so that gave me a good experience. A long time Windows guy slowly transitioned to Mac and Linux.

Please don’t get me wrong, but I’m not completely defying Windows at all. I do like Windows too but when it comes to performance and freedom I get from Linux, nothing can beat it. And I think Linux desktop environments are ready for prime time.

I’ve done quite a bit of distro hopping but I realized that it’s no use. What you can do with Linux distros are pretty much the same but what makes things different is the desktop environments such as GNOME, MATE and Xfce. You can install all of them and switch as you go. Unlike distro hopping, you don’t have to wipe out your disk to try them out.

Once you install Windows or macOS, you are stuck with it. But with Linux, you can use any desktop environment available. And all of them are free.

I have a Windows machine, Macbook Pro and 2 Linux Mint machines at home. I love what I have and I keep digging everyday. 🙂

How to Copy cat Output to Clipboard on Linux Mint

There may be times when you want to copy the output of cat command to your clipboard. cat foo.txt | pbcopy is available on macOS but how do we do something like that on Linux Mint (or Ubuntu)? xclip can be installed to accomplish that.

Install xclip.

sudo apt install xclip

By doing something like the following, you can copy the content of a text file to clipboard.

cat foo.txt | xclip -selection cliboard

This is too much typing just to copy contents from the text file. You could add the following alias in your ~/.bashrc or ~/.zshrc if you use zshell (which is my favorite shell).

alias "cs=xclip -selection clipboard"

Once you add the line, you can do source ~/.bashrc (or ~/.zshrc) and you should start to be able to use it like below.

cat foo.txt | cs

How to Install Google Chrome on Linux Mint

Linux Mint (and any Debian derivatives) does not come with Google Chrome. You can’t install it even from Software Manager. In this blog, I will show you how to install it from terminal.

Make sure you have vim installed on your machine. (sudo apt install vim)

Next create a new file under the directory.

sudo vim /etc/apt/sources.list.d/chrome.list

Paste the following source in the file.

deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main

Add the key.

wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add -

Execute update.

sudo apt update

Install Google Chrome.

sudo apt install google-chrome-stable

Start Google Chrome

google-chrome

I’m not sure how you can add Google Chrome in the favorite menu yet. I will update this article when I find out.

Edit: It showed up in the menu the next day, so I am guessing it takes some time for the DE to cache the newly installed applications.