Add Gitea self-hosted git server

Docker Compose stack (Gitea + Postgres) on port 3000, SSH on 2222,
reverse-proxied via Caddy at git.monotrope.au.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Louis Simoneau
2026-04-10 08:14:11 +10:00
parent 5a734d404b
commit 0d7287dce1
4 changed files with 106 additions and 2 deletions

View File

@@ -1,4 +1,4 @@
.PHONY: build serve deploy ssh setup miniflux goatcounter
.PHONY: build serve deploy ssh setup miniflux gitea goatcounter enrich
# Load .env if it exists
-include .env
@@ -7,7 +7,7 @@ export
DEPLOY_USER := deploy
MONOTROPE_HOST ?=
build:
build: enrich
cd site && hugo --minify
serve:
@@ -29,6 +29,13 @@ miniflux:
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
ansible-playbook -i "$(MONOTROPE_HOST)," -u root infra/ansible/playbook.yml --tags miniflux
gitea:
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
ansible-playbook -i "$(MONOTROPE_HOST)," -u root infra/ansible/playbook.yml --tags gitea
goatcounter:
@test -n "$(MONOTROPE_HOST)" || (echo "Error: MONOTROPE_HOST is not set"; exit 1)
ansible-playbook -i "$(MONOTROPE_HOST)," -u root infra/ansible/playbook.yml --tags goatcounter
enrich:
uv run enrich.py

View File

@@ -30,6 +30,13 @@ reader.monotrope.au {
encode zstd gzip
}
# Gitea
git.monotrope.au {
reverse_proxy localhost:3000
encode zstd gzip
}
# GoatCounter analytics
stats.monotrope.au {
reverse_proxy localhost:8081

View File

@@ -10,6 +10,7 @@
miniflux_db_password: "{{ lookup('env', 'MINIFLUX_DB_PASSWORD') }}"
miniflux_admin_user: "{{ lookup('env', 'MINIFLUX_ADMIN_USER') | default('admin') }}"
miniflux_admin_password: "{{ lookup('env', 'MINIFLUX_ADMIN_PASSWORD') }}"
gitea_db_password: "{{ lookup('env', 'GITEA_DB_PASSWORD') }}"
goatcounter_version: "2.7.0"
goatcounter_admin_email: "{{ lookup('env', 'GOATCOUNTER_ADMIN_EMAIL') }}"
goatcounter_admin_password: "{{ lookup('env', 'GOATCOUNTER_ADMIN_PASSWORD') }}"
@@ -66,6 +67,7 @@
notify: Restart Caddy
tags:
- miniflux
- gitea
- goatcounter
- name: Enable and start Caddy
@@ -113,6 +115,12 @@
port: '443'
proto: tcp
- name: Allow Gitea SSH
ufw:
rule: allow
port: '2222'
proto: tcp
- name: Enable UFW
ufw:
state: enabled
@@ -197,6 +205,43 @@
chdir: /opt/miniflux
tags: miniflux
# ── Gitea ───────────────────────────────────────────────────────────────
- name: Create Gitea directory
file:
path: /opt/gitea
state: directory
owner: root
group: root
mode: '0750'
tags: gitea
- name: Copy Gitea docker-compose.yml
copy:
src: ../gitea/docker-compose.yml
dest: /opt/gitea/docker-compose.yml
owner: root
group: root
mode: '0640'
tags: gitea
- name: Write Gitea .env
copy:
dest: /opt/gitea/.env
owner: root
group: root
mode: '0600'
content: |
GITEA_DB_PASSWORD={{ gitea_db_password }}
no_log: true
tags: gitea
- name: Pull and start Gitea
command: docker compose up -d --pull always
args:
chdir: /opt/gitea
tags: gitea
# ── GoatCounter ─────────────────────────────────────────────────────────
- name: Create goatcounter system user

View File

@@ -0,0 +1,45 @@
services:
gitea:
image: gitea/gitea:latest
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "127.0.0.1:3000:3000"
- "2222:22"
volumes:
- gitea_data:/data
environment:
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: db:5432
GITEA__database__NAME: gitea
GITEA__database__USER: gitea
GITEA__database__PASSWD: "${GITEA_DB_PASSWORD}"
GITEA__server__ROOT_URL: "https://git.monotrope.au/"
GITEA__server__DOMAIN: "git.monotrope.au"
GITEA__server__SSH_DOMAIN: "git.monotrope.au"
GITEA__server__SSH_PORT: 2222
env_file:
- .env
db:
image: postgres:16-alpine
restart: unless-stopped
volumes:
- gitea_db:/var/lib/postgresql/data
environment:
POSTGRES_DB: gitea
POSTGRES_USER: gitea
POSTGRES_PASSWORD: "${GITEA_DB_PASSWORD}"
env_file:
- .env
healthcheck:
test: ["CMD", "pg_isready", "-U", "gitea"]
interval: 10s
timeout: 5s
retries: 5
volumes:
gitea_data:
gitea_db: