perpetuum mobile
03. 12. 2018. docker * aws * ruby


Installing Docker CE for Ubuntu

# Uninstall old versions
$ sudo apt-get remove docker docker-engine

# Install packages to allow apt to use a repository over HTTPS    
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

# Add Docker’s official GPG key
$ curl -fsSL | sudo apt-key add -

# set up the stable repository
$ sudo add-apt-repository "deb [arch=amd64] $(lsb_release -cs) stable"

# Install Docker CE
$ sudo apt-get update
$ sudo apt-get install docker-ce

# Verify that Docker CE is installed correctly
$ sudo docker run hello-world

Docker cheat sheet

## List Docker CLI commands
docker container --help

## Display Docker version and info
docker --version
docker version
docker info

## Execute Docker image
docker run hello-world

## List Docker images
docker image ls

## List Docker containers (running, all, all in quiet mode)
docker container ls
docker container ls --all
docker container ls -aq

Uninstalling Docker CE

$ sudo apt-get purge docker-ce
$ sudo rm -rf /var/lib/docker

Installing Docker Compose

# download the latest version of Docker Compose
# (Use the latest Compose release number in the download command:
$ sudo curl -L "$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Apply executable permissions to the binary
$ sudo chmod +x /usr/local/bin/docker-compose

# Test the installation
$ docker-compose --version

Add docker and docker-compose to the plugins array of your zshrc file:

plugins=(... docker docker-compose)

Uninstalling Docker Compose

$ sudo rm /usr/local/bin/docker-compose


# Create a directory for the project
$ mkdir composetest
$ cd composetest

Create Dockerfile at the project root:

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY /usr/bin/
RUN chmod +x /usr/bin/

# Start the main process.
CMD ["rails", "server", "-b", ""]

That’ll put your application code inside an image that builds a container with Ruby, Bundler and all your dependencies inside it.

( –> more information on how to write Dockerfiles )

Create a bootstrap Gemfile

source ''
gem 'rails', '~>5'

Create an empty Gemfile.lock

touch Gemfile.lock

Next, provide an entrypoint script to fix a Rails-specific issue that prevents the server from restarting when a certain file pre-exists. This script will be executed every time the container gets started. consists of:

set -e

# Remove a potentially pre-existing for Rails.
rm -f /myapp/tmp/pids/

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"

Create docker-compose.yml

version: '3'
    image: postgres
      - ./tmp/db:/var/lib/postgresql/data
    build: .
    command: bash -c "rm -f tmp/pids/ && bundle exec rails s -p 3000 -b ''"
      - .:/myapp
      - "3000:3000"
      - db

Build the project

$ sudo docker-compose run web rails new . --force --no-deps --database=postgresql

# change the ownership of new files
$ sudo chown -R $USER:$USER .

Whenever Gemfile or Dockerfile change, it is necessary to rebuild the project:

$ sudo docker-compose build web

To connect the database, edit the contents of config/database.yml to match this:

default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  pool: 5

  <<: *default
  database: myapp_development

  <<: *default
  database: myapp_test

Create the db in another terminal

$ sudo docker-compose run web rails db:create

After that, rails app is bootable:

$ sudo docker-compose up

The app is running on http://localhost:3000

Stop the application

$ sudo docker-compose down

Restart the application

$ sudo docker-compose up     

Rebuild the application

$ sudo docker-compose run web bundle install
$ sudo docker-compose up --build