Set up Forgejo role and migrate Gitea to Forgejo 11

This commit is contained in:
Jef Roosens 2026-04-07 16:08:00 +02:00
parent 1c9721f0b2
commit 300358fa98
Signed by: Jef Roosens
GPG key ID: 21FD3D77D56BAF49
10 changed files with 319 additions and 19 deletions

View file

@ -102,51 +102,73 @@
path: "{{ btrfs_raid.path }}/webdav/data"
- name: Set up Gitea
- name: Set up Forgejo
hosts: emma
become: yes
tags: gitea
tags: forgejo
roles:
- role: any.common.btrfs-subvolumes
become: yes
vars:
subvolumes:
# Data files and LFS are placed on RAID
- filesystem_uuid: "{{ btrfs_raid.uuid }}"
filesystem_path: "{{ btrfs_raid.path }}"
name: "/gitea/data"
name: "/forgejo/data"
- filesystem_uuid: "{{ btrfs_raid.uuid }}"
filesystem_path: "{{ btrfs_raid.path }}"
name: "/gitea/lfs"
name: "/forgejo/lfs"
# Repositories and database are stored in NVME
- filesystem_uuid: "{{ btrfs_nvme.uuid }}"
filesystem_path: "{{ btrfs_nvme.path }}"
name: "/@rootfs/data/gitea/repositories"
name: "/@rootfs/data/forgejo/repositories"
- filesystem_uuid: "{{ btrfs_nvme.uuid }}"
filesystem_path: "{{ btrfs_nvme.path }}"
name: "/@rootfs/data/gitea/postgres"
name: "/@rootfs/data/forgejo/postgres"
- role: any.software.gitea
- role: any.software.forgejo-podman
vars:
gitea_data_dir: "{{ btrfs_raid.path }}/gitea/data"
gitea_lfs_dir: "{{ btrfs_raid.path }}/gitea/lfs"
gitea_repositories_dir: "{{ btrfs_nvme.path }}/data/gitea/repositories"
postgres_data_dir: "{{ btrfs_nvme.path }}/data/gitea/postgres"
# General
forgejo_version: '11.0.11'
forgejo_postgres_version: '14.8'
# Networking
forgejo_http_port: 8027
forgejo_ssh_port: 8016
forgejo_domain: 'git.rustybever.be'
forgejo_root_url: 'https://git.rustybever.be/'
# Secrets
forgejo_lfs_jwt_secret: "{{ vault_gitea_lfs_jwt_secret }}"
forgejo_secret_key: "{{ vault_gitea_secret_key }}"
forgejo_internal_token: "{{ vault_gitea_internal_token }}"
forgejo_jwt_secret: "{{ vault_gitea_jwt_secret }}"
# Data
forgejo_data_dir: "{{ btrfs_raid.path }}/forgejo/data"
forgejo_repositories_dir: "{{ btrfs_nvme.path }}/data/forgejo/repositories"
forgejo_lfs_dir: "{{ btrfs_raid.path }}/forgejo/lfs"
forgejo_postgres_dir: "{{ btrfs_nvme.path }}/data/forgejo/postgres"
- role: any.tools.backup-scripts
become: true
vars:
backups:
# TODO: gitea-data, gitea-lfs
- name: "gitea-postgres"
- name: "forgejo-postgres"
type: "podman-postgres"
user: "debian"
container: "systemd-gitea-postgres"
pg_user: "gitea"
database: "gitea"
- name: "gitea-repositories"
container: "systemd-forgejo-postgres"
pg_user: "forgejo"
database: "forgejo"
- name: "forgejo-repositories"
type: "btrfs-subvolume"
path: "/data/gitea/repositories"
path: "/data/forgejo/repositories"
- name: "forgejo-data"
type: "btrfs-subvolume"
path: "{{ btrfs_raid.path }}/forgejo/data"
- name: "forgejo-lfs"
type: "btrfs-subvolume"
path: "{{ btrfs_raid.path }}/forgejo/lfs"
- name: Set up Otter
hosts: emma

View file

