# Gitea with Let's Encrypt in a Docker Compose # Author # hey, I’m Vladimir Mikhalev, but my friends call me Valdemar. # My website with detailed IT guides: https://www.heyvaldemar.com/ # Follow me on YouTube: https://www.youtube.com/channel/UCf85kQ0u1sYTTTyKVpxrlyQ?sub_confirmation=1 # Follow me on Twitter: https://twitter.com/heyValdemar # Follow me on Instagram: https://www.instagram.com/heyvaldemar/ # Follow me on Facebook: https://www.facebook.com/heyValdemarFB/ # Follow me on TikTok: https://www.tiktok.com/@heyvaldemar # Follow me on LinkedIn: https://www.linkedin.com/in/heyvaldemar/ # Follow me on GitHub: https://github.com/heyvaldemar # Communication # Chat with IT pros on Discord: https://discord.gg/AJQGCCBcqf # Reach me at ask@sre.gg # Give Thanks # Support on GitHub: https://github.com/sponsors/heyValdemar # Support on Patreon: https://www.patreon.com/heyValdemar # Support on BuyMeaCoffee: https://www.buymeacoffee.com/heyValdemar # Support on Ko-fi: https://ko-fi.com/heyValdemar # Support on PayPal: https://www.paypal.com/paypalme/heyValdemarCOM # Install Docker Engine and Docker Compose by following my guide: https://www.heyvaldemar.com/install-docker-engine-and-docker-compose-on-ubuntu-server/ # Run gitea-restore-application-data.sh to restore application data if needed. # Run gitea-restore-database.sh to restore database if needed. # Deploy Gitea server with a Docker Compose using the command: # docker compose -f gitea-traefik-letsencrypt-docker-compose.yml -p gitea up -d volumes: gitea-data: gitea-config: gitea-postgres: gitea-data-backups: gitea-postgres-backups: traefik-certificates: services: postgres: # Image tag (replace with yours) image: postgres:14 volumes: - gitea-postgres:/var/lib/postgresql/data environment: # Database name (replace with yours) POSTGRES_DB: giteadb # Database user (replace with yours) POSTGRES_USER: giteadbuser # Database password (replace with yours) POSTGRES_PASSWORD: etFneCEtAWRKkfeQmkvwLWE healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -h 127.0.0.1"] interval: 10s timeout: 5s retries: 3 start_period: 60s restart: unless-stopped gitea: # Image tag (replace with yours) image: gitea/gitea:1.17 volumes: - gitea-data:/data - gitea-config:/etc/gitea - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro environment: DB_TYPE: postgres DB_HOST: postgres:5432 # Database name (replace with yours) DB_NAME: giteadb # Database user (replace with yours) DB_USER: giteadbuser # Database password (replace with yours) DB_PASSWD: etFneCEtAWRKkfeQmkvwLWE RUN_MODE: prod SSH_PORT: 0 DISABLE_SSH: 'true' HTTP_PORT: 3000 # Gitea URL (replace with yours) ROOT_URL: https://gitea.heyvaldemar.net healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/"] interval: 10s timeout: 5s retries: 3 start_period: 90s labels: - "traefik.enable=true" # Gitea URL (replace with yours) - "traefik.http.routers.gitea.rule=Host(`gitea.heyvaldemar.net`)" - "traefik.http.routers.gitea.service=gitea" - "traefik.http.routers.gitea.entrypoints=websecure" - "traefik.http.services.gitea.loadbalancer.server.port=3000" - "traefik.http.routers.gitea.tls=true" - "traefik.http.routers.gitea.tls.certresolver=letsencrypt" - "traefik.http.services.gitea.loadbalancer.passhostheader=true" - "traefik.http.routers.gitea.middlewares=compresstraefik" - "traefik.http.middlewares.compresstraefik.compress=true" restart: unless-stopped depends_on: postgres: condition: service_healthy traefik: condition: service_healthy traefik: # Image tag (replace with yours) image: traefik:2.8 command: - "--log.level=WARN" - "--accesslog=true" - "--api.dashboard=true" - "--api.insecure=true" - "--ping=true" - "--ping.entrypoint=ping" - "--entryPoints.ping.address=:8082" - "--entryPoints.web.address=:80" - "--entryPoints.websecure.address=:443" - "--providers.docker=true" - "--providers.docker.endpoint=unix:///var/run/docker.sock" - "--providers.docker.exposedByDefault=false" - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" # Email for Let's Encrypt (replace with yours) - "--certificatesresolvers.letsencrypt.acme.email=callvaldemar@gmail.com" - "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/acme/acme.json" - "--metrics.prometheus=true" - "--metrics.prometheus.buckets=0.1,0.3,1.2,5.0" - "--global.checkNewVersion=true" - "--global.sendAnonymousUsage=false" volumes: - /var/run/docker.sock:/var/run/docker.sock - traefik-certificates:/etc/traefik/acme ports: - "80:80" - "443:443" healthcheck: test: ["CMD", "wget", "http://localhost:8082/ping","--spider"] interval: 10s timeout: 5s retries: 3 start_period: 5s labels: - "traefik.enable=true" # Traefik URL (replace with yours) - "traefik.http.routers.dashboard.rule=Host(`traefik.gitea.heyvaldemar.net`)" - "traefik.http.routers.dashboard.service=api@internal" - "traefik.http.routers.dashboard.entrypoints=websecure" - "traefik.http.services.dashboard.loadbalancer.server.port=8080" - "traefik.http.routers.dashboard.tls=true" - "traefik.http.routers.dashboard.tls.certresolver=letsencrypt" - "traefik.http.services.dashboard.loadbalancer.passhostheader=true" - "traefik.http.routers.dashboard.middlewares=authtraefik" # Basic Authentication for Traefik Dashboard # Username: traefikadmin (replace with yours) # Passwords must be encoded using MD5, SHA1, or BCrypt https://hostingcanada.org/htpasswd-generator/ - "traefik.http.middlewares.authtraefik.basicauth.users=traefikadmin:$$2y$$10$$sMzJfirKC75x/hVpiINeZOiSm.Jkity9cn4KwNkRvO7hSQVFc5FLO" - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)" - "traefik.http.routers.http-catchall.entrypoints=web" - "traefik.http.routers.http-catchall.middlewares=redirect-to-https" - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https" restart: unless-stopped backups: # Image tag (replace with yours) image: postgres:14 # Database backups prune interval (replace with yours). Default is 7 days. # find /srv/gitea-postgres/backups -type f -mtime +7 | xargs rm -f # Application data backups prune interval (replace with yours). Default is 7 days. # find /srv/gitea-application-data/backups -type f -mtime +7 | xargs rm -f # Gitea backups interval (replace with yours). Default is 1 day. # sleep 24h # Run gitea-restore-application-data.sh to restore application data if needed. # Run gitea-restore-database.sh to restore database if needed. command: sh -c 'sleep 30m && while true; do PGPASSWORD="$$(echo $$POSTGRES_PASSWORD)" pg_dump -h postgres -p 5432 -d giteadb -U giteadbuser | gzip > /srv/gitea-postgres/backups/gitea-postgres-backup-$$(date "+%Y-%m-%d_%H-%M").gz && tar -zcpf /srv/gitea-application-data/backups/gitea-application-data-backup-$$(date "+%Y-%m-%d_%H-%M").tar.gz /etc/gitea && find /srv/gitea-postgres/backups -type f -mtime +7 | xargs rm -f && find /srv/gitea-application-data/backups -type f -mtime +7 | xargs rm -f; sleep 24h; done' volumes: - gitea-data:/etc/gitea # Application data backups location - gitea-data-backups:/srv/gitea-application-data/backups # Database backups location - gitea-postgres-backups:/srv/gitea-postgres/backups environment: # Database password (replace with yours) POSTGRES_PASSWORD: etFneCEtAWRKkfeQmkvwLWE restart: unless-stopped depends_on: postgres: condition: service_healthy gitea: condition: service_healthy