Docker

Going live

Where we left off

Dockerfile

FROM ruby:2.2.2

# deps
RUN apt-get update -qq && apt-get install -y build-essential nodejs npm nodejs-legacy mysql-client vim

RUN mkdir /lunchiatto

WORKDIR /tmp
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install --without development test

ADD . /lunchiatto
WORKDIR /lunchiatto
RUN npm install -g bower
RUN bower install --allow-root
RUN bundle exec rake assets:clobber
RUN bundle exec rake assets:precompile --trace

docker-compose.yml

db:
  image: postgres:9.4.1
  ports:
    - "5432:5432"
web:
  build: .
  command: bundle exec puma -C config/puma.rb
  ports:
    - "3000:3000"
  links:
    - db
  env_file: .prod-env

VPS

VPS

  • Digital Ocean
  • Ubuntu 14.04 with docker
  • 512 MB Ram
  • 1 CPU
  • 20 GB

Nginx

upstream lunchiatto_app {
    server 127.0.0.1:3000;
}

server {
    listen 80;
    server_name www.lunchiatto.com;
    return 301 https://$server_name$request_uri;
}

Nginx

server {
        # Running port
        listen 443;
        server_name www.lunchiatto.com;

        # SSL
        ssl_certificate /etc/ssl/certs/ssl-bundle.crt;
        ssl_certificate_key /etc/ssl/certs/lunchiatto.key;

        ssl on;
        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;

        # Proxying the connections connections
        location / {

            proxy_pass         http://lunchiatto_app;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;

        }
}

production.Dockerfile

FROM ruby:2.2.3

# deps
RUN apt-get update -qq && apt-get install -y build-essential nodejs npm nodejs-legacy

# Environment variables
ENV APP_HOME=/lunchiatto
ENV BUNDLE_WITHOUT=development:test
ENV BUNDLE_FROZEN=true
RUN bundle config --global jobs 8

# setup the directory
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

COPY Gemfile* ${APP_HOME}/
RUN bundle install

#copy code
ADD . $APP_HOME

#precompile assets
RUN rake assets:precompile

Start all that

Start all that

export COMPOSE_FILE=docker-compose-prod.yml
docker-compose up -d

Not done yet

docker-compose-prod.yml

db:
  image: postgres:9.4.1

redis:
  image: redis:3.0.5

sidekiq: &sidekiq
  build: .
  dockerfile: production.Dockerfile
  command: bundle exec sidekiq -q mailers -c 2
  env_file: .env
  links:
    - db
    - redis

web:
  <<: *sidekiq
  command: bundle exec puma -C config/puma.rb
  ports:
    - "3000:3000"

Backups

Backups

#!/bin/bash
# run a backup
NAME="$(/bin/date +"%Y%m%d%H%M")_dump.sql"
BACKUP_PATH="/tmp/$NAME"
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
docker-compose run db pg_dump -U postgres -h db codequestmanager_production > $BACKUP_PATH
aws s3 cp $BACKUP_PATH s3://lunchiatto-backups/$NAME
rm $BACKUP_PATH
*/15 * * * * cd /home/bartek/lunchiatto && bin/backup

Cron

Scheduling

0 9 * * * cd /home/bartek/lunchiatto && docker-compose run web rake daily_emails:send
0 9 * * * cd /home/bartek/lunchiatto && docker-compose run web rake weekly_emails:send
0 14 * * * cd /home/bartek/lunchiatto && docker-compose run web rake status_email:send

Heroku Scheduler -> cron tasks

Problems

  • Requires manual setup
  • On host machine
  • Not in the repo

Deploys

Manual deploys

A script

#!/bin/bash
# build lunchiatto
cd /home/bartek/lunchiatto
git pull origin master
./bin/backup
docker-compose build
docker-compose up -d

A script

Get codeship involved

ssh user@your.server.ip 'COMPOSE_FILE="docker-compose-prod.yml" ~/lunchiatto/bin/build'

Add key codeship's public key to server

Deployment setup

Get codeship involved

What's next?

Docker part 2

By Bartek Kruszczyński