@ -0,0 +1,27 @@
# `any.software.forgejo-podman`
## Description
Role that installs Forgejo along with a Postgresql database in Podman.
## Configuration
* General
* `forgejo_version`: version of Forgejo to install
* `forgejo_postgres_version`: version of PostgreSQL to install
* Networking
* `forgejo_ssh_port`: port to expose the SSH port to; will skip publishing port if omitted
* `forgejo_http_port`: port to expose the HTTP server to; will skip publishing port if omitted
* `forgejo_domain`: domain the server will be running on
* `forgejo_ssh_domain`: SSH domain setting, defaults to `forgejo_domain`
* `forgejo_root_url`: root URL setting
* Secrets
* `forgejo_lfs_jwt_secret`: the LFS JWT secret
* `forgejo_secret_key`: the `SECRET_KEY` variable
* `forgejo_internal_token`: the `INTERNAL_TOKEN` variable
* `forgejo_jwt_secret`: the JWT secret used for OAuth2
* Data
* `forgejo_data_dir`: the directory regular data is stored in
* `forgejo_repositories_dir`: directory all repositories are stored in
* `forgejo_lfs_dir`: directory LFS objects are stored in
* `forgejo_postgres_dir`: data directory for the PostgreSQL database

View file

@ -0,0 +1,16 @@
---
- name: 'restart forgejo-app'
ansible.builtin.service:
name: 'forgejo-app'
state: 'restarted'
scope: user
daemon_reload: true
- name: 'restart forgejo-postgres'
ansible.builtin.service:
name: 'forgejo-postgres'
state: 'restarted'
scope: user
daemon_reload: true

View file

@ -0,0 +1,4 @@
---
dependencies:
- role: any.tools.caddy
become: true

View file

@ -0,0 +1,55 @@
---
- name: Ensure configuration file is present
become: true
ansible.builtin.template:
src: "app.ini.j2"
dest: "{{ forgejo_data_dir }}/gitea/conf/app.ini"
mode: '0644'
owner: 'debian'
group: 'debian'
notify: 'restart forgejo-app'
- name: Ensure forgejo.pod is present
ansible.builtin.template:
src: "forgejo.pod.j2"
dest: "/home/debian/.config/containers/systemd/forgejo.pod"
mode: '0755'
owner: 'debian'
group: 'debian'
notify: 'restart forgejo-app'
- name: Ensure forgejo-app.container is present
ansible.builtin.template:
src: "forgejo-app.container.j2"
dest: "/home/debian/.config/containers/systemd/forgejo-app.container"
mode: '0755'
owner: 'debian'
group: 'debian'
notify: 'restart forgejo-app'
- name: Ensure forgejo-postgres.container is present
ansible.builtin.template:
src: "forgejo-postgres.container.j2"
dest: "/home/debian/.config/containers/systemd/forgejo-postgres.container"
mode: '0755'
owner: 'debian'
group: 'debian'
notify: 'restart forgejo-postgres'
- name: Ensure Caddyfile is present
become: true
ansible.builtin.template:
src: 'forgejo.Caddyfile.j2'
dest: '/etc/caddy/forgejo.Caddyfile'
owner: root
group: root
mode: '0644'
notify: reload caddy
when: 'forgejo_domain is defined'
- name: Allow Forgejo SSH connections
become: true
community.general.ufw:
port: "{{ forgejo_ssh_port }}"
rule: 'allow'
when: 'forgejo_ssh_port is defined'

View file

@ -0,0 +1,126 @@
APP_NAME = The Rusty Bever
RUN_MODE = prod
RUN_USER = git
WORK_PATH = /data/gitea
[repository]
ROOT = /data/git/repositories
; Makes public the default option when creating a repo
DEFAULT_PRIVATE = public
; Disables releases, projects & wiki by default for new repos (but can be enabled when needed)
DEFAULT_REPO_UNITS = repo.code,repo.issues,repo.pulls
; Might as well be compatible with
DEFAULT_BRANCH = main
[repository.pull-request]
WORK_IN_PROGRESS_PREFIXES = WIP:,[WIP]:,Draft:,[Draft]:
[repository.local]
LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
[repository.upload]
TEMP_PATH = /data/gitea/uploads
[ui]
; Always show the full name of a user when possible
DEFAULT_SHOW_FULL_NAME = true
THEMES = auto,gitea,arc-green,gitea-modern
[server]
APP_DATA_PATH = /data/gitea
DOMAIN = {{ forgejo_domain }}
SSH_DOMAIN = {{ forgejo_ssh_domain | default(forgejo_domain) }}
HTTP_PORT = 3000
ROOT_URL = {{ forgejo_root_url }}
DISABLE_SSH = false
SSH_PORT = 22
SSH_LISTEN_PORT = 22
LFS_START_SERVER = true
OFFLINE_MODE = false
LFS_JWT_SECRET = {{ forgejo_lfs_jwt_secret }}
[lfs]
PATH = /data/git/lfs
[database]
PATH = /data/gitea/gitea.db
DB_TYPE = postgres
HOST = localhost:5432
NAME = gitea
USER = gitea
PASSWD = gitea
LOG_SQL = false
SCHEMA =
SSL_MODE = disable
CHARSET = utf8
[indexer]
ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
[session]
PROVIDER_CONFIG = /data/gitea/sessions
PROVIDER = file
[picture]
AVATAR_UPLOAD_PATH = /data/gitea/avatars
REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
DISABLE_GRAVATAR = false
ENABLE_FEDERATED_AVATAR = true
[attachment]
PATH = /data/gitea/attachments
[log]
MODE = console
LEVEL = info
REDIRECT_MACARON_LOG = true
MACARON = console
ROOT_PATH = /data/gitea/log
; disable router logs
logger.router.MODE =
[log.console]
MODE = console
FLAGS = journaldflags
COLORIZE = false
[security]
INSTALL_LOCK = true
MIN_PASSWORD_LENGTH = 12
PASSWORD_COMPLEXITY = lower,upper,digit
SECRET_KEY = {{ forgejo_secret_key }}
INTERNAL_TOKEN = {{ forgejo_internal_token }}
[service]
DISABLE_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = false
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
ALLOW_ONLY_EXTERNAL_REGISTRATION = false
ENABLE_CAPTCHA = false
DEFAULT_KEEP_EMAIL_PRIVATE = false
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
DEFAULT_ENABLE_TIMETRACKING = true
NO_REPLY_ADDRESS = noreply.localhost
[mailer]
ENABLED = false
[openid]
ENABLE_OPENID_SIGNIN = true
ENABLE_OPENID_SIGNUP = false
[oauth2]
JWT_SECRET = {{ forgejo_jwt_secret }}
[other]
SHOW_FOOTER_VERSION = false
SHOW_FOOTER_TEMPLATE_LOAD_TIME = false
[cron.delete_repo_archives]
ENABLED = true
SCHEDULE = @weekly
[metrics]
enabled = true

View file

@ -0,0 +1,19 @@
# vim: ft=systemd
[Unit]
Requires=forgejo-postgres.service
After=forgejo-postgres.service
[Container]
Image=codeberg.org/forgejo/forgejo:{{ forgejo_version }}
Pod=forgejo.pod
Volume={{ forgejo_data_dir }}:/data
Volume={{ forgejo_repositories_dir }}:/data/git/repositories
Volume={{ forgejo_lfs_dir }}:/data/git/lfs
Volume=/etc/localtime:/etc/localtime:ro
[Service]
Restart=always
[Install]
WantedBy=default.target

View file

@ -0,0 +1,18 @@
# vim: ft=systemd
[Container]
Image=docker.io/postgres:{{ forgejo_postgres_version }}-alpine
Pod=forgejo.pod
Environment=POSTGRES_USER=gitea POSTGRES_PASSWORD=gitea POSTGRES_DB=gitea
HealthCmd=["pg_isready","-U","gitea"]
HealthInterval=30s
HealthRetries=3
HealthStartPeriod=30s
HealthTimeout=5s
Notify=Healthy
Volume={{ forgejo_postgres_dir }}:/var/lib/postgresql/data
[Service]
Restart=always

View file

@ -0,0 +1,5 @@
{{ forgejo_domain }} {
reverse_proxy localhost:{{ forgejo_http_port }} {
header_down +X-Robots-Tag "none"
}
}

View file

@ -0,0 +1,8 @@
# vim: ft=systemd
[Pod]
{% if forgejo_ssh_port is defined %}
PublishPort={{ forgejo_ssh_port }}:22
{% endif %}
{% if forgejo_http_port is defined %}
PublishPort={{ forgejo_http_port }}:3000
{% endif %}