Ansible role for deploying forgejo git server
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-11 09:57:31 +00:00
.forgejo/workflows feat: moved to forgejo runner 2026-10-11 16:56:36 +07:00
defaults feat: initial commit 2026-10-11 16:45:44 +07:00
meta feat: initial commit 2026-10-11 16:45:44 +07:00
tasks feat: initial commit 2026-10-11 16:45:44 +07:00
templates feat: initial commit 2026-10-11 16:45:44 +07:00
.gitignore feat: initial commit 2026-10-11 16:45:44 +07:00
CHANGELOG.md feat: initial commit 2026-10-11 16:45:44 +07:00
LICENSE feat: initial commit 2026-10-11 16:45:44 +07:00
README.md Prettified Code! 2026-10-11 09:57:31 +00:00

Forgejo

Deploys a Forgejo instance with PostgreSQL via Docker Compose, routed through Traefik as a reverse proxy. Follows the Docker installation guide (root image, built-in OpenSSH, FORGEJO__section__KEY configuration).

Requirements

  • Docker
  • community.docker Ansible collection

Variables

Variable Default Description
forgejo_instance forgejo Unique instance name. Compose project name and container name prefix.
forgejo_data_path /data/forgejo Host path for persistent data: forgejo/ (repositories, app.ini, owned by forgejo_uid) and db/ (PostgreSQL).
forgejo_docker_path /docker/forgejo Host path for the compose.yml file.
forgejo_version 16 Image tag of codeberg.org/forgejo/forgejo. 16 follows the latest 16.x release. Major upgrades need the manual steps of the release notes.
forgejo_db_version 17-alpine Image tag of postgres.
forgejo_uid / forgejo_gid 1000 UID/GID of the git user in the container (USER_UID/USER_GID).
forgejo_domain ~ Required. Public domain, no protocol. Traefik Host() rule, ROOT_URL and SSH clone domain.
forgejo_port ~ When set, exposes the web UI on 127.0.0.1:<port>.
forgejo_traefik true Attaches to traefik_web and adds HTTP routing labels.
forgejo_traefik_certresolver default Traefik certificate resolver for forgejo_domain.
forgejo_ssh_port ~ Host port SSH (container port 22) is published on. Unset disables SSH. See SSH.
forgejo_ssh_public_port forgejo_ssh_port or 22 Port shown in SSH clone URLs.
forgejo_extra_hosts {} Extra /etc/hosts entries (hostname: IP), e.g. to reach Keycloak on a host without NAT hairpin.
forgejo_db_pass ~ Required. PostgreSQL password.
forgejo_secret_key ~ Required. SECRET_KEY, encrypts 2FA and OIDC client secrets in the database. Never change it after the first run.
forgejo_admin ~ Dict username, password, email. Created once if the user doesn't exist. admin is a reserved name.
forgejo_disable_registration true Blocks local self-registration. With OIDC providers set, accounts can still be created through OIDC (ALLOW_ONLY_EXTERNAL_REGISTRATION).
forgejo_require_signin_view false Anonymous visitors must log in to see anything.
forgejo_mail_conf ~ SMTP dict: host, username, password, optional port (587), address, from_name (Forgejo), protocol (smtp+starttls/smtps/smtp).
forgejo_oidc_providers [] OIDC authentication sources. See SSO.
forgejo_oauth2_client see defaults auto_registration, username (userid/nickname/email), account_linking (disabled/login/auto) of [oauth2_client].
forgejo_runners [] Actions runners to register: name, secret (40 hex), optional scope ("" = instance, <owner>, <owner>/<repo>). See the forgejo_runner role. Also runs alone with tasks_from: runners.
forgejo_extra_env {} Further app.ini settings as FORGEJO__<section>__<KEY>: value.
forgejo_uninstall false Stops and removes containers and the compose directory.
forgejo_purge false Also removes the data directory. Requires forgejo_uninstall: true. Irreversible.

Usage

forgejo_domain: git.example.com
forgejo_db_pass: "{{ vault_forgejo_db_pass }}"
forgejo_secret_key: "{{ vault_forgejo_secret_key }}"
forgejo_ssh_port: 222
forgejo_admin:
  username: forgejo-admin
  password: "{{ vault_forgejo_admin_pass }}"
  email: it@example.com

SSH

forgejo_ssh_port publishes container port 22 (Forgejo's built-in OpenSSH) directly on the host, e.g. 222. SSH carries no hostname (no SNI), so it isn't routed through Traefik.

The public SSH port also has to be forwarded by whatever sits in front of the host (firewall/HAProxy, TCP mode).

SSO

Each entry of forgejo_oidc_providers becomes an OAuth2/OpenID Connect authentication source, so several Keycloak instances or realms can be offered side by side.

Key Required Default Description
name yes — Source name, [A-Za-z0-9_-]. Login button label and part of the callback URL.
discovery_url yes — e.g. https://auth.example.com/realms/<realm>/.well-known/openid-configuration.
client_id yes — OIDC client ID.
client_secret yes — OIDC client secret.
scopes no [email, profile] Scopes in addition to openid.
icon_url no unset Icon on the login button.
group_claim_name no unset Claim holding the user's groups, needed for admin_group/restricted_group.
admin_group no unset Members of this group become site admins.
restricted_group no unset Members of this group become restricted users.
skip_local_2fa no false Skip Forgejo's own 2FA for logins through this source.

Redirect URI to register on the Keycloak client: https://<forgejo_domain>/user/oauth2/<name>/callback.

forgejo_extra_hosts:
  auth.example.com: 10.0.0.2
forgejo_oidc_providers:
  - name: tni
    discovery_url: https://auth.example.com/realms/tni/.well-known/openid-configuration
    client_id: forgejo
    client_secret: "{{ vault_forgejo_tni_secret }}"
    group_claim_name: groups
    admin_group: forgejo-admins
  - name: evoxa
    discovery_url: https://auth.example.com/realms/evoxa/.well-known/openid-configuration
    client_id: forgejo
    client_secret: "{{ vault_forgejo_evoxa_secret }}"

Sources are matched by name: new ones are created, existing ones are updated on every run (reported as ok, the CLI can't tell whether anything changed). Removing an entry does not delete the source in Forgejo, do that in Site Administration. Forgejo fetches the discovery URL when a source is saved, so an unreachable Keycloak fails the run.

Notes

  • The web installer is skipped (INSTALL_LOCK), all settings come from environment variables written into app.ini on start. Environment variables can't remove values from app.ini, edit it by hand for that.
  • forgejo_data_path/forgejo is owned by forgejo_uid:forgejo_gid, forgejo_data_path/db by 70:70 (postgres alpine), mode 0700.
  • The rendered compose.yml is mode 0600 since it contains secrets. Store all secrets in Ansible Vault.