title: docker-machine + docker-compose + ssl (lets encrypt through nginx & certbot)
body: <p>I'm trying to add automatic TLS/SSL termination to an Nginx in a <strong>docker-compose</strong> deployed through the <strong>docker-machine</strong> (DigitalOcean).</p>
  
  <p>I found a few nice resources [<a href="https://www.humankode.com/ssl/how-to-set-up-free-ssl-certificates-from-lets-encrypt-using-docker-and-nginx" rel="noreferrer">humankode/how-to-set-up...</a>, <a href="https://medium.com/@pentacent/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71" rel="noreferrer">medium/nginx-and-lets-encrypt...</a>] on how to do it through the docker-compose but they both are saying from the perspective of being on the server. I really want to avoid that. I'd love to do it locally, on my laptop, bundle it all together, and send it off. Or, even do it remotely without doing any ssh.</p>
  
  <p>A few attempts failed but it feels like they were close. The main obstacle seems to be with files/volumes. Following the <em>medium/nginx-and-lets-encrytp...</em> guide I'm having problems with saving OpenSSL privkey.pem. The other tutorial (<em>humankode</em>), to me knowledge, does everything on the server and that's where the volumes live.</p>
  
  <p>My latest attempt was to set up certificates on the machine through the <a href="https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04" rel="noreferrer">DigitalOcean tutorial</a> and try to include these through in my docker-compose build. No luck.</p>
  
  <p>There were many modifications but my settings are similar to:</p>
  
  <h3>docker-compose.yml</h3>
  
  <pre><code>version: '3.7'
  
  services:
    nginx:
      image: nginx:1.15.9-alpine
      container_name: nginx
      build:
        context: ./nginx
        dockerfile: Dockerfile
      restart: always
      volumes:
        - /etc/letsencrypt
        - /var/www/certbot
      ports:
        - "80:80"
        - "443:443"
      command: "/bin/sh -c 'while :; do sleep 6h &amp; wait $${!}; nginx -s reload; done &amp; nginx -g \"daemon off;\"'"
  
    certbot:
      image: certbot/certbot
      restart: unless-stopped
      volumes:
        - "/etc/letsencrypt"
        - "/var/www/certbot"
      entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h &amp; wait $${!}; done;'"
  </code></pre>
  
  <h3>nginx/Dockerfile</h3>
  
  <pre><code>FROM nginx:1.15.9-alpine
  
  RUN rm /etc/nginx/conf.d/default.conf
  COPY prod.conf /etc/nginx/conf.d/
  </code></pre>
  
  <h3>nginx/conf.d</h3>
  
  <pre><code># PRODUCTION
  server {
      listen 80;
      listen [::]:80;
      server_name example.site;
  
      location ~ /.well-known/acme-challenge {
          allow all;
          root /usr/share/nginx/html;
      }
  
      location / {
          return 301 https://$host$request_uri;
      }
  }
  
  server {
      listen 443 ssl;
      server_name example.site;
  
      ssl_certificate /etc/letsencrypt/live/example.site/fullchain.pem;
      ssl_certificate_key /etc/letsencrypt/live/example.site/privkey.pem;
  
      include /etc/letsencrypt/options-ssl-nginx.conf;
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  </code></pre>