feat: add Gitea self-hosted Git service with Actions runner

- Create new 'dev' stack at dev.pivoine.art
- Add Gitea with PostgreSQL database (core stack)
- Add Gitea Actions runner with Docker support
- Enable mailer configuration via SMTP
- Enable container registry and packages
- Add gitea database to PostgreSQL init script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-15 11:43:13 +01:00
parent f25856a44b
commit d32ac39d27
4 changed files with 104 additions and 0 deletions

View File

@@ -155,6 +155,14 @@ envs:
MEDIA_FILESTASH_IMAGE: machines/filestash:latest
MEDIA_FILESTASH_TRAEFIK_HOST: filestash.media.pivoine.art
MEDIA_FILESTASH_CANARY: true
# Dev (Gitea + Runner)
DEV_TRAEFIK_ENABLED: true
DEV_COMPOSE_PROJECT_NAME: dev
DEV_GITEA_IMAGE: gitea/gitea:latest
DEV_GITEA_TRAEFIK_HOST: dev.pivoine.art
DEV_GITEA_DB_NAME: gitea
DEV_GITEA_RUNNER_IMAGE: gitea/act_runner:latest
DEV_GITEA_RUNNER_NAME: docker-runner
# PairDrop
DROP_TRAEFIK_ENABLED: true
DROP_COMPOSE_PROJECT_NAME: drop

View File

@@ -21,6 +21,7 @@ include:
- proxy/compose.yaml
- watch/compose.yaml
- media/compose.yaml
- dev/compose.yaml
networks:
compose_network:

View File

@@ -41,6 +41,10 @@ psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-E
SELECT 'CREATE DATABASE asciinema'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'asciinema')\\gexec
-- Gitea self-hosted Git service database
SELECT 'CREATE DATABASE gitea'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'gitea')\\gexec
-- Grant privileges to all databases
GRANT ALL PRIVILEGES ON DATABASE directus TO $POSTGRES_USER;
GRANT ALL PRIVILEGES ON DATABASE umami TO $POSTGRES_USER;

91
dev/compose.yaml Normal file
View File

@@ -0,0 +1,91 @@
services:
# Gitea - Self-hosted Git service
gitea:
image: ${DEV_GITEA_IMAGE:-gitea/gitea:latest}
container_name: ${DEV_COMPOSE_PROJECT_NAME}_gitea
restart: unless-stopped
depends_on:
- gitea_runner
volumes:
- gitea_data:/data
- gitea_config:/etc/gitea
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
TZ: ${TIMEZONE:-Europe/Berlin}
USER_UID: 1000
USER_GID: 1000
GITEA__database__DB_TYPE: postgres
GITEA__database__HOST: ${CORE_DB_HOST}:${CORE_DB_PORT}
GITEA__database__NAME: ${DEV_GITEA_DB_NAME}
GITEA__database__USER: ${DB_USER}
GITEA__database__PASSWD: ${DB_PASSWORD}
GITEA__server__DOMAIN: ${DEV_GITEA_TRAEFIK_HOST}
GITEA__server__SSH_DOMAIN: ${DEV_GITEA_TRAEFIK_HOST}
GITEA__server__ROOT_URL: https://${DEV_GITEA_TRAEFIK_HOST}/
GITEA__server__PROTOCOL: http
GITEA__server__HTTP_PORT: 3000
GITEA__server__START_SSH_SERVER: true
GITEA__server__SSH_PORT: 22
GITEA__server__SSH_LISTEN_PORT: 2222
GITEA__mailer__ENABLED: true
GITEA__mailer__PROTOCOL: smtp+starttls
GITEA__mailer__SMTP_ADDR: ${SMTP_HOST}
GITEA__mailer__SMTP_PORT: ${SMTP_PORT}
GITEA__mailer__USER: ${SMTP_USER}
GITEA__mailer__PASSWD: ${SMTP_PASSWORD}
GITEA__mailer__FROM: ${EMAIL_FROM}
GITEA__service__DISABLE_REGISTRATION: false
GITEA__service__REQUIRE_SIGNIN_VIEW: false
GITEA__packages__ENABLED: true
GITEA__actions__ENABLED: true
networks:
- compose_network
labels:
- 'traefik.enable=${DEV_TRAEFIK_ENABLED}'
# HTTP to HTTPS redirect
- 'traefik.http.middlewares.${DEV_COMPOSE_PROJECT_NAME}-gitea-redirect-web-secure.redirectscheme.scheme=https'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web.middlewares=${DEV_COMPOSE_PROJECT_NAME}-gitea-redirect-web-secure'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web.rule=Host(`${DEV_GITEA_TRAEFIK_HOST}`)'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web.entrypoints=web'
# HTTPS router
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure.rule=Host(`${DEV_GITEA_TRAEFIK_HOST}`)'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure.tls.certresolver=resolver'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure.entrypoints=web-secure'
- 'traefik.http.middlewares.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure-compress.compress=true'
- 'traefik.http.routers.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure.middlewares=${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure-compress,security-headers@file'
# Service
- 'traefik.http.services.${DEV_COMPOSE_PROJECT_NAME}-gitea-web-secure.loadbalancer.server.port=3000'
- 'traefik.docker.network=${NETWORK_NAME}'
# Watchtower
- 'com.centurylinklabs.watchtower.enable=${WATCHTOWER_LABEL_ENABLE}'
# Gitea Runner - Act runner for Gitea Actions
gitea_runner:
image: ${DEV_GITEA_RUNNER_IMAGE:-gitea/act_runner:latest}
container_name: ${DEV_COMPOSE_PROJECT_NAME}_gitea_runner
restart: unless-stopped
volumes:
- gitea_runner_data:/data
- /var/run/docker.sock:/var/run/docker.sock
environment:
TZ: ${TIMEZONE:-Europe/Berlin}
GITEA_INSTANCE_URL: https://${DEV_GITEA_TRAEFIK_HOST}
GITEA_RUNNER_REGISTRATION_TOKEN: ${DEV_GITEA_RUNNER_TOKEN}
GITEA_RUNNER_NAME: ${DEV_GITEA_RUNNER_NAME:-docker-runner}
GITEA_RUNNER_LABELS: ubuntu-latest:docker://node:20-bookworm,ubuntu-22.04:docker://node:20-bookworm,ubuntu-20.04:docker://node:18-buster
networks:
- compose_network
volumes:
gitea_data:
name: ${DEV_COMPOSE_PROJECT_NAME}_gitea_data
gitea_config:
name: ${DEV_COMPOSE_PROJECT_NAME}_gitea_config
gitea_runner_data:
name: ${DEV_COMPOSE_PROJECT_NAME}_gitea_runner_data
networks:
compose_network:
name: ${NETWORK_NAME}
external: true