Dogfooding it, Pt 6 - Gitea
Considering the amount of configuration files necessary, this blog needs a backing source repository. And, since it's about independence of cloud services, GitHub or a third-party hosted GitLab or Gitea is out. That's exactly the sort of thing we don't want. Instead, this post details how to add a Gitea instance to our homelab.
Unlike Traefik, where I showed how to make the static configuration live in a configuration file, for Gitea, we'll make the configuration live in environment variables and, where necessary, Docker secrets. And, since we're stuck with the Compose specification version 2.3.8, we'll need to work with a monolithic compose file still. One of the reasons I want it all version-controlled...
So, first, we'll prepare the Postgres database we'll be using.
$ pwgen > secrets/gitea
Edit the compose file and add the following to the secrets secion
gitea:
file:: /home/<your user>/secrets/gitea
And make that secret available to the postgres server by adding to the postgres section, under secrets:
- gitea
Then update the stack:
$ docker stack deploy -c <compose file> --prune homelab
Next, create the database user and database to use for Gitea.
$ docker container ls
$ docker container exec -it <postgres container ID> bash
$ $ psql -U postgres << EOSQL
create role gitea with login password '$(cat /run/secrets/gitea)';
create database gitea with owner gitea;
grant all privileges on database gitea to gitea;
EOSQL
Note that we don't pass a password to the psql invocation - the postgres container is configured to trust connections on its UNIX socket. For the moment, that's fine - any attacker that can get to the container's UNIX socket already has enough privileges to also change the configuration file to allow such a connection without authentication.
Now, add the Gitea service to your compose file:
gitea:
depends_on:
- postgres
deploy:
labels:
traefik.enable: "true"
traefik.http.routers.gitea-http-rtr.entrypoints: websecure
traefik.http.routers.gitea-http-rtr.rule: "Host(`gitea.<your domain>`)"
traefik.http.routers.gitea-http-rtr.service: "gitea"
traefik.http.services.gitea.loadbalancer.server.port: "3000"
traefik.tcp.routers.gitea-ssh-rtr.entrypoints: ssh
traefik.tcp.routers.gitea-ssh-rtr.rule: "HosSNI(`*`)"
traefik.tcp.routers.gitea-ssh-rtr.service: "gitea-ssh"
traefik.tcp.services.gitea-ssh.loadbalancer.server.port: "2222"
replicas: 1
environment:
GITEA__database__DB_TYPE: "postgres"
GITEA__database__HOST: "postgres"
GITEA__database__NAME: "gitea"
GITEA__database__USER: "gitea"
GITEA__database__PASSWD__FILE: "/run/secrets/gitea"
GITEA__server__ROOT_URL: "https://gitea.<your domain>"
GITEA__cors__ENABLED: "true"
GITEA__cors__ALLOW_DOMAIN: "https://*.<your domain>"
GITEA__server__DOMAIN: "gitea.<your domain>"
image: "gitea/gitea:1-rootless"
logging:
driver: journald
networks:
- homelab
restart: on-failure
secrets:
- gitea
user: "10004:10004"
volumes:
- "/srv/data/docker/gitea/data:/var/lib/gitea:rw"
- "/srv/data/docker/gitea/config:/etc/gitea:rw"
So, to explain the configuration, we label this host for two Traefik routers.. One is our standard HTTP router for the web interface. The other is a TCP router for Gitea's SSH server. We'll get back to that guy. Our environment variables set Gitea up to use the Postgres database with user gitea and the secret we established earlier. We enable CORS and restrict allowed domains to our own - in case we want to integrate Gitea resources in other things we do down the line. We also set our root URL and domain name, since we are behind a reverse proxy, and tell Gitea the proxy communicates information using the proxy protocol.
We still need the volumes we want to mount, so
$ mkdir -p /srv/data/docker/gitea/{config,data}
$ sudo chown -R 10004:10004 /srv/data/docker/gitea
$ sudo chmod -R g-rwx,o-rwx /srv/data/docker/gitea
This is enough to bring Gitea itself up, but we still need to tell our reverse proxy about the new SSH endpoint. So, we need to add to traefik.toml:
[entryPoints.ssh]
address = ":10022"
And to our compose file, for the traefik service, under ports:
- "10022:10022"
At this point, we can deploy our stack.
$ docker stack rm homelab
$ docker stack deploy -c <compose file> --prune homelab
Since we are making a change to a static configuration file, we have to bring the stack down and redeploy - we can't just update.
Once the stack is up and running, point a web browser to https://gitea.<domain> and complete the installation. Simply clicking Install Gitea should work, but you may want to create your admin user here.
The configuration files (secrets exempt) after this chapter are available at https://gitea.turriff.net/andreas/Homelab/src/tag/Dogfooding_it_Pt_6 .