Initial commit
Some checks failed
/ ansible-docsmith (push) Failing after 17s

Signed-off-by: Julien Riou <julien@riou.xyz>
This commit is contained in:
Julien Riou 2026-02-16 08:50:48 +01:00
commit c4388611eb
Signed by: jriou
GPG key ID: 9A099EDA51316854
47 changed files with 1674 additions and 2 deletions

View file

@ -0,0 +1,35 @@
---
on:
- push
jobs:
ansible-docsmith:
runs-on: node-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install ansible-docsmith
run: |
apt-get update
apt-get install -y python3-pip
pip install ansible-docsmith --break-system-packages
- name: Run ansible-docsmith
run: ansible-docsmith generate .
- name: Verify changes
run: |
set -e
git diff > diff.txt
CHANGES=$(wc -l diff.txt | awk '{ print $1 }')
echo "Number of changes: ${CHANGES}"
if [ ${CHANGES} -gt 0 ] ; then
echo ""
cat diff.txt
echo ""
echo "Fix with the following command:"
echo ""
echo "run ansible-docsmith generate ${role_dir}"
exit 1
fi

View file

@ -1,3 +1,3 @@
# ansible
# Ansible
My Ansible collection
My Ansible collection.

View file

@ -0,0 +1,17 @@
---
- name: Check requirements
ansible.builtin.assert:
that:
- certbot_email is defined
- certbot_domain is defined
- name: Install packages
ansible.builtin.package:
name: certbot
- name: Request certificate
ansible.builtin.command:
cmd: >-
certbot certonly --standalone -n --agree-tos
--email {{ certbot_email }} -d {{ certbot_domain }}
creates: /etc/letsencrypt/live/{{ certbot_domain }}/fullchain.pem

43
roles/coller/README.md Normal file
View file

