Gitea docker-compose certbot

I am trying to run a gitea server with https using certbot.

For this purpose I am using docker compose:

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: gitea/gitea:1.20
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - FORGEJO__database__DB_TYPE=postgres
      - FORGEJO__database__HOST=db:5432
      - FORGEJO__database__NAME= gitea
      - FORGEJO__database__USER= gitea
      - FORGEJO__database__PASSWD= gitea
    restart: unless-stopped
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
      - ./etc/letsencrypt:/etc/letsencrypt
    ports:
      - "443:443"
      - "222:22"
    depends_on:
      - db
      - certbot

  db:
    image: postgres:14
    restart: unless-stopped
    environment:
      - POSTGRES_USER= gitea
      - POSTGRES_PASSWORD= gitea
      - POSTGRES_DB= gitea
    networks:
      - gitea
    volumes:
      - ./postgres:/var/lib/postgresql/data

  certbot:
    container_name: certbot
    build: .
    command: >
             certonly
            ...
    volumes:
      - ./etc/letsencrypt:/etc/letsencrypt
      - ./certbot/data:/var/www/certbot
      - ./certbot/logs:/var/log/letsencrypt

I know that the certificates are there, but there is a problem with the permissions.
The certificates have one 700 accessibility by root.
Now if I run the container of gitea I get the following error:

cmd/web_https.go:170:runHTTPS() [E] Failed to load https cert file /etc/letsencrypt/live/mydomain.com/cert.pem for tcp:0.0.0.0:443: open /etc/letsencrypt/live/mydomain.com/cert.pem: permission denied

which makes kind of sense. I do not want to reduce the security level of the certificates of course, so I tried running gitea with root by changing the user in the docker-compose.yml file

      - USER_UID=0
      - USER_GID=0

which only yielded the following error message:

[F] Gitea is not supposed to be run as root. Sorry. If you need to use privileged TCP ports please instead use setcap and the `cap_net_bind_service` permission

which I do not understand. I do not think I am looking for a privileged TCP port, but I just want gitea to be able to access the certificates without having to expose them publicly.

I am not sure what to do? Is this something that is supported?

You could setup a certbot renewal hook that copies the certificates to Gitea’s directory and allows Gitea to read them.

Here’s an example certbot - give systemd service access to certificates in protected folder - Server Fault.

@Jake, yes, I could. Though I am not very comfortable with this solution.

I am no expert on security, but it feels like having your passwords secured in a safe and but leaving a copy on your desk.

How does that make sense?

Realistically the solution of setting Gitea to run as root would be worse, as it would have full control over the system and if an exploit were discovered they would gain access to everything.

If someone just steals your TLS certificate and key, they could impersonate your service only if they gain access to your DNS server/domain registrar accounts, which is unlikely if you use good passwords and 2FA. They could also theoretically decrypt user communications, but this would require them being on the same network as the victim or having control over an upstream network (e.g., being an ISP).

You can set the permissions of the copied certificates/keys to be restricted so that only the Gitea user has access to it. You could also separate your domains (say git.example.com) and only give Gitea access to that keypair.

1 Like

@Jake That makes sense.

I confirmed that copying the files is the most appropriate solution to the issue.

Thank you guys very much for the help :slight_smile:

Thank you for the clarification.

I confirmed with the guys from Let’s Encrypt that this is the most appropriate solution.
Preserve security when service cannot access certificates - Help - Let's Encrypt Community Support.

Seems like automatic copying is the most appropriate solution.

1 Like