Using Certbot with Docker-Compoes

I am fairly new to this so I will try to include all pertinent info, and please forgive what is probably a very obvious a silly thing that I've missed. I have a golang docker container which my app is built in and am trying to install an SSL certificate. I am using the golang:1.16-alpine image for my app.

Here is my Dockerfile:

 # syntax=docker/dockerfile:1
 
 FROM golang:1.16-alpine
 
 WORKDIR /app
 
 COPY go.mod ./
 COPY go.sum ./
 
 RUN go mod download
 
 COPY * ./
 COPY templates/* ./templates/
 
 RUN go build -o /docker-gs-ping
 
 RUN apk add python3 python3-dev py3-pip build-base libressl-dev musl-dev libffi-dev rust cargo
 
 RUN pip3 install pip --upgrade
 RUN pip3 install certbot-nginx
 RUN mkdir /etc/letsencrypt
 
 EXPOSE 8080
 
 CMD [ "/docker-gs-ping" ]

Here is my docker-compose.yml:

 version: "3.4"
 services:
   phpmyadmin:
     image: phpmyadmin/phpmyadmin
     environment:
       - PMA_ARBITRARY=1
       - PMA_HOST=db
       - PMA_PORT=3306
     restart: always
     ports:
       - 8081:8081
     volumes:
       - /sessions
     depends_on:
       - db
   db:
     image: mysql:latest
     environment:
       MYSQL_ROOT_PASSWORD: ah83is82js95pq
       MYSQL_DATABASE: northernairport
     ports:
       - "3306:3306"
     volumes:
       - ./data:/docker-entrypoint-initdb.d
     restart: always
   app:
     container_name: NorthernAirport
     build:
       dockerfile: Dockerfile
       context: .
     ports:
       - "80:80"
       - "443:443"
     restart: always
     volumes:
       - ./public:/var/www/html

Finally my nginx.conf:

 server {
     listen       80;
     server_name  northernair.xyz;
 
     location / {
         root   /app;
         index  index.gohtml;
     }
 
     error_page   500 502 503 504  /50x.html;
     location = /50x.html {
         root   /usr/share/nginx/html;
     }
 }

My domain is:
northernair.xyz

I ran this command:
docker-compose up

It produced this output:
the certbot service fails:

certbot_1 | Certbot failed to authenticate some domains (authenticator: webroot). The Certificate Authority reported these problems:
certbot_1 | Domain: northernair.xyz
certbot_1 | Type: connection
certbot_1 | Detail: Fetching http://northernair.xyz/.well-known/acme-challenge/83JtXGlU7qqx7hKaJ1W5YkNBJSvmMmb4RyITNR_q3Yo: Connection refused

My web server is (include version):
golang1.16-alpine docker image

The operating system my web server runs on is (include version):
Ubuntu

My hosting provider, if applicable, is:
Digital Ocean

I can login to a root shell on my machine (yes or no, or I don't know):
yes

I'm using a control panel to manage my site (no, or provide the name and version of the control panel):
no

The version of my client is (e.g. output of certbot --version or certbot-auto --version if you're using Certbot):
not sure how to complete this within my container but I see this output in when building:

certbot-1.24.0-py3-none-any.whl

Please edit your post using backticks for code.

```
Like this
```

That said, if you want to install certbot via pip, there are instructions on the website: Certbot Instructions | Certbot

(You need to use a venv)

But there's a docker image for certbot itself, if you need it. It's certbot/certbot -- just be extra careful and don't run it without configuring its volumes well. (Also: it can't reload other containers without some hacking)

https://eff-certbot.readthedocs.io/en/stable/install.html#running-with-docker

2 Likes

I altered my Dockerfile according to the Certbot docs you sent:

RUN apk update
RUN apk add python3 py3-virtualenv augeas
RUN python3 -m venv /opt/certbot/
RUN source /opt/certbot/bin/activate
RUN /opt/certbot/bin/pip install --upgrade pip setuptools wheel
RUN /opt/certbot/bin/pip install certbot
RUN ln -s /opt/certbot/bin/certbot /usr/bin/certbot
RUN certbot certonly --webroot

Now I get this error

Building wheel for cffi (setup.py): finished with status 'error'
error: subprocess-exited-with-error

× python setup.py bdist_wheel did not run successfully.
│ exit code: 1
╰─> [45 lines of output]

Don't run certbot certonly in your dockerfile, that's not a setup command, it's a command to issue a certificate: it should be run manually once or as an entry point (just make sure it doesn't renew a certificate before its time).

There are two issues with using certbot inside docker, tho:

  1. You cannot reload the webserver.
  2. You cannot run certbot with cron o a systemd timer for autorenewal (and you have to share a webroot with the webserver) unless you use the host's cron, defeating the point.

I wouldn't do it. It's very complex and there are just too many possibilities for messing it up.

Running certbot on the host machine and putting a nginx reverse proxy and TLS terminator in front is what I would do.

(The error you get from python can be related to the different libraries in Alpine, musl instead of the common glibc)

1 Like

I don't necessarily need certbot in my container but I was not aware how else to accomplish HTTPS with my web app that is in a docker container. Can you point me to some docs describing what you are recommending?

You can install nginx and certbot on the host machine, use the instructions on certbot.eff.org

Then, find a tutorial or the documentation to use nginx as a "reverse proxy"

You'll have to configure nginx to serve your website on the public interface over https, and then it will proxy unencrypted requests on localhost to your container/containers.

Ask questions if you have them.

Other maybe simpler solutions can be Caddy or traefik, but I have never used those. They should really be simpler.

1 Like

this has been quite helpful but when I get to step 8 it simply says:
"You'll need to install your new certificate in the configuration file for your webserver."

Looking this up I see about 100 different ways of doing this and it isn't clear to me what I should be doing. Can you offer any guidance? I think after that I am good to go.

1 Like

It's nginx, right?

You have to add the appropriate directives in the nginx config (I don't remember the paths on the docker image).

See the format on ssl-config.mozilla.org

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.