@ -0,0 +1,43 @@
# ansible-role-coller
Ansible role to manage a [coller](https://git.riou.xyz/jriou/coller) instance.
## Installation
Clone the repository in your local Ansible roles directory:
```
git clone https://git.riou.xyz/jriou/ansible-role-coller.git ~/.ansible/roles/coller
```
See [Storing and finding
roles](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_reuse_roles.html#storing-and-finding-roles).
## Configuration
See [Variable
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
to find where you should put your own variables.
Then define at least `coller_db_password` with a strong and secure password,
encrypted using
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
See list of [default variables](defaults/main.yml).
## Usage
Example of a basic coller.yml playbook:
```yaml
- hosts: coller
roles:
- coller
```
Then run the playbook:
```
ansible-playbook coller.yml
```

View file

@ -0,0 +1,9 @@
---
coller_version: 1.3.1
coller_config_dir: /etc/coller
coller_port: 8080
coller_manage_iptables: false
coller_allowed_sources: []
coller_db_name: coller
coller_db_user: coller
#coller_db_password:

View file

@ -0,0 +1,4 @@
---
- name: save iptables
ansible.builtin.shell:
cmd: netfilter-persistent save

View file

@ -0,0 +1,3 @@
---
dependencies:
- role: geerlingguy.docker

View file

@ -0,0 +1,55 @@
---
- name: check password
ansible.builtin.assert:
that:
- coller_db_password is defined
- name: download source code
ansible.builtin.git:
repo: https://git.riou.xyz/jriou/coller.git
dest: /opt/coller
version: "{{ coller_version }}"
- name: create directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0755"
loop:
- "{{ coller_config_dir }}"
- name: create docker-compose files
ansible.builtin.template:
src: "{{ item.src }}.j2"
dest: "{{ coller_config_dir }}/{{ item.src }}"
owner: root
group: root
mode: "{{ item.mode }}"
loop:
- src: docker-compose.yml
mode: "0644"
- src: db.env
mode: "0600"
- name: create configuration file
ansible.builtin.copy:
content:
database_type: postgres
database_dsn: "host=db dbname={{ coller_db_name }} user={{ coller_db_user }} password={{ coller_db_password }}"
dest: "{{ coller_config_dir }}/collerd.json"
owner: root
group: root
mode: "0640"
no_log: true
- name: start service
community.docker.docker_compose_v2:
project_src: "{{ coller_config_dir }}"
files:
- docker-compose.yml
- name: manage iptables
when: coller_manage_iptables
ansible.builtin.include_tasks: manage-iptables.yml

View file

@ -0,0 +1,16 @@
---
- name: install packages
ansible.builtin.package:
name: netfilter-persistent
- name: allow with iptables
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
source: "{{ item }}"
destination_ports:
- "{{ coller_port }}"
jump: ACCEPT
comment: coller
loop: "{{ coller_allowed_sources }}"
notify: save iptables

View file

@ -0,0 +1,6 @@
{{ ansible_managed | comment }}
POSTGRES_USER={{ coller_db_user }}
POSTGRES_PASSWORD={{ coller_db_password }}
POSTGRES_DB={{ coller_db_name }}
POSTGRES_INITDB_ARGS="--data-checksums"
POSTGRES_HOST_AUTH_METHOD=scram-sha-256

View file

@ -0,0 +1,32 @@
---
{{ ansible_managed | comment }}
services:
server:
image: coller:{{ coller_version }}
build: /opt/coller
container_name: collerd
restart: always
networks:
- coller
ports:
- "{{ coller_port }}:8080"
volumes:
- "{{ coller_config_dir }}/collerd.json:/etc/collerd.json:ro"
command: collerd -config /etc/collerd.json
db:
image: postgres:17
hostname: db
container_name: collerd_db
restart: always
env_file: {{ coller_config_dir }}/db.env
networks:
- coller
volumes:
- coller:/var/lib/postgresql/data
networks:
coller:
volumes:
coller:

39
roles/firefly/README.md Normal file
View file

@ -0,0 +1,39 @@
# Ansible Role Firefly
Ansible role to manage a [Firefly III](https://firefly-iii.org/) instance.
## Configuration
See [Variable
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
to find where you should put your own variables.
Then define at least `firefly_static_cron_token`, `firefly_db_password` and
`firefly_app_key` variables with a strong and secure password, encrypted using
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
See list of [default variables](defaults/main.yml).
## Usage
Example of a basic firefly.yml playbook:
```yaml
hosts:
- firefly
roles:
- firefly
```
Then run the playbook:
```
ansible-playbook firefly.yml
```
## Donate
As we all love FOSS projects, you should consider [sponsoring and/or
contribute](https://github.com/firefly-iii/firefly-iii).

View file

@ -0,0 +1,14 @@
---
firefly_version: latest
firefly_port: 8080
firefly_static_cron_token: CHANGEME
firefly_home: /var/lib/firefly
firefly_site_owner: root@localhost
firefly_app_key: CHANGEME
firefly_language: en_US
firefly_tz: Etc/UTC
firefly_db_database: firefly
firefly_db_username: firefly
firefly_db_password: CHANGEME
firefly_manage_iptables: false
firefly_allowed_sources: []

View file

@ -0,0 +1,4 @@
---
- name: save iptables
ansible.builtin.shell:
cmd: netfilter-persistent save

View file

@ -0,0 +1,3 @@
---
dependencies:
- role: geerlingguy.docker

View file

@ -0,0 +1,40 @@
---
- name: install dependencies
ansible.builtin.apt:
name:
- python3-docker
- python3-compose
- name: create directories
ansible.builtin.file:
path: /etc/firefly
state: directory
- name: create configuration files
ansible.builtin.template:
src: "{{ item }}.j2"
dest: "/etc/firefly/{{ item }}"
mode: "0600"
loop:
- docker-compose.yml
- db.env
- app.env
- name: start service
community.docker.docker_compose_v2:
project_src: /etc/firefly
files:
- docker-compose.yml
- name: allow with iptables
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
source: "{{ item }}"
destination_ports:
- "{{ firefly_port }}"
jump: ACCEPT
comment: firefly
loop: "{{ firefly_allowed_sources }}"
notify: save iptables
when: firefly_manage_iptables

View file

@ -0,0 +1,132 @@
APP_ENV=local
APP_DEBUG=false
SITE_OWNER={{ firefly_site_owner }}
APP_KEY={{ firefly_app_key }}
DEFAULT_LANGUAGE={{ firefly_language }}
DEFAULT_LOCALE=equal
TZ={{ firefly_tz }}
TRUSTED_PROXIES=*
LOG_CHANNEL=stack
APP_LOG_LEVEL=notice
AUDIT_LOG_LEVEL=emergency
AUDIT_LOG_CHANNEL=
PAPERTRAIL_HOST=
PAPERTRAIL_PORT=
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
# For other database types, please see the FAQ: https://docs.firefly-iii.org/firefly-iii/faq/self-hosted/#i-want-to-use-sqlite
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
# Use "pgsql" for PostgreSQL
# Use "mysql" for MySQL and MariaDB.
# Use "sqlite" for SQLite.
DB_CONNECTION=pgsql
DB_HOST=db
DB_PORT=5432
DB_DATABASE={{ firefly_db_database }}
DB_USERNAME={{ firefly_db_username }}
DB_PASSWORD={{ firefly_db_password }}
DB_SOCKET=
PGSQL_SSL_MODE=prefer
PGSQL_SCHEMA=public
CACHE_DRIVER=file
SESSION_DRIVER=file
REDIS_SCHEME=tcp
REDIS_PATH=
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_USERNAME=firefly
REDIS_PASSWORD=
REDIS_DB="0"
REDIS_CACHE_DB="1"
COOKIE_PATH="/"
COOKIE_DOMAIN=
COOKIE_SECURE=false
COOKIE_SAMESITE=lax
MAIL_MAILER=log
MAIL_HOST=null
MAIL_PORT=2525
MAIL_FROM=changeme@example.com
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_SENDMAIL_COMMAND=
MAILGUN_DOMAIN=
MAILGUN_SECRET=
MAILGUN_ENDPOINT=api.mailgun.net
MANDRILL_SECRET=
SPARKPOST_SECRET=
SEND_ERROR_MESSAGE=true
SEND_REPORT_JOURNALS=true
ENABLE_EXTERNAL_MAP=false
ENABLE_EXTERNAL_RATES=false
MAP_DEFAULT_LAT=51.983333
MAP_DEFAULT_LONG=5.916667
MAP_DEFAULT_ZOOM=6
VALID_URL_PROTOCOLS=
AUTHENTICATION_GUARD=web
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
AUTHENTICATION_GUARD_EMAIL=
PASSPORT_PRIVATE_KEY=
PASSPORT_PUBLIC_KEY=
CUSTOM_LOGOUT_URL=
DISABLE_FRAME_HEADER=false
DISABLE_CSP_HEADER=false
TRACKER_SITE_ID=
TRACKER_URL=
ALLOW_WEBHOOKS=false
STATIC_CRON_TOKEN={{ firefly_static_cron_token }}
DKR_BUILD_LOCALE=false
DKR_CHECK_SQLITE=true
DKR_RUN_MIGRATION=true
DKR_RUN_UPGRADE=true
DKR_RUN_VERIFY=true
DKR_RUN_REPORT=true
DKR_RUN_PASSPORT_INSTALL=true
APP_NAME=FireflyIII
BROADCAST_DRIVER=log
QUEUE_DRIVER=sync
CACHE_PREFIX=firefly
PUSHER_KEY=
IPINFO_TOKEN=
PUSHER_SECRET=
PUSHER_ID=
DEMO_USERNAME=
DEMO_PASSWORD=
FIREFLY_III_LAYOUT=v1
#
# If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable.
# It won't work. It doesn't do ANYTHING. Don't believe the lies you read online. I'm not joking.
# This configuration value WILL NOT HELP.
#
# Notable exception to this rule is Synology, which, according to some users, will use APP_URL to rewrite stuff.
#
# This variable is ONLY used in some of the emails Firefly III sends around. Nowhere else.
# So when configuring anything WEB related this variable doesn't do anything. Nothing
#
# If you're stuck I understand you get desperate but look SOMEWHERE ELSE.
#
APP_URL=http://localhost

View file

@ -0,0 +1,5 @@
POSTGRES_USER={{ firefly_db_username }}
POSTGRES_PASSWORD={{ firefly_db_password }}
POSTGRES_DB={{ firefly_db_database }}
POSTGRES_INITDB_ARGS="--data-checksums"
POSTGRES_HOST_AUTH_METHOD=scram-sha-256

View file

@ -0,0 +1,40 @@
---
{{ ansible_managed | comment }}
services:
app:
image: fireflyiii/core:{{ firefly_version }}
hostname: app
container_name: firefly_iii_core
restart: always
volumes:
- {{ firefly_home }}/app/upload:/var/www/html/storage/upload
env_file: /etc/firefly/app.env
networks:
- firefly_iii
ports:
- {{ firefly_port }}:8080
depends_on:
- db
db:
image: postgres:17
hostname: db
container_name: firefly_iii_db
restart: always
env_file: /etc/firefly/db.env
networks:
- firefly_iii
volumes:
- {{ firefly_home }}/db/data:/var/lib/postgresql/data
- {{ firefly_home }}/db/backup:/var/lib/postgresql/backup
cron:
image: alpine
restart: always
container_name: firefly_iii_cron
command: sh -c "echo \"0 3 * * * wget -qO- http://app:8080/api/v1/cron/{{ firefly_static_cron_token }}\" | crontab - && crond -f -L /dev/stdout"
networks:
- firefly_iii
networks:
firefly_iii:
driver: bridge

321
roles/forgejo/README.md Normal file
View file

@ -0,0 +1,321 @@
# Ansible Role Forgejo
Ansible role to manage a [Forgejo](https://forgejo.org/) instance.
## Configuration
See [Variable
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
to find where you should put your own variables.
Then define at least `forgejo_db_password` with a strong and secure password,
encrypted using
[ansible-vault](https://docs.ansible.com/ansible/latest/cli/ansible-vault.html).
## Table of Content
<!-- ANSIBLE DOCSMITH TOC START -->
* [Role variables](#variables)
* [`forgejo_server`](#variable-forgejo_server)
* [`forgejo_version`](#variable-forgejo_version)
* [`forgejo_home_dir`](#variable-forgejo_home_dir)
* [`forgejo_config_dir`](#variable-forgejo_config_dir)
* [`forgejo_web_port`](#variable-forgejo_web_port)
* [`forgejo_ssh_port`](#variable-forgejo_ssh_port)
* [`forgejo_db_username`](#variable-forgejo_db_username)
* [`forgejo_db_password`](#variable-forgejo_db_password)
* [`forgejo_db_database`](#variable-forgejo_db_database)
* [`forgejo_mailer`](#variable-forgejo_mailer)
* [`forgejo_service`](#variable-forgejo_service)
* [`forgejo_manage_iptables`](#variable-forgejo_manage_iptables)
* [`forgejo_allowed_sources`](#variable-forgejo_allowed_sources)
* [`forgejo_runners_version`](#variable-forgejo_runners_version)
* [`forgejo_runners_config_dir`](#variable-forgejo_runners_config_dir)
* [`forgejo_runners_instance`](#variable-forgejo_runners_instance)
* [`forgejo_runners`](#variable-forgejo_runners)
<!-- ANSIBLE DOCSMITH TOC END -->
<!-- ANSIBLE DOCSMITH MAIN START -->
## Role variables<a id="variables"></a>
The following variables can be configured for this role:
| Variable | Type | Required | Default | Description (abstract) |
|----------|------|----------|---------|------------------------|
| `forgejo_server` | `bool` | No | `true` | Enable the server mode |
| `forgejo_version` | `int` | No | `14` | Version of the Forgejo binaries |
| `forgejo_home_dir` | `path` | No | `"/var/lib/forgejo"` | Path to the home directory |
| `forgejo_config_dir` | `path` | No | `"/etc/forgejo"` | Path to the configuration directory |
| `forgejo_web_port` | `int` | No | `3000` | Port to listen for the web UI |
| `forgejo_ssh_port` | `int` | No | `222` | Port to listen for SSH |
| `forgejo_db_username` | `str` | No | `"forgejo"` | Name of the user in the database |
| `forgejo_db_password` | `str` | Yes | N/A | Password of the user in the database |
| `forgejo_db_database` | `str` | No | `"forgejo"` | Name of the database |
| `forgejo_mailer` | `dict` | No | N/A | Configure the mailer to send e-mail notifications<br><br>Define a `enabled` key with a boolean to enable the mailer<br><br>Define a `from` key with the source e-mail address<br><br>See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/) |
| `forgejo_service` | `dict` | No | N/A | Configure service settings<br><br>See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service) |
| `forgejo_manage_iptables` | `bool` | No | `false` | Configure iptables rules |
| `forgejo_allowed_sources` | `list` | No | N/A | List of IP ranges to allow when `forgejo_manage_iptables` is enabled |
| `forgejo_runners_version` | `str` | No | `"9.1.1"` | Version of the runners |
| `forgejo_runners_config_dir` | `path` | No | `"/etc/forgejo-runners"` | Path to the configuration directory of the runners |
| `forgejo_runners_instance` | `str` | No | N/A | URL of the Forgejo instance to register the runners |
| `forgejo_runners` | `dict` | No | N/A | List of runners to configure<br><br>The key is the name of the repository on the instance<br><br>The value is a dict with a `token` key and optionally a dict of `labels` |
### `forgejo_server`<a id="variable-forgejo_server"></a>
[*⇑ Back to ToC ⇑*](#toc)
Enable the server mode
- **Type**: `bool`
- **Required**: No
- **Default**: `true`
### `forgejo_version`<a id="variable-forgejo_version"></a>
[*⇑ Back to ToC ⇑*](#toc)
Version of the Forgejo binaries
- **Type**: `int`
- **Required**: No
- **Default**: `14`
### `forgejo_home_dir`<a id="variable-forgejo_home_dir"></a>
[*⇑ Back to ToC ⇑*](#toc)
Path to the home directory
- **Type**: `path`
- **Required**: No
- **Default**: `"/var/lib/forgejo"`
### `forgejo_config_dir`<a id="variable-forgejo_config_dir"></a>
[*⇑ Back to ToC ⇑*](#toc)
Path to the configuration directory
- **Type**: `path`
- **Required**: No
- **Default**: `"/etc/forgejo"`
### `forgejo_web_port`<a id="variable-forgejo_web_port"></a>
[*⇑ Back to ToC ⇑*](#toc)
Port to listen for the web UI
- **Type**: `int`
- **Required**: No
- **Default**: `3000`
### `forgejo_ssh_port`<a id="variable-forgejo_ssh_port"></a>
[*⇑ Back to ToC ⇑*](#toc)
Port to listen for SSH
- **Type**: `int`
- **Required**: No
- **Default**: `222`
### `forgejo_db_username`<a id="variable-forgejo_db_username"></a>
[*⇑ Back to ToC ⇑*](#toc)
Name of the user in the database
- **Type**: `str`
- **Required**: No
- **Default**: `"forgejo"`
### `forgejo_db_password`<a id="variable-forgejo_db_password"></a>
[*⇑ Back to ToC ⇑*](#toc)
Password of the user in the database
- **Type**: `str`
- **Required**: Yes
### `forgejo_db_database`<a id="variable-forgejo_db_database"></a>
[*⇑ Back to ToC ⇑*](#toc)
Name of the database
- **Type**: `str`
- **Required**: No
- **Default**: `"forgejo"`
### `forgejo_mailer`<a id="variable-forgejo_mailer"></a>
[*⇑ Back to ToC ⇑*](#toc)
Configure the mailer to send e-mail notifications
Define a `enabled` key with a boolean to enable the mailer
Define a `from` key with the source e-mail address
See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/)
- **Type**: `dict`
- **Required**: No
### `forgejo_service`<a id="variable-forgejo_service"></a>
[*⇑ Back to ToC ⇑*](#toc)
Configure service settings
See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service)
- **Type**: `dict`
- **Required**: No
### `forgejo_manage_iptables`<a id="variable-forgejo_manage_iptables"></a>
[*⇑ Back to ToC ⇑*](#toc)
Configure iptables rules
- **Type**: `bool`
- **Required**: No
- **Default**: `false`
### `forgejo_allowed_sources`<a id="variable-forgejo_allowed_sources"></a>
[*⇑ Back to ToC ⇑*](#toc)
List of IP ranges to allow when `forgejo_manage_iptables` is enabled
- **Type**: `list`
- **Required**: No
### `forgejo_runners_version`<a id="variable-forgejo_runners_version"></a>
[*⇑ Back to ToC ⇑*](#toc)
Version of the runners
- **Type**: `str`
- **Required**: No
- **Default**: `"9.1.1"`
### `forgejo_runners_config_dir`<a id="variable-forgejo_runners_config_dir"></a>
[*⇑ Back to ToC ⇑*](#toc)
Path to the configuration directory of the runners
- **Type**: `path`
- **Required**: No
- **Default**: `"/etc/forgejo-runners"`
### `forgejo_runners_instance`<a id="variable-forgejo_runners_instance"></a>
[*⇑ Back to ToC ⇑*](#toc)
URL of the Forgejo instance to register the runners
- **Type**: `str`
- **Required**: No
### `forgejo_runners`<a id="variable-forgejo_runners"></a>
[*⇑ Back to ToC ⇑*](#toc)
List of runners to configure
The key is the name of the repository on the instance
The value is a dict with a `token` key and optionally a dict of `labels`
- **Type**: `dict`
- **Required**: No
<!-- ANSIBLE DOCSMITH MAIN END -->
## Usage
Example of a basic forgejo.yml playbook:
```yaml
- hosts: forgejo
roles:
- jriou.forgejo
```
Then run the playbook:
```
ansible-playbook forgejo.yml
```
## Runners
Example of runners configuration:
```yaml
- hosts: forgejo
roles:
- jriou.forgejo
vars:
forgejo_server: false
forgejo_runners_instance: https://codeberg.org # FIXME
forgejo_runners:
coller:
token: **redacted**
labels:
debian12: docker://data.forgejo.org/oci/debian:bookworm
debian13: docker://data.forgejo.org/oci/debian:trixie
ansible:
token: **redacted**
labels:
docker: docker://data.forgejo.org/oci/node:latest
```
## Donate
As we all love FOSS projects, you should consider [donating to
Codeberg](https://donate.codeberg.org/), the non-profit organization behind
Forgejo.

View file

@ -0,0 +1,120 @@
---
# Enable the server mode
#
# - Type: bool
# - Required: No
# - Default: true
forgejo_server: true
# Version of the Forgejo binaries
#
# - Type: int
# - Required: No
# - Default: 14
forgejo_version: 14
# Path to the home directory
#
# - Type: path
# - Required: No
# - Default: /var/lib/forgejo
forgejo_home_dir: /var/lib/forgejo
# Path to the configuration directory
#
# - Type: path
# - Required: No
# - Default: /etc/forgejo
forgejo_config_dir: /etc/forgejo
# Port to listen for the web UI
#
# - Type: int
# - Required: No
# - Default: 3000
forgejo_web_port: 3000
# Port to listen for SSH
#
# - Type: int
# - Required: No
# - Default: 222
forgejo_ssh_port: 222
# Name of the user in the database
#
# - Type: str
# - Required: No
# - Default: forgejo
forgejo_db_username: forgejo
# Password of the user in the database
#
# - Type: str
# - Required: Yes
forgejo_db_password: CHANGEME
# Name of the database
#
# - Type: str
# - Required: No
# - Default: forgejo
forgejo_db_database: forgejo
# Configure the mailer to send e-mail notifications
#
# Define a `enabled` key with a boolean to enable the mailer
#
# Define a `from` key with the source e-mail address
#
# See
#
# - Type: dict
# - Required: No
forgejo_mailer: {}
# Configure service settings
#
# See
#
# - Type: dict
# - Required: No
forgejo_service: {}
# Configure iptables rules
#
# - Type: bool
# - Required: No
# - Default: false
forgejo_manage_iptables: false
# List of IP ranges to allow when `forgejo_manage_iptables` is enabled
#
# - Type: list
# - Required: No
forgejo_allowed_sources: []
# Version of the runners
#
# - Type: str
# - Required: No
# - Default: 9.1.1
forgejo_runners_version: 9.1.1
# Path to the configuration directory of the runners
#
# - Type: path
# - Required: No
# - Default: /etc/forgejo-runners
forgejo_runners_config_dir: /etc/forgejo-runners
# List of runners to configure
#
# The key is the name of the repository on the instance
#
# The value is a dict with a `token` key and optionally a dict of `labels`
#
# - Type: dict
# - Required: No
forgejo_runners: {}

View file

@ -0,0 +1,17 @@
---
- name: save iptables
ansible.builtin.shell:
cmd: netfilter-persistent save
- name: start runners
community.docker.docker_compose_v2:
project_src: "{{ forgejo_runners_config_dir }}"
files:
- docker-compose.yml
- name: restart runners
community.docker.docker_compose_v2:
project_src: "{{ forgejo_runners_config_dir }}"
files:
- docker-compose.yml
state: restarted

View file

@ -0,0 +1,106 @@
---
argument_specs:
main:
short_description: Install and configure a Forgejo instance
description:
- Install and configure a [Forgejo](https://forgejo.org/) instance.
author:
- jriou
options:
forgejo_server:
description:
- Enable the server mode
type: bool
default: true
forgejo_version:
description:
- Version of the Forgejo binaries
type: int
default: 14
forgejo_home_dir:
description:
- Path to the home directory
type: path
default: /var/lib/forgejo
forgejo_config_dir:
description:
- Path to the configuration directory
type: path
default: /etc/forgejo
forgejo_web_port:
description:
- Port to listen for the web UI
type: int
default: 3000
forgejo_ssh_port:
description:
- Port to listen for SSH
type: int
default: 222
forgejo_db_username:
description:
- Name of the user in the database
default: forgejo
forgejo_db_password:
description:
- Password of the user in the database
required: true
forgejo_db_database:
description:
- Name of the database
default: forgejo
forgejo_mailer:
description:
- Configure the mailer to send e-mail notifications
- Define a `enabled` key with a boolean to enable the mailer
- Define a `from` key with the source e-mail address
- See [Email setup](https://forgejo.org/docs/latest/admin/setup/email/)
type: dict
forgejo_service:
description:
- Configure service settings
- See [Service](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#service-service)
type: dict
forgejo_manage_iptables:
description:
- Configure iptables rules
type: bool
default: false
forgejo_allowed_sources:
description:
- List of IP ranges to allow when `forgejo_manage_iptables` is enabled
type: list
forgejo_runners_version:
description:
- Version of the runners
default: 9.1.1
forgejo_runners_config_dir:
description:
- Path to the configuration directory of the runners
type: path
default: /etc/forgejo-runners
forgejo_runners_instance:
description:
- URL of the Forgejo instance to register the runners
forgejo_runners:
description:
- List of runners to configure
- The key is the name of the repository on the instance
- The value is a dict with a `token` key and optionally a dict of `labels`
type: dict

View file

@ -0,0 +1,18 @@
---
dependencies:
- role: geerlingguy.docker
galaxy_info:
role_name: jriou.forgejo
author: jriou
description: Ansible role to manage a Forgejo instance
license_file: LICENSE
min_ansible_version: 2.18
platforms:
- name: Debian
versions:
- bullseye
- bookworm
- trixie
galaxy_tags:
- forgejo

View file

@ -0,0 +1,20 @@
---
- name: register runners
ansible.builtin.include_tasks: register-runner.yml
loop: "{{ forgejo_runners | dict2items }}"
loop_control:
label: "{{ item.key }}"
- name: create runners configuration
ansible.builtin.template:
src: "runners/docker-compose.yml.j2"
dest: "{{ forgejo_runners_config_dir }}/docker-compose.yml"
owner: root
group: root
mode: "0644"
- name: start runners service
community.docker.docker_compose_v2:
project_src: "{{ forgejo_runners_config_dir }}"
files:
- docker-compose.yml

View file

@ -0,0 +1,61 @@
---
- name: check database password
ansible.builtin.assert:
that: forgejo_db_password is defined
- name: create directories
ansible.builtin.file:
state: directory
path: "{{ item }}"
owner: forgejo
group: forgejo
mode: "0755"
loop: &forgejo_directories
- "{{ forgejo_config_dir }}"
- "{{ forgejo_home_dir }}"
- "{{ forgejo_home_dir }}/server"
- "{{ forgejo_home_dir }}/db"
- name: ensure permissions on those directories
ansible.builtin.command:
cmd: "chown -R forgejo:forgejo {{ item }}"
loop: *forgejo_directories
- name: create docker-compose configuration
ansible.builtin.template:
src: "{{ item.name }}.j2"
dest: "{{ forgejo_config_dir }}/{{ item.name }}"
owner: root
group: root
mode: "{{ item.mode }}"
loop:
- name: docker-compose.yml
mode: "0644"
- name: server.env
mode: "0600"
- name: db.env
mode: "0600"
- name: start service
community.docker.docker_compose_v2:
project_src: "{{ forgejo_config_dir }}"
files:
- docker-compose.yml
- name: allow with iptables
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
source: "{{ item }}"
destination_ports:
- "{{ forgejo_web_port }}"
- "{{ forgejo_ssh_port }}"
jump: ACCEPT
comment: forgejo
loop: "{{ forgejo_allowed_sources }}"
notify: save iptables
when: forgejo_manage_iptables
- name: deploy runners
ansible.builtin.include_tasks: deploy-runners.yml
when: forgejo_runners

View file

@ -0,0 +1,21 @@
---
- name: add forgejo user
ansible.builtin.user:
name: forgejo
system: yes
password: '!'
home: "{{ forgejo_home_dir }}"
create_home: no
- name: read forgejo attributes
ansible.builtin.getent:
database: passwd
key: forgejo
- name: deploy server
ansible.builtin.include_tasks: deploy-server.yml
when: forgejo_server
- name: deploy runners
ansible.builtin.include_tasks: deploy-runners.yml
when: forgejo_runners is defined

View file

@ -0,0 +1,39 @@
---
- name: check variables
ansible.builtin.assert:
that:
- forgejo_runners_instance is defined
- forgejo_runners_version is defined
- forgejo_runners_config_dir is defined
- "'key' in item"
- "'value' in item"
- name: create runner subdirectory
ansible.builtin.file:
path: "{{ forgejo_runners_config_dir }}/{{ item.key }}"
state: directory
mode: "0755"
owner: forgejo
group: forgejo
- name: register runner
ansible.builtin.command:
cmd: >-
docker run
-v /var/run/docker.sock:/var/run/docker.sock
-v {{ forgejo_runners_config_dir }}/{{ item.key }}:/data
--rm
--user {{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}
code.forgejo.org/forgejo/runner:{{ forgejo_runners_version }}
forgejo-runner register --no-interactive
--token {{ item.value.token }}
--name {{ item.key }}
--instance {{ forgejo_runners_instance }}
creates: "{{ forgejo_runners_config_dir }}/{{ item.key }}/.runner"
notify: start runners
- name: create runner configuration
ansible.builtin.template:
src: runners/config.yml.j2
dest: "{{ forgejo_runners_config_dir }}/{{ item.key }}/config.yml"
notify: restart runners

View file

@ -0,0 +1,6 @@
{{ ansible_managed | comment }}
POSTGRES_USER="{{ forgejo_db_username }}"
POSTGRES_PASSWORD="{{ forgejo_db_password }}"
POSTGRES_DB="{{ forgejo_db_database }}"
POSTGRES_INITDB_ARGS="--data-checksums"
POSTGRES_HOST_AUTH_METHOD=scram-sha-256

View file

@ -0,0 +1,35 @@
---
{{ ansible_managed | comment }}
services:
server:
image: codeberg.org/forgejo/forgejo:{{ forgejo_version }}
container_name: forgejo-server
env_file: {{ forgejo_config_dir }}/server.env
restart: always
networks:
- forgejo
volumes:
- "{{ forgejo_home_dir }}/server:/data"
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "{{ forgejo_web_port }}:3000"
- "{{ forgejo_ssh_port }}:22"
depends_on:
- db
db:
image: postgres:17
hostname: db
container_name: forgejo-db
restart: always
env_file: {{ forgejo_config_dir }}/db.env
user: "{{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}"
networks:
- forgejo
volumes:
- "{{ forgejo_home_dir }}/db:/var/lib/postgresql/data"
networks:
forgejo:
external: false

View file

@ -0,0 +1,44 @@
{{ ansible_managed | comment }}
log:
level: info
job_level: info
runner:
file: .runner
capacity: 1
timeout: 3h
shutdown_timeout: 3h
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
report_interval: 1s
{% if item.value.labels | default({}) %}
labels:
{% for label_name, label_value in item.value.labels.items() %}
- "{{ label_name }}:{{ label_value }}"
{% endfor %}
{% endif %}
cache:
enabled: true
port: 0
dir: ""
external_server: ""
secret: ""
host: ""
proxy_port: 0
actions_cache_url_override: ""
container:
network: ""
enable_ipv6: false
privileged: false
options:
workdir_parent:
valid_volumes: []
docker_host: "-"
force_pull: false
force_rebuild: false
host:
workdir_parent:

View file

@ -0,0 +1,27 @@
---
{{ ansible_managed | comment }}
services:
docker:
image: docker:dind
privileged: true
restart: always
volumes:
- certs:/certs
{% for runner in forgejo_runners %}
runner-{{ runner }}:
image: code.forgejo.org/forgejo/runner:{{ forgejo_runners_version }}
user: {{ ansible_facts.getent_passwd.forgejo[1] }}:{{ ansible_facts.getent_passwd.forgejo[2] }}
environment:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_VERIFY: 1
DOCKER_CERT_PATH: /certs/client
restart: always
volumes:
- {{ forgejo_runners_config_dir }}/{{ runner }}:/data
- certs:/certs
command: 'forgejo-runner --config config.yml daemon'
{% endfor %}
volumes:
certs:

View file

@ -0,0 +1,19 @@
{{ ansible_managed | comment }}
USER_UID={{ ansible_facts.getent_passwd.forgejo[1] }}
USER_GID={{ ansible_facts.getent_passwd.forgejo[2] }}
FORGEJO__server__SSH_PORT={{ forgejo_ssh_port }}
FORGEJO__database__DB_TYPE=postgres
FORGEJO__database__HOST=db:5432
FORGEJO__database__NAME="{{ forgejo_db_database }}"
FORGEJO__database__USER="{{ forgejo_db_username }}"
FORGEJO__database__PASSWD="{{ forgejo_db_password }}"
{% if forgejo_mailer %}
{% for k, v in forgejo_mailer.items() %}
FORGEJO__mailer__{{ k | upper }}="{{ v }}"
{% endfor %}
{% endif %}
{% if forgejo_service %}
{% for k, v in forgejo_service.items() %}
FORGEJO__service__{{ k | upper }}="{{ v }}"
{% endfor %}
{% endif %}

View file

@ -0,0 +1,24 @@
---
galene_version: galene-1.0
galene_http_port: 443
galene_turn: ":1194"
galene_user: galene
galene_group: galene
galene_base_directory: /var/lib/galene
galene_data_directory: "{{ galene_base_directory }}/data"
galene_groups_directory: "{{ galene_base_directory }}/groups"
galene_recording_directory: "{{ galene_base_directory }}/recordings"
galene_static_directory: "{{ galene_base_directory }}/static"
# galene_domain:
# galene_config:
# canonicalHost: galene.example.org
galene_config: {}
# galene_groups:
# example:
# users:
# bob:
# password: ***
# permissions: op
galene_groups: {}

View file

@ -0,0 +1,9 @@
---
- name: Reload systemd
ansible.builtin.systemd_service:
daemon_reload: true
- name: Restart galene
ansible.builtin.service:
name: galene
state: restarted

View file

@ -0,0 +1,3 @@
---
dependencies:
- role: golang

116
roles/galene/tasks/main.yml Normal file
View file

@ -0,0 +1,116 @@
---
# TODO: install in block
- name: Install requirements
ansible.builtin.package:
name: git
- name: Clone source code
ansible.builtin.git:
repo: https://github.com/jech/galene
dest: /opt/galene
version: "{{ galene_version }}"
- name: Compile
ansible.builtin.command:
chdir: /opt/galene
cmd: go build -ldflags='-s -w'
creates: /opt/galene/galene
environment:
CGO_ENABLED: "0"
PATH: /usr/local/go/bin
- name: Install
ansible.builtin.copy:
remote_src: true
src: /opt/galene/galene
dest: /usr/local/bin/galene
owner: root
group: root
mode: "0755"
# TODO End of install in block
- name: Create user
ansible.builtin.user:
name: "{{ galene_user }}"
system: true
password: '!'
home: "{{ galene_base_directory }}"
create_home: false
- name: Create directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ galene_user }}"
group: "{{ galene_group }}"
mode: "0755"
loop:
- "{{ galene_base_directory }}"
- "{{ galene_data_directory }}"
- "{{ galene_groups_directory }}"
- "{{ galene_recording_directory }}"
- "{{ galene_static_directory }}"
- name: Copy static directory
ansible.builtin.copy:
src: /opt/galene/static/
dest: "{{ galene_static_directory }}/"
remote_src: true
mode: "0755"
owner: "{{ galene_user }}"
group: "{{ galene_group }}"
when: galene_static_directory != "/opt/galene/static"
- name: Configure groups
ansible.builtin.copy:
content: "{{ item.value | to_json }}"
dest: "{{ galene_groups_directory }}/{{ item.key }}.json"
owner: "{{ galene_user }}"
group: "{{ galene_group }}"
mode: "0600"
loop: "{{ galene_groups | dict2items }}"
loop_control:
label: "{{ item.key }}"
notify: Restart galene
- name: Create global configuration
ansible.builtin.copy:
content: "{{ galene_config | to_json }}"
dest: "{{ galene_data_directory }}/config.json"
owner: "{{ galene_user }}"
group: "{{ galene_group }}"
mode: "0600"
notify: Restart galene
- name: Configure TLS certificates
when: galene_domain is defined
ansible.builtin.copy:
remote_src: true
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ galene_user }}"
group: "{{ galene_group }}"
loop:
- src: "/etc/letsencrypt/live/{{ galene_domain }}/fullchain.pem"
dest: "{{ galene_data_directory }}/cert.pem"
mode: "0644"
- src: "/etc/letsencrypt/live/{{ galene_domain }}/privkey.pem"
dest: "{{ galene_data_directory }}/key.pem"
mode: "0600"
- name: Create service
ansible.builtin.template:
src: galene.service.j2
dest: /etc/systemd/system/galene.service
mode: "0644"
owner: root
group: root
notify:
- Reload systemd
- Restart galene
- name: Start service
ansible.builtin.service:
name: galene
state: started
enabled: true

View file

@ -0,0 +1,19 @@
{{ ansible_managed | comment }}
[Unit]
Description=Galene
After=network.target
[Service]
Type=simple
WorkingDirectory={{ galene_base_directory }}
User={{ galene_user }}
Group={{ galene_group }}
{% if galene_http_port < 1024 %}
AmbientCapabilities=CAP_NET_BIND_SERVICE
{% endif %}
ExecStart=/usr/local/bin/galene -http :{{ galene_http_port }} -data {{ galene_data_directory }} -groups {{ galene_groups_directory }} -recordings {{ galene_recording_directory }} -static {{ galene_static_directory }} -turn "{{ galene_turn }}"
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,2 @@
---
golang_version: 1.25.4

View file

@ -0,0 +1,7 @@
---
- name: Install
ansible.builtin.unarchive:
src: "https://go.dev/dl/go{{ golang_version }}.linux-amd64.tar.gz"
dest: /usr/local
remote_src: true
creates: /usr/local/go

1
roles/navidrome/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
venv

35
roles/navidrome/README.md Normal file
View file

@ -0,0 +1,35 @@
# Ansible Role Navidrome
Ansible role to manage a [Navidrome](https://github.com/navidrome/navidrome) instance.
## Configuration
See [Variable
precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#ansible-variable-precedence)
to find where you should put your own variables.
See list of [default
variables](https://git.riou.xyz/jriou/ansible-role-navidrome/src/branch/main/defaults/main.yml).
## Usage
Example of a basic navidrome.yml playbook:
```yaml
hosts:
- navidrome
roles:
- navidrome
```
Then run the playbook:
```
ansible-playbook navidrome.yml
```
## Donate
As we all love FOSS, you should consider sponsoring the
[Navidrome](https://github.com/navidrome/navidrome) project.

View file

@ -0,0 +1,14 @@
---
navidrome_version: 0.54.5
navidrome_arch: amd64
navidrome_user: navidrome
navidrome_group: navidrome
navidrome_music_folder: /opt/navidrome/music
navidrome_data_folder: /var/lib/navidrome
navidrome_cache_folder: "{{ navidrome_data_folder }}/cache"
navidrome_manage_iptables: false
navidrome_allowed_sources: []
navidrome_address: localhost
navidrome_port: 4533
navidrome_enable_insights_collector: false
# navidrome_base_url:

View file

@ -0,0 +1,14 @@
---
- name: Reload systemd
ansible.builtin.systemd_service:
daemon_reload: true
- name: Restart navidrome
ansible.builtin.service:
name: navidrome
state: restarted
- name: Save iptables
ansible.builtin.command:
cmd: netfilter-persistent save
changed_when: true

View file

@ -0,0 +1,62 @@
---
- name: Install package
ansible.builtin.apt:
deb: "https://github.com/navidrome/navidrome/releases/download/v{{ navidrome_version }}/navidrome_{{ navidrome_version }}_linux_{{ navidrome_arch }}.deb"
- name: Create directories
ansible.builtin.file:
state: directory
path: "{{ item }}"
owner: "{{ navidrome_user }}"
group: "{{ navidrome_group }}"
mode: "0755"
loop:
- "{{ navidrome_music_folder }}"
- "{{ navidrome_data_folder }}"
- "{{ navidrome_cache_folder }}"
- name: Create configuration file
ansible.builtin.template:
src: navidrome.toml.j2
dest: /etc/navidrome/navidrome.toml
owner: "{{ navidrome_user }}"
group: "{{ navidrome_group }}"
mode: "0644"
notify:
- Restart navidrome
- name: Create systemd override directory
ansible.builtin.file:
state: directory
path: /etc/systemd/system/navidrome.service.d
owner: root
group: root
mode: "0755"
- name: Add systemd override
ansible.builtin.template:
src: override.conf.j2
dest: /etc/systemd/system/navidrome.service.d/override.conf
owner: root
group: root
mode: "0755"
notify:
- Reload systemd
- Restart navidrome
- name: Start service
ansible.builtin.service:
name: navidrome
state: started
- name: Manage iptables
ansible.builtin.iptables:
chain: INPUT
protocol: tcp
source: "{{ item }}"
destination_port: "{{ navidrome_port }}"
jump: ACCEPT
comment: navidrome
loop: "{{ navidrome_allowed_sources }}"
notify: Save iptables
when: navidrome_manage_iptables

View file

@ -0,0 +1,10 @@
{{ ansible_managed | comment }}
MusicFolder = "{{ navidrome_music_folder }}"
DataFolder = "{{ navidrome_data_folder }}"
CacheFolder = "{{ navidrome_cache_folder }}"
Address = "{{ navidrome_address }}"
Port = "{{ navidrome_port }}"
EnableInsightsCollector = "{{ navidrome_enable_insights_collector }}"
{% if navidrome_base_url is defined %}
BaseUrl = "{{ navidrome_base_url }}"
{% endif %}

View file

@ -0,0 +1,5 @@
{{ ansible_managed | comment }}
[Service]
User={{ navidrome_user }}
WorkingDirectory={{ navidrome_data_folder }}
ReadWritePaths={{ navidrome_data_folder }}