check / check (push) Failing after 1m40s
deploy/gitea/compose.yaml runs traefik, stock Gitea 1.27.3, rproxy and servewaf on one network with a fixed subnet. Its containers skip servewaf's checks; the network's gateway is left out of that range. rproxy takes uploads of 2 GiB and 30 minutes, and cuts responses at 15 minutes. script/gitea-setup (make gitea-setup) brings the setup up and checks it. docs/gitea.md is rewritten around the setup. Judgement call: the Core Rule Set runs in detect mode, so it refuses nothing. Judgement call: traefik serves its own certificate; no certificate resolver. Partially verified: the image build failed three runs on Ubuntu's snapshot service, so the checks ran only against a stand-in image with the same binary. Model: opus-5-5
121 lines
4.9 KiB
YAML
121 lines
4.9 KiB
YAML
# Gitea behind traefik, with rproxy and servewaf in front of it.
|
|
# docs/gitea.md says what each setting here does and why. Before starting it:
|
|
# - set SMALLWEBWAF_IMAGE to the smallwebwaf image, named by digest;
|
|
# - replace git.example.org with the site's host name;
|
|
# - replace each 10.99.0 with the first three numbers of a /24 subnet that
|
|
# no other network on the host uses.
|
|
# Then run `docker compose up --detach` in this directory.
|
|
# script/gitea-setup checks this setup.
|
|
|
|
name: gitea
|
|
|
|
x-logging: &logging
|
|
driver: json-file
|
|
options:
|
|
max-size: 10m
|
|
max-file: "5"
|
|
|
|
services:
|
|
traefik:
|
|
# traefik v3.7.17, 2026-11-03
|
|
image: traefik@sha256:68ae5fe5b64ca166704b746a9e8afcd385e36b3f569a5691401bf652d57b3748
|
|
# traefik replaces the X-Forwarded-For header a visitor sends. Keep it
|
|
# so: otherwise a visitor could name an address on the shared network,
|
|
# and skip servewaf's checks.
|
|
command:
|
|
- --providers.docker.exposedbydefault=false
|
|
- --entrypoints.web.address=:80
|
|
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
|
- --entrypoints.websecure.address=:443
|
|
# Until a certificate resolver is added here, as for your other
|
|
# sites, traefik answers with a certificate it made itself.
|
|
- --entrypoints.websecure.http.tls=true
|
|
# traefik's own limit of 60 seconds for a whole request would cut
|
|
# off an upload long before rproxy's limit of 30 minutes.
|
|
- --entrypoints.websecure.transport.respondingTimeouts.readTimeout=30m
|
|
ports:
|
|
- 80:80
|
|
- 443:443
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
shared:
|
|
# Containers on the shared network find traefik under the
|
|
# site's name, and so reach it from their own address.
|
|
aliases:
|
|
- git.example.org
|
|
restart: unless-stopped
|
|
|
|
gitea:
|
|
# gitea 1.27.3, 2026-08-29
|
|
image: gitea/gitea@sha256:87a67ee09d3ae0d1df5fda5dcda3e2a1f9236a45b0a59025d6e00e46adc43bef
|
|
environment:
|
|
GITEA__server__ROOT_URL: https://git.example.org/
|
|
# Gitea starts at its defaults, with SQLite, instead of showing its
|
|
# install page to whoever opens it first.
|
|
GITEA__security__INSTALL_LOCK: "true"
|
|
# rproxy's address. Gitea then takes each visitor's address from
|
|
# the X-Real-Ip header traefik sets and rproxy passes on.
|
|
GITEA__security__REVERSE_PROXY_TRUSTED_PROXIES: 10.99.0.2
|
|
volumes:
|
|
- gitea-data:/data
|
|
networks:
|
|
- shared
|
|
restart: unless-stopped
|
|
|
|
rproxy:
|
|
image: ${SMALLWEBWAF_IMAGE:?set SMALLWEBWAF_IMAGE to the smallwebwaf image}
|
|
environment:
|
|
SWRP_WAF_BACKEND: http://servewaf:8080
|
|
SWRP_UPSTREAM_URL: http://gitea:3000
|
|
# Pushes, LFS objects, packages and release attachments of up to
|
|
# 2 GiB, sent in up to 30 minutes.
|
|
SWRP_MAX_REQUEST_SIZE: 2G
|
|
SWRP_MAX_REQUEST_TIME_MS: "1800000"
|
|
# 15 minutes for a clone or a download, half the default.
|
|
SWRP_MAX_RESPONSE_TIME_MS: "900000"
|
|
labels:
|
|
traefik.enable: "true"
|
|
traefik.http.routers.gitea.rule: Host(`git.example.org`)
|
|
traefik.http.routers.gitea.entrypoints: websecure
|
|
traefik.http.services.gitea.loadbalancer.server.port: "8080"
|
|
networks:
|
|
shared:
|
|
ipv4_address: 10.99.0.2
|
|
logging: *logging
|
|
restart: unless-stopped
|
|
|
|
servewaf:
|
|
image: ${SMALLWEBWAF_IMAGE:?set SMALLWEBWAF_IMAGE to the smallwebwaf image}
|
|
environment:
|
|
SMALLWEBWAF_COMMAND: servewaf
|
|
# The containers on the shared network skip the checks. Add the
|
|
# address of an automation fleet on another host here too; without
|
|
# that, the default request limits are sized for such a fleet.
|
|
SWWAF_ALLOW_NETS: 10.99.0.128/25
|
|
# In block mode the Core Rule Set refuses everyday Gitea searches
|
|
# and file names, and 31 refusals in a minute ban the address.
|
|
SWWAF_WAF_MODE: detect
|
|
volumes:
|
|
- servewaf-state:/var/lib/smallwebwaf
|
|
networks:
|
|
- shared
|
|
logging: *logging
|
|
restart: unless-stopped
|
|
|
|
networks:
|
|
# The network traefik and Gitea share. Its containers get addresses in its
|
|
# upper half, which servewaf lets skip the checks. The gateway, the host's
|
|
# own address on it, stays out of that half: requests docker passes on from
|
|
# a published port, such as those of visitors over IPv6, can come from it.
|
|
shared:
|
|
ipam:
|
|
config:
|
|
- subnet: 10.99.0.0/24
|
|
ip_range: 10.99.0.128/25
|
|
gateway: 10.99.0.1
|
|
|
|
volumes:
|
|
gitea-data:
|
|
servewaf-state:
|