Chasing After the Wind

Chasing After the Wind

Regardless of your religious inclinations, or whether you believe in God or not, it is undeniable that the Bible contains many passages and teachings that are useful and practical. One such passage is from the book of Ecclesiastes in the Old Testament. In Chapter 4 it described something very profound that struck me. It is about how people keep chasing after the wind.

What does chasing after the wind mean? Have you tried doing it yourself? Perhaps not, because you know that you cannot see the wind. You cannot grasp it nor catch it. It always slips away from your hands. Since you cannot catch it at all, chasing it would be pointless. read more

How to run a Rails 6 application using Docker Compose

How to run a Rails 6 application using Docker Compose

In the previous article we learned how to create a Rails 6 Docker image and run it locally. While useful for demonstration purposes, it is not enough for a real-world web application. In addition to our main application code, there are other services that we also need, like a database, a queue system, storage and so on.

Docker Compose provides a way for us to describe how our entire application works using declarative code. Declarative code means that we specify the final state of our application, rather than specifying what steps are needed to create our application. This results in a simpler, more intuitive configuration.

docker-compose.yml

Just like we used a Dockerfile to instruct Docker on how to create our custom image, we use a docker-compose.yml file when using Compose.

First, let’s take a look at a sample Compose file for a Rails 6 application:

version: '3'

services:
app:
build: .
ports:
- 3000:3000
volumes:
- .:/usr/src/app
- gem_cache:/bundler_gems
env_file:
- .env/development
environment:
- WEBPACKER_DEV_SERVER_HOST=webpack_dev_server

db:
image: postgres
env_file:
- .env/development
volumes:
- db_data:/var/lib/postgresql/data

webpack_dev_server:
build: .
command: ./bin/webpack-dev-server
ports:
- 3035:3035
volumes:
- .:/usr/src/app
- gem_cache:/bundler_gems
env_file:
- .env/development
environment:
- WEBPACKER_DEV_SERVER_HOST=0.0.0.0

redis:
image: redis

volumes:
db_data:
gem_cache: read more

How to build a Rails 6 application using Docker

How to build a Rails 6 application using Docker

In the Introduction to Docker article, we developed a good basic foundational knowledge about container technology. Now, we will take it one step further by creating and running a Rails 6 application exclusively using Docker. As of this writing, Rails 6 is the latest version of the Ruby on Rails web application framework.

Generating the Rails code

We learned previously that we can run Ruby code using Docker even without having Ruby in our local machine. We can also use the container’s shell and run commands directly in the container. Using these, let’s try to perform some commands in a container running Ruby 2.7:

docker run -it --rm -v ${PWD}:/usr/src/app ruby:2.7 bash

The -i and -t flags (combined as -it) is necessary to be able to use the container’s shell. In this case, we also use the -v flag (volume). What is it for?

Docker Volumes

Docker provides a mechanism for storing data without being coupled to a specific container. Containers should be treated as ephemeral, meaning they can be created and destroyed at any time. Thus, we should not store data inside a container as it will also get deleted once that container is destroyed.

Volumes work by mounting it into a container. In the example above, we set it as:

-v ${PWD}:/usr/src/app

This means that the current directory is going to be mounted into the container under the path /usr/src/app. You can mount it as a readonly volume or not. For our purposes, we need it to be writable (the default) as this is where our Rails application is going to run.

Installing the Rails gem

We need to prepare the project directory in our local machine. For example, we will create our Rails application under a projects folder:

mkdir -p ~/projects
cd ~/projects

Then we run the command to use the bash shell of a Ruby 2.7 container:

docker run -it --rm -v ${PWD}:/usr/src/app ruby:2.7 bash

Great! Now we can access the shell and run commands inside the container. Note that the default Docker user is root, so all commands here will run under the root user.

[email protected]_id:/# cd /usr/src/app
[email protected]_id:/# gem install rails

Since we are using a Ruby container, RubyGems is already installed by default and so we can use the gem command immediately.

Javascript Dependencies

Rails 6 comes with a gem called webpacker, which is basically a Ruby wrapper for the webpack library. Webpacker requires yarn (an alternative to npm) and most Javascript libraries require Node to be installed as well. Thus we will need to install these first in the container before we proceed with creating our project.

# Add the Node source
[email protected]_id:/# curl -sL https://deb.nodesource.com/setup_14.x | bash

# Add the yarn source
[email protected]_id:/# curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
[email protected]_id:/# echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

# Install Node and yarn
[email protected]_id:/# apt-get update -yqq && apt-get install -yqq --no-install-recommends \
nodejs \
yarn read more

Introduction to Docker

Introduction to Docker

Docker is perhaps responsible for the proliferation of containers in application development. The concept of containers is quite old, and can be traced back in the 1980s by chroot wherein different user spaces can be used within the same operating system. Once Docker was introduced however, it paved the way for further developments in containerization and changed the way how we develop and deploy software.

In this article we will discuss how to install and setup Docker in your local machine. Common Docker commands will be introduced that will equip you with foundational knowledge for tackling the next steps in application development using containers (such as Compose).

Installing Docker

The following steps are specific to most Linux distributions, but after the installation step, the concepts discussed here can be applied to any operating system.

First, we need to ensure that old versions of Docker are removed so that we can install the latest version.

sudo apt-get remove docker docker-engine docker.io containerd runc

Update your package repositories and install the requirements for Docker.

sudo apt-get update 
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common

Install Docker’s official GPG key and add the stable repository.

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"

Update the repositories again and install Docker CE, the CLI and associated packages. The CE means “Community Edition”, which is the free, open-source version of Docker. Docker (the company) also has an “Enterprise Edition” (EE) that is targeted specifically for businesses and large deployments. Both CE and EE share the same core features, but EE has more advanced management and support systems.

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Note: If you encountered an error similar to the message below and you were not able to install Docker:

Package 'docker-ce' has no installation candidate read more

Path of Least Regret

As we live and get older, we learn a lot of things about life. Good and bad experiences serve us lessons and make us more equipped when dealing with our unpredictable future. We can also tap other people’s experiences to open us to new ideas. These thoughts were highlighted one day when my wife said that she appreciated my calm demeanor even though things are not going well. While I am not always like this, when I think about it, I attribute this behavior to one principle: living life on the path of least regret. read more