Self Hosting Gitlab using Quadlets
| 3 minutes read§ What are Quadlets?
I self-host most of my services important to me personally. Lately, I have been using Quadlets for this. I came across the concept of Quadlets from Immich.
For git repositories, I have been just using git init --bare in a server and
plain SSH to work them: git clone git@<user>:sources/<repo>.
Having used Quadlets with Immich, I thought of trying using them with Gitlab. And this post talks about how to do that.
§ Podman Setup
Before setting up the quadlet, there are some packages required for podman to
function fine with networking. I installed: aardvark-dns, dbus-user-session, passt, podman, uidmap. But some packages from this list may not be needed for
gitlab as it’s just a single container.
§ Gitlab Setup
Basically, all that we need to do is define:
.config/containers/systemd/gitlab.container
[Unit]
Description=GitLab Container
After=network-online.target
Wants=network-online.target
# This ensures that the container won't start unless the directories are
# available.
# I need this since my file system is double encrypted - FDE with LUKS for
# system) and file-level encryption, managed by `ansible`. You might not need
# this if this path is guaranteed to be available.
ConditionPathExists=<path-to-data-directory>/repositories
[Container]
Image=docker.io/gitlab/gitlab-ce:latest
ContainerName=gitlab
ShmSize=256m
PublishPort=3939:80
PublishPort=2222:22
Volume=<path-to-data-directory>/repositories/config:/etc/gitlab:Z
Volume=<path-to-data-directory>/repositories/logs:/var/log/gitlab:Z
Volume=<path-to-data-directory>/repositories/data:/var/opt/gitlab:Z
# Explaining, GITLAB_OMNIBUS_CONFIG
# `external_url`: I have an external reverse proxy managed by my Ansible roles.
# `nginx['listen_port']: Just listen on `80`, so that I can manage the actual
# SSL from my reverse proxy outside.
# `nginx['listen_https']: Ask `nginx` to not do SSL inside the container.
# `gitlab_rails['gitlab_shell_ssh_port']: The port I use for listening for SSH.
Environment=GITLAB_OMNIBUS_CONFIG="external_url 'https://<my-hostname>'; nginx['listen_port'] = 80; nginx['listen_https'] = false; gitlab_rails['gitlab_shell_ssh_port'] = 2222;"
[Service]
Restart=always
TimeoutStartSec=900
[Install]
WantedBy=default.target
§ Gitlab Omnibus Config
There’s quite a bit going on in the GITLAB_OMNIBUS_CONFIG. My Ansible setup
takes care of setting up SSL and exposing it over 443, so I don’t forward that
to gitlab. That’s what I configure external_url to. The nginx specific
configuration asks nginx to not do SSL and listen on 80 which I forward to
3939 outside. For SSH, the port I forward is 2222 as my node itself does its
ssh on 22.
§ Starting the Service
Once this unit file is set up, you should be able to start it with:
$ systemctl --user daemon-reload
$ systemctl --user enable --now gitlab.service
For the first launch, getting the image will take some time. You can look at the
status using:
systemctl status --user gitlab.
Once it is up and running, use journalctl --user -fu gitlab to look at the
service logs.
Now, ideally if you set up your reverse proxy right, you should be able to access
gitlab over your hostname.
§ Gitlab Configuration
We do need to take care of one more thing, that is the root password. You can
find it under your config directory in the file initial_root_password. Use this
password with the username root for further configuration as per
next steps documentation.
§ Why Quadlets?
Podman and Quadlets can manage a significantly more complex configuration (for
instance, Immich via
this handbook).
I find this much easier to manage than docker-compose.yaml, which isn’t
ergonomic with Ansible. Additionally, podman doesn’t need any daemon running
like Docker for it to be useful.