Let’s assume you have a simple root server and want to deploy a demo environment for your application. There is an easy docker-compose template you can use to deploy a ready-to-use environment.

This post describes a way to quickly set up a new Rails production environment with SSL encryption. The resulting services should automatically renew certificates and not need any further configuration.

Components

We use the following docker images as basis for this setup:

Setup

I assume you are working within the /srv directory.

First download the nginx template used by docker-gen container:

1
curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > nginx.tmpl

Then configure your services from the following docker-compose.yml template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
version: '3'
services:
  nginx:
    image: nginx
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
    container_name: nginx-web
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /srv/volumes/nginx/conf.d:/etc/nginx/conf.d
      - /srv/volumes/nginx/vhost.d:/etc/nginx/vhost.d
      - /srv/volumes/nginx/html:/usr/share/nginx/html
      - /srv/volumes/nginx/certs:/etc/nginx/certs:ro
  nginx-gen:
    image: jwilder/docker-gen
    command: -notify-sighup nginx-web -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    container_name: nginx-gen
    restart: always
    volumes:
      - /srv/volumes/nginx/conf.d:/etc/nginx/conf.d
      - /srv/volumes/nginx/vhost.d:/etc/nginx/vhost.d
      - /srv/volumes/nginx/html:/usr/share/nginx/html
      - /srv/volumes/nginx/certs:/etc/nginx/certs:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro
  nginx-letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: nginx-letsencrypt
    restart: always
    volumes:
      - /srv/volumes/nginx/conf.d:/etc/nginx/conf.d
      - /srv/volumes/nginx/vhost.d:/etc/nginx/vhost.d
      - /srv/volumes/nginx/html:/usr/share/nginx/html
      - /srv/volumes/nginx/certs:/etc/nginx/certs:rw
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      NGINX_DOCKER_GEN_CONTAINER: nginx-gen
      NGINX_PROXY_CONTAINER: nginx-web
  app:
    image: my_genius_app
    command: bundle exec unicorn -p 3000
    restart: always
    ports:
      - 3000
    environment: &environment
      - RAILS_ENV=production
      - VIRTUAL_HOST=sub.domain.com
      - VIRTUAL_PORT=3000
      - LETSENCRYPT_HOST=sub.domain.com
    volumes: &volumes
      - ./volumes/app/log:/app/log
      - ./volumes/app/tmp:/app/tmp
networks:
  default:
    external:
      name: webproxy

You might have noticed that we need to create the network referenced in the docker-compose.yml:

1
docker network create webproxy

Then pull the images and start the app.

1
2
docker-compose pull
docker-compose up -d

Conclusion

I hope this post could show you how easy it is to setup an SSL encrypted web host with docker-compose on a simple server.

Further credits go to evertramos/docker-compose-letsencrypt-nginx-proxy-companion, which proposes a more generalized version to bootstrap your environment.