yurko
3/16/2018 - 10:17 AM

Dockerize Rails (Puma + Postgres + Nginx)

Dockerize Rails (Puma + Postgres + Nginx)

# From http://chrisstump.online/2016/02/20/docker-existing-rails-application/

upstream puma {
  server app:3000;
}

server {
  # define your domain
  server_name my_app.com;

  # define the public application root
  root   /app/public;
  index  index.html;

  # define where Nginx should write its logs
  access_log /app/log/nginx.access.log;
  error_log /app/log/nginx.error.log;

  # deny requests for files that should never be accessed
  location ~ /\. {
    deny all;
  }

  location ~* ^.+\.(rb|log)$ {
    deny all;
  }

  # serve static (compiled) assets directly if they exist (for rails production)
  location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
    try_files $uri @rails;

    access_log off;
    gzip_static on; # to serve pre-gzipped version

    expires max;
    add_header Cache-Control public;

    # Some browsers still send conditional-GET requests if there's a
    # Last-Modified header or an ETag header even if they haven't
    # reached the expiry date sent in the Expires header.
    add_header Last-Modified "";
    add_header ETag "";
    break;
  }

  # send non-static file requests to the app server
  location / {
    try_files $uri @rails;
  }

  location @rails {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://puma;
  }
}
app:
  env_file: .env
  build: .
  entrypoint: bundle exec
  command: rails server -p 3000
  volumes:
    - .:/app
  ports:
    - "3000"
  links:
    - postgres
postgres:
  env_file: .env
  image: postgres:9.4
  ports:
    - "5432"
nginx:
  image: nginx
  links:
    - app
  volumes_from:
    - app
  volumes:
    - ./nginx.conf:/etc/nginx/conf.d/my_app.conf:ro
  ports:
    - "80:80"
# From one of the official ruby images
FROM ruby:2.4.1-alpine

# Available (and reused) args
# Use --build-arg APP_PATH=/usr/app to use another app directory
# Use --build-arg PORT=5000 to use another app default port
ARG APP_PATH='/app'
ARG PORT=3000

# Setting env up
ENV RAILS_ENV='production'
ENV RAKE_ENV='production'

# Installing required packages
RUN apk add --no-cache \
    build-base \
    tzdata \
    git \
    postgresql-dev \
    nodejs \
    imagemagick

# Configuring main directory
RUN mkdir -p $APP_PATH
WORKDIR $APP_PATH

# Adding gems
COPY Gemfile* ./
RUN bundle install --jobs 20 --retry 5 --without development test

# Adding project files
COPY . ./
RUN bundle exec rake DATABASE_URL=postgres:does_not_exist assets:precompile

EXPOSE $PORT
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]

# Metadata
LABEL org.label-schema.vendor="David Dérus" \
      org.label-schema.url="https://davidderus.com" \
      org.label-schema.name="RailsApp" \
      org.label-schema.description="A Rails production server using Puma and precompiling assets" \
      org.label-schema.version="v1.1.0" \
      org.label-schema.docker.schema-version="1.0"
.git
.gitignore
/doc
.yardoc
coverage
jsdoc
/tmp
/log
Dockerfile
Dockerfile.prod
docker-compose.yml
README.md
/public/uploads
/test/reports
.env
.envrc
.byebug_history
.rake_tasks