Post

Gitea and Personal CAs

Just a quick note about self-hosting Gitea in Docker Containers: if you’re hosting your own CA, you’ll notice that any of the secure connections outbound from Gitea will be less than pleased that none of the certs are trustworthy. It doesn’t have your root certs in place, so to fix this issue: let’s add some certificates.

This will definitely keep your webhooks from working as I might’ve found out after writing an article.

The original Docker Compose file for Gitea looks like this for me. I’m just including the gitea service which is the one we will be changing.

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
services:
  server:
    image: gitea/gitea
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=mysql
      - GITEA__database__HOST=db:3306
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=reallyawesomepassword
      - GITEA__webhook__ALLOWED_HOST_LIST=*
      - GITEA__server__ROOT_URL=https://gitea.cerberus.local
      - GITEA__server__SSH_PORT=222
    restart: always
    networks:
      - gitea
    volumes:
      - /mnt/git/gitea/data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

So, my directory layout is pretty straightforward but relevant. The docker-compose.yaml file lives in the gitea directory. Any data that Gitea needs to create (or any services in the Docker Compose file) get created in the gitea directory as well. This means that everything is self-contained.

I added a docker directory and created a Dockerfile inside of there. We’re gonna need this as we’re gonna roll the certificates into a new Docker image using gitea/gitea as the base. I host my certs on a local webserver so it’s easier just to grab them from the webserver and shove ‘em into the image.

1
2
3
4
5
6
FROM gitea/gitea

RUN cd /usr/local/share/ca-certificates && \
    /usr/bin/wget http://astinus.cerberus.local/certs/root_ca.crt && \
    /usr/bin/wget http://astinus.cerberus.local/certs/intermediate_ca.crt && \
    /usr/sbin/update-ca-certificates

The only reason we can get away with this is because wget and ca-certificates are already installed on the base image. Otherwise we’d have to install them via apk.

Next up, let’s tweak the docker-compose.yaml file to build the container and use that instead of the default gitea/gitea image. I’m gonna call my image jamesthebard/gitea and point it to the Dockerfile that lives in the docker directory.

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
services:
  server:
    image: jamesthebard/gitea
    container_name: gitea
    build: ./docker
    environment:
      - USER_UID=1000
      - USER_GID=1000
      - GITEA__database__DB_TYPE=mysql
      - GITEA__database__HOST=db:3306
      - GITEA__database__NAME=gitea
      - GITEA__database__USER=gitea
      - GITEA__database__PASSWD=reallyawesomepassword
      - GITEA__webhook__ALLOWED_HOST_LIST=*
      - GITEA__server__ROOT_URL=https://gitea.cerberus.local
      - GITEA__server__SSH_PORT=222
    restart: always
    networks:
      - gitea
    volumes:
      - /mnt/git/gitea/data:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
    depends_on:
      - db

So, after a quick build it should grab the root and intermediate CA certs from the webserver, put them in the correct directory, and then update the certificate store with those certs.

1
2
cd gitea
docker compose build

You can also test to see if the certs were installed successfully. If it doesn’t eat itself, then things are working perfectly.

1
2
docker run -it jamesthebard/gitea /bin/bash
curl https://astinus.cerberus.local

The final step is just to restart the containers.

1
docker compose down && docker compose up -d
This post is licensed under CC BY 4.0 by the author.