# Gitea - [Gitea](#gitea) - [Gitea on Rootless Podman](#gitea-on-rootless-podman) - [A note on directories](#a-note-on-directories) - [Create the gitea user](#create-the-gitea-user) - [Convert Compose to Quadlet](#convert-compose-to-quadlet) - [Install Quadlets](#install-quadlets) - [Upgrade](#upgrade) - [Editing Gitea Config](#editing-gitea-config) - [Gitea Runners](#gitea-runners) - [Firewall Rules](#firewall-rules) - [Install](#install) - [Cache Cleanup](#cache-cleanup) - [Email Notifications](#email-notifications) ## Gitea on Rootless Podman ### A note on directories ```bash 2025/07/30 16:49:12 cmd/web.go:116:showWebStartupMessage() [I] * AppPath: /usr/local/bin/gitea 2025/07/30 16:49:12 cmd/web.go:117:showWebStartupMessage() [I] * WorkPath: /var/lib/gitea 2025/07/30 16:49:12 cmd/web.go:118:showWebStartupMessage() [I] * CustomPath: /var/lib/gitea/custom 2025/07/30 16:49:12 cmd/web.go:119:showWebStartupMessage() [I] * ConfigFile: /etc/gitea/app.ini 2025/07/30 16:49:12 modules/storage/storage.go:176:initAttachments() [I] Initialising Attachment storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/attachments 2025/07/30 16:49:12 modules/storage/storage.go:166:initAvatars() [I] Initialising Avatar storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/avatars 2025/07/30 16:49:12 modules/storage/storage.go:192:initRepoAvatars() [I] Initialising Repository Avatar storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/repo-avatars 2025/07/30 16:49:12 modules/storage/storage.go:198:initRepoArchives() [I] Initialising Repository Archive storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/repo-archive 2025/07/30 16:49:12 modules/storage/storage.go:208:initPackages() [I] Initialising Packages storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/packages 2025/07/30 16:49:12 modules/storage/storage.go:219:initActions() [I] Initialising Actions storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/actions_log 2025/07/30 16:49:12 modules/storage/storage.go:223:initActions() [I] Initialising ActionsArtifacts storage with type: local 2025/07/30 16:49:12 modules/storage/local.go:33:NewLocalStorage() [I] Creating new Local Storage at /var/lib/gitea/data/actions_artifacts ``` ### Create the gitea user ```bash useradd gitea loginctl enable-linger $(id -u gitea) systemctl --user --machine=gitea@.host enable podman-restart systemctl --user --machine=gitea@.host enable --now podman.socket su -l gitea mkdir -p .config/containers/systemd mkdir data config postgres exit ``` ### Convert Compose to Quadlet ```bash # Run this in Homelab, not on the server. mkdir $(pwd)/active/podman_gitea/quadlets # Generate the systemd service podman run \ --network none \ --rm \ -v $(pwd)/active/podman_gitea/compose:$(pwd)/active/podman_gitea/compose:z \ -v $(pwd)/active/podman_gitea/quadlets:$(pwd)/active/podman_gitea/quadlets:z \ quay.io/k9withabone/podlet \ -f $(pwd)/active/podman_gitea/quadlets \ -i \ --overwrite \ compose $(pwd)/active/podman_gitea/compose/compose.yaml # Copy the files to the server scp -r $(pwd)/active/podman_gitea/quadlets/. 3dserver:/home/gitea/.config/containers/systemd/ ``` ### Install Quadlets First, set up the volumes needed by the container. ```bash # Enter the container namespace podman unshare # Create the volumes mkdir gitea_data chown -R 1000:1000 gitea_data mkdir gitea_etc chown -R 1000:1000 gitea_etc exit ``` Now launch the service. The first user you register will be the admin. ```bash # Create a systemctl viable shell machinectl shell gitea@ systemctl --user daemon-reload systemctl --user restart gitea postgres # Enables auto-update service which will pull new container images automatically every day systemctl --user enable --now podman-auto-update.timer ``` ### Upgrade 1. Check [the blog](https://blog.gitea.com/) for any breaking changes. 2. Update the `compose.yaml` with any needed changes 3. [Regenerate the quadlets](#convert-compose-to-quadlet) 4. Upload the new quadlets and restart the service ```bash # Upload quadlets and restart export PODMAN_SERVER=3dserver scp -r active/podman_gitea/quadlets/. $PODMAN_SERVER:/home/gitea/.config/containers/systemd/ ssh $PODMAN_SERVER chown -R gitea:gitea /home/gitea/.config/containers/systemd/ ssh $PODMAN_SERVER machinectl shell gitea@ systemctl --user daemon-reload systemctl --user restart gitea postgres ``` ### Editing Gitea Config ```bash # Use podman unshare to work within the container's namespace podman unshare vim ~/gitea_data/gitea/conf/app.ini ``` ## Gitea Runners ### Firewall Rules Since our runner will be contacting our public IP, we need to add a firewall rule to allow traffic from our DMZ network to our DMZ network. Do this in Unifi or whatever equivalent you have. ### Install ```bash touch config.yaml export GITEA_TOKEN= docker run \ -v /var/run/docker.sock:/var/run/docker.sock \ -e GITEA_INSTANCE_URL=https://gitea.reeseapps.com \ -e GITEA_RUNNER_REGISTRATION_TOKEN=$GITEA_TOKEN \ -e GITEA_RUNNER_NAME=gitea_runner \ --restart always \ --name gitea_runner \ -d docker.io/gitea/act_runner:latest ``` ### Cache Cleanup Each org or project with a package registry will have its own cleanup rules. For example, services -> settings -> Packages -> Add Cleanup Rule will allow you to create a cleanup rule for packages stored under the "services" org. These cleanup rules should run automatically. You'll need to enable `cron` and `cron.cleanup_packages` in the app.ini (/data/gitea/conf). Cron: Package Cleanup: ```conf [cron] ENABLED = true RUN_AT_START = true NOTICE_ON_SUCCESS = true SCHEDULE = @midnight [cron.cleanup_packages] ENABLED = true RUN_AT_START = true SCHEDULE = @midnight NOTICE_ON_SUCCESS = true ``` On the other hand, the docker builder cache will balloon out of control over time. The gitea docker runner is handled outside of Gitea's context, so you'll need to clean it up yourself. ```bash # Check used system resources docker system df ``` You should run something like this on a schedule: ```bash # Prune the builder cache docker builder prune -a ``` To run it every day at noon: `crontab -e` ```bash 0 12 * * * yes | docker builder prune -a 0 12 * * * docker image prune -a -f ``` ## Email Notifications In `/data/gitea/conf/app.ini` add (yes, the `` around the password matters): ```conf [mailer] ENABLED = true FROM = gitea@reeseapps.com PROTOCOL = smtps SMTP_ADDR = email-smtp.us-east-1.amazonaws.com SMTP_PORT = 465 USER = ABC123 PASSWD = `ABC123...` ```