name: gitea x-logging: &default-logging driver: json-file options: max-size: "10m" max-file: "3" services: nginx: image: ${NGINX_IMAGE:-nginx:1.27-alpine} container_name: ${NGINX_CONTAINER_NAME:-gitea-nginx} restart: ${GITEA_RESTART_POLICY:-unless-stopped} ports: - "${NGINX_HTTP_PORT:-80}:80" volumes: - ${NGINX_CONFIG_DIR:-./nginx}:/etc/nginx/conf.d:ro depends_on: gitea: condition: service_healthy networks: - frontend logging: *default-logging gitea: image: ${GITEA_IMAGE:-gitea/gitea:1.26} container_name: ${GITEA_CONTAINER_NAME:-gitea} restart: ${GITEA_RESTART_POLICY:-unless-stopped} environment: USER_UID: "${GITEA_UID:-1000}" USER_GID: "${GITEA_GID:-1000}" TZ: "${GITEA_TZ:-Europe/Rome}" # --- Database (MySQL) --- GITEA__database__DB_TYPE: mysql GITEA__database__HOST: "db:3306" GITEA__database__NAME: "${MYSQL_DATABASE:-gitea}" GITEA__database__USER: "${MYSQL_USER:-gitea}" GITEA__database__PASSWD: "${MYSQL_PASSWORD:?MYSQL_PASSWORD is not set - copy .env.example to .env and set it}" GITEA__database__SSL_MODE: "false" GITEA__database__CHARSET: "utf8mb4" # --- Server --- GITEA__server__DOMAIN: "${GITEA_DOMAIN}" GITEA__server__ROOT_URL: "${GITEA_ROOT_URL}" GITEA__server__PROTOCOL: "${GITEA_PROTOCOL:-http}" GITEA__server__HTTP_PORT: "3000" # git over SSH is served by the image's own OpenSSH daemon on container # port 22, so START_SSH_SERVER stays false - turning it on makes Gitea's # built-in server race sshd for port 22 and the container dies. # SSH_PORT is only what Gitea advertises in clone URLs (the host port). GITEA__server__SSH_DOMAIN: "${GITEA_SSH_DOMAIN}" GITEA__server__START_SSH_SERVER: "${GITEA_START_SSH_SERVER:-false}" GITEA__server__SSH_PORT: "${GITEA_SSH_PORT:-2222}" # --- Security / service --- GITEA__security__INSTALL_LOCK: "${GITEA_INSTALL_LOCK:-true}" GITEA__service__DISABLE_REGISTRATION: "${GITEA_DISABLE_REGISTRATION:-true}" GITEA__service__REQUIRE_SIGNIN_VIEW: "${GITEA_REQUIRE_SIGNIN_VIEW:-false}" volumes: - gitea-data:/data - gitea-config:/etc/gitea ports: - "${GITEA_SSH_PORT:-2222}:22" # git over SSH depends_on: db: condition: service_healthy networks: - frontend - backend healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://127.0.0.1:3000/api/healthz"] interval: 30s timeout: 5s retries: 5 start_period: 60s logging: *default-logging db: image: ${MYSQL_IMAGE:-mysql:8.4} container_name: ${MYSQL_CONTAINER_NAME:-gitea-db} restart: ${GITEA_RESTART_POLICY:-unless-stopped} command: - --character-set-server=utf8mb4 - --collation-server=utf8mb4_0900_as_cs - --innodb-buffer-pool-size=${MYSQL_INNODB_BUFFER_POOL_SIZE:-512M} - --max-connections=${MYSQL_MAX_CONNECTIONS:-200} environment: # No fixed root password is stored anywhere: the app user below is all # Gitea needs. The generated root password is printed once to the log. MYSQL_RANDOM_ROOT_PASSWORD: "yes" MYSQL_DATABASE: "${MYSQL_DATABASE:-gitea}" MYSQL_USER: "${MYSQL_USER:-gitea}" MYSQL_PASSWORD: "${MYSQL_PASSWORD:?MYSQL_PASSWORD is not set - copy .env.example to .env and set it}" TZ: "${GITEA_TZ:-Europe/Rome}" volumes: - gitea-db:/var/lib/mysql networks: - backend healthcheck: # Ping over TCP, not the socket: during init MySQL runs a temporary # socket-only server, so this cannot report ready too early. test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -u\"$$MYSQL_USER\" -p\"$$MYSQL_PASSWORD\" --silent"] interval: 10s timeout: 5s retries: 12 start_period: 60s logging: *default-logging networks: frontend: driver: bridge backend: driver: bridge internal: true # the database has no route to the internet volumes: gitea-db: gitea-data: gitea-config: