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:
- nginx - As reverse-proxy taking incoming request and passing them to the respective service.
- jwilder/docker-gen - Generating the correct configuration for the nginx container.
- jrcs/letsencrypt-nginx-proxy-companion - Issueing and Renewing the SSL certificate via Let’s Encrypt and invoking config regeneration and reload via
docker-gen
for thenginx
service. - custom rails app image
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.