Compare commits

...

332 Commits

Author SHA1 Message Date
ec51e99087 chore(playbooks/authelia): add more tags 2026-03-15 17:09:26 +01:00
143310aabc update(authelia): bump version to 4.39.16 2026-03-15 16:29:06 +01:00
b4080f1f2c update(gitea): bump version to 1.25.5 2026-03-15 12:41:21 +01:00
5d42897dd1 chore(playbooks/pretix): improved ansible tagging 2026-03-13 19:39:56 +01:00
bb00502100 update(pretix): bump version to 2026.2.0 2026-03-13 19:39:55 +01:00
9b6d78d933 fix(keycloak): no syntax mixing in container args 2026-03-08 22:19:43 +01:00
2088bccf8c update(ghost): bump version to 6.21.0 2026-03-07 15:11:04 +01:00
0378bfbc0a update(keycloak): bump version to 26.5.5 2026-03-05 22:55:42 +01:00
717b3164a6 update(ghost): bump version to 6.19.3 2026-03-01 19:10:24 +01:00
3eeeee58bc update(hedgedoc): bump version to 1.10.7 2026-02-26 19:52:08 +01:00
ab538bf034 update(snipe_it): bump version to 8.4.0 2026-02-24 17:01:17 +01:00
1e4e1cc976 update(playbooks/gitea): support putting anubis in front of gitea 2026-02-21 18:46:26 +01:00
6e88875b87 feat(anubis): add ansible role and playbook 2026-02-21 18:46:18 +01:00
0385a191e8 update(keycloak): bump version to 26.5.4 2026-02-20 21:42:39 +01:00
25329996d0 update(ghost): bump version to 6.19.1 2026-02-17 21:07:13 +01:00
4edeac717b update(vaultwarden): bump version to 1.35.3 2026-02-13 21:34:21 +01:00
7e0f7ba65a meta: ensure NpmSpec is used for specifying collection dependencies 2026-02-10 20:42:48 +01:00
c28194c9f7 update(keycloak): bump version to 26.5.3 2026-02-10 20:40:47 +01:00
dbb01ba24a update(hedgedoc): bump version to 1.10.6 2026-02-04 21:57:31 +01:00
4341c740c0 update(phpldapadmin): bump version to 2.3.9 2026-02-03 10:00:02 +01:00
4666fdff45 update(ghost): bump version to 6.16.1 2026-02-01 18:21:49 +01:00
5ec7c248a9 update(ghost): bump version to 6.14.0 2026-01-26 21:54:05 +01:00
da692ab691 update(keycloak): bump version to 26.5.2 2026-01-23 21:57:01 +01:00
3c137977c5 update(gitea): bump version to 1.25.4 2026-01-22 21:35:20 +01:00
25ddb3e07c update(jellyfin): bump version to 10.11.6 2026-01-19 11:48:28 +01:00
ffb66bad27 update(ghost): bump versio to 6.13.2 2026-01-18 20:50:01 +01:00
df2c72da25 feat(playbooks/keycloak): allow overriding postgresql client address 2026-01-17 13:42:41 +01:00
b2e01d0f5e update(playbooks/vaultwarden): remove unneeded pre_tasks 2026-01-17 13:02:29 +01:00
1ab39acc95 update(keycloak): bump version to 26.5.1 2026-01-14 19:40:33 +01:00
8912c9428f update(ghost): bump version to 6.12.0 2026-01-11 20:58:25 +01:00
3b63d8615d update(vaultwarden): bump version to 1.35.2 2026-01-09 23:26:51 +01:00
54f104db43 update(keycloak): bump version to 26.5.0 2026-01-06 11:20:40 +01:00
efb55e2e62 update(phpldapadmin): bump version to 2.3.8 2026-01-04 11:43:53 +01:00
b80301248b update(vaultwarden): bump version to 1.35.1 2025-12-30 19:13:03 +01:00
85168c0635 update(playbooks/pretix): add caddy reverse proxy management 2025-12-29 17:02:32 +01:00
d64234c4ef feat(playbooks/snipe_it): add playbook 2025-12-29 16:21:30 +01:00
57d20b8438 fix(playbooks/jellyfin): fix typo 2025-12-29 16:19:13 +01:00
5fa0f4032b feat(playbooks/authelia): add playbook 2025-12-29 16:00:10 +01:00
619920c297 feat(playbooks/unifi_controller): enable caddy reverse proxy management 2025-12-29 15:26:25 +01:00
a534d5e1d2 update(unifi_controller): bump version to 10.0.162 2025-12-28 14:31:28 +01:00
3ed2158b4c feat(playbooks/keycloak): add playbook 2025-12-28 14:16:11 +01:00
3f44c2261d feat(playbooks/phpldapadmin): expand playbook 2025-12-28 12:38:53 +01:00
3f743def26 feat(playbooks/jellyfin): add playbook 2025-12-28 12:14:09 +01:00
9a1481e760 feat(playbooks/vaultwarden): add playbook 2025-12-28 11:11:46 +01:00
12fa3e5bdf chore(vaultwarden): add network retries for container image retrieval 2025-12-28 11:05:42 +01:00
6fae0d9d31 update(vaultwarden): bump version to 1.35.0 2025-12-28 10:40:23 +01:00
487b6bfa67 update(ghost): bump version to 6.10.3 2025-12-27 23:52:41 +01:00
418e6bd626 feat(playbooks/hedgedoc): add ansible playbook 2025-12-26 14:35:06 +01:00
ac6f9dfad7 feat(playbooks/gitea): add playbook 2025-12-25 15:51:01 +01:00
73c227cc54 fix(playbook/pretix): allow mapping ports on nginx container 2025-12-22 13:48:59 +01:00
bdfeb66112 chore(pretix): fix task name warnings 2025-12-22 10:39:09 +01:00
cafa6b8beb update(pretix): bump version to 2025.10.1 2025-12-21 22:07:20 +01:00
d01f0ef7cb update(jellyfin): bump version to 10.11.5 2025-12-19 22:44:07 +01:00
7dd7213362 update(gitea): bump version to 1.25.3 2025-12-19 22:08:52 +01:00
9b7aa0c233 update(phpldapadmin): bump version to 2.3.7 2025-12-18 22:05:30 +01:00
77a4708251 chore(playbooks/pretix): add tag for valkey 2025-12-14 17:44:04 +01:00
10729bc4a3 update(snipe_it): bump version to 8.3.7 2025-12-12 20:28:35 +01:00
a7763636fa update(ghost): bump version to 6.10.1 2025-12-08 17:07:00 +01:00
c44eb78c17 update(hedgedoc): bump version to 1.10.5 2025-12-07 09:35:02 +01:00
2fbb2a1d8c meta: bump collection version to 0.2.2 2025-12-06 08:36:02 +01:00
417e190368 update(hedgedoc): bump version to 1.10.4 2025-12-06 08:33:21 +01:00
7558cb4992 update(keycloak): bump version to 26.4.7 2025-12-02 17:38:37 +01:00
02aa9a0ed9 update(jellyfin): bump version to 10.11.4 2025-12-02 17:38:01 +01:00
22384de456 update(phpldapadmin): bump version to 2.3.5 2025-12-01 16:09:37 +01:00
8eda51cca6 updates(authelia): bump version to 4.39.15 2025-11-29 20:32:50 +01:00
c6b338fec3 update(ghost): bump version to 6.9.1 2025-11-27 22:32:31 +01:00
d3dc6298c0 update(keycloak): bump version to 26.4.6 2025-11-25 19:33:45 +01:00
fedd8abf04 update(snipe_it): bump version to 8.3.6 2025-11-24 17:02:20 +01:00
006a568038 update(unifi_controller): bump version to 9.5.21 2025-11-23 13:00:13 +01:00
d118333b97 feat(unifi_controller): add ansible role and playbook 2025-11-23 12:59:52 +01:00
438dda0c6a update(gitea): bump version to 1.25.2 2025-11-22 21:40:24 +01:00
03f4e33558 update(jellyfin): bump version to 10.11.3 2025-11-17 21:52:51 +01:00
538ca940c1 update(ghost): bump version to 6.8.0 2025-11-14 23:48:49 +01:00
77be291a50 update(keycloak): bump version to 26.4.5 2025-11-12 17:38:02 +01:00
83b7cf1a33 update(snipe_it): bump version to 8.3.5 2025-11-10 22:45:26 +01:00
6b870de0fb update(authelia): bump version to 4.39.14 2025-11-09 13:58:57 +01:00
5e56e73132 update(ghost): bump version to 6.7.0 2025-11-08 23:08:48 +01:00
7881d97eb5 update(keycloak): bump version to 26.4.4 2025-11-07 21:07:27 +01:00
d859544a98 feat(playbooks/pretix): allow configuring certificate obtainal method 2025-11-06 22:31:04 +01:00
8767fdd1a7 update(pretix): bump version to 2025.9.0 2025-11-06 22:25:10 +01:00
d7931d73d1 update(gitea): bump version to 1.25.1 2025-11-05 21:20:44 +01:00
75bbe2e5e3 update(jellyfin): bump version to 10.11.2 2025-11-04 19:14:18 +01:00
5a429ee504 update(gitea): bump version to 1.25.0 2025-10-29 21:04:33 +01:00
6e8a7b055a update(jellyfin): bump version to 10.11.1 2025-10-27 16:22:54 +01:00
bb6fce90a9 update(gitea): bump version to 1.24.7 2025-10-25 23:16:33 +02:00
c6acd7cf19 chore(jellyfin): allow setting container environment 2025-10-24 17:58:30 +02:00
3286c56929 meta: bump collection version to 0.2.1 2025-10-23 18:49:50 +02:00
cd4fac6372 update(ghost): bump version to 6.5.1 2025-10-23 18:48:46 +02:00
22cce2bf06 update(keycloak): bump version to 26.4.2 2025-10-23 18:47:45 +02:00
22c1e9d179 update(jellyfin): bump version to 10.11.0 2025-10-20 18:10:41 +02:00
acc7ae289b update(snipe_it): bump version to 8.3.4 2025-10-17 22:06:34 +02:00
3adb3d4d6d update(keycloak): bump version to 26.4.1 2025-10-16 15:35:24 +02:00
86cea40cfc update(vouch_proxy): bump version to 0.45.1 2025-10-13 16:41:00 +02:00
066a5f2c59 update(authelia): bump version to 4.39.13 2025-10-12 09:09:39 +02:00
ce14010fee update(ghost): bump version to 6.3.1 2025-10-10 22:46:57 +02:00
e6f0c912d5 update(pretix): bump version to 2025.8.0 2025-10-08 18:36:39 +02:00
8838e17624 update(authelia): bump version to 4.39.12 2025-10-08 13:42:02 +02:00
5d8845c075 update(snipe_it): bump version to 8.3.3 2025-10-07 12:23:12 +02:00
c593006de1 update(phpldapadmin): bump version to 2.3.4 2025-10-07 10:36:51 +02:00
55363ef3ae update(keycloak): bump version to 26.4.0 2025-10-01 16:00:29 +02:00
504b54f7ef update(authelia): bump version to 4.39.11 2025-10-01 15:44:49 +02:00
bca5e68288 feat(pretix): add ansible role and playbook 2025-09-29 16:41:20 +02:00
04f62eb021 update(keycloak): bump version to 26.3.5 2025-09-25 21:27:21 +02:00
887fd4055f update(phpldapadmin): bump version to 2.3.3 2025-09-20 19:06:19 +02:00
873dc4894a update(snipe_it): bump version to 8.3.2 2025-09-19 22:06:15 +02:00
1b979d54d3 update(authelia): bump version to 4.39.10 2025-09-16 22:46:34 +02:00
a1aea3ba10 update(phpldapadmin): bump version to 2.3.1 2025-09-13 10:53:53 +02:00
7360beb85d update(gitea): bump version to 1.24.6 2025-09-11 22:02:20 +02:00
c5d66a4bc3 update(authelia): bump version to 4.39.9 2025-09-09 19:04:52 +02:00
c1643a2a06 update(ghost): bump version to 6.0.7 2025-09-08 22:33:46 +02:00
6b004e3477 update(authelia): bump version to 4.39.8 2025-09-02 18:19:12 +02:00
b6e0a88716 update(snipe_it): bump version to 8.3.1 2025-09-01 16:59:08 +02:00
ae24dcfd9b update(authelia): bump version to 4.39.7 2025-08-31 16:12:29 +02:00
5457046433 update(snipe_it): bump version to 8.3.0 2025-08-29 22:04:30 +02:00
61be252a50 update(ghost): bump version to 6.0.5 2025-08-23 22:57:24 +02:00
20867e7a36 update(vouch_proxy): bump version to 0.45.0 2025-08-22 21:17:33 +02:00
5fbe6325d0 update(keycloak): bump version to 26.3.3 2025-08-20 16:26:41 +02:00
f3aa284efa update(ghost): bump version to 6.0.4 2025-08-19 21:24:30 +02:00
94a73bd3a9 update(phpldapadmin): bump version to 2.3.0 2025-08-18 21:38:25 +02:00
b66213e29d meta: update collection version to 0.2.0, update dependencies 2025-08-16 17:12:17 +02:00
79a39e1aca update(gitea): bump version to 1.24.5 2025-08-13 19:00:25 +02:00
448975a12f update(authelia): bump version to 4.39.6 2025-08-09 10:19:13 +02:00
9cde7b3961 update(gitea): bump version to 1.24.4 2025-08-04 21:47:37 +02:00
0b1ac4957e update(vaultwarden): bump version to 1.34.3 2025-07-31 23:27:20 +02:00
ef83afc453 update(vaultwarden): bump version to 1.34.2 2025-07-28 16:12:58 +02:00
4d266054d4 update(keycloak): bump version to 26.3.2 2025-07-25 22:59:40 +02:00
15810fd6dc update(snipe_it): bump version to 8.2.1 2025-07-24 20:30:42 +02:00
df5f37bd5a update(snipe_it): bump version to 8.2.0 2025-07-23 17:30:53 +02:00
6a5f04f751 update(phpldapadmin): bump version to 2.2.2 2025-07-18 23:06:48 +02:00
63803053dc update(gitea): bump version to 1.24.3 2025-07-15 21:16:00 +02:00
0d07413608 update(phpldapadmin): bump version to 2.2.1 2025-07-13 16:14:54 +02:00
f46812872c update(authelia): bump version to 4.39.5 2025-07-13 10:16:25 +02:00
9861de8914 update(snipe_it): bump version to 8.1.18 2025-07-09 18:15:27 +02:00
b73d10f31e update(keycloak): bump version to 26.3.1 2025-07-09 18:13:22 +02:00
a38ded822f update(ghost): bump version to 5.129.1 2025-07-06 22:48:56 +02:00
52a8630554 update(keycloak): bump version to 26.3.0 2025-07-02 21:53:21 +02:00
d0cbff5d20 update(snipe-it): bump version to 8.1.17 2025-06-30 15:32:13 +02:00
3a52c20914 update(ghost): bump version to 5.126.1 2025-06-22 19:37:07 +02:00
017edc5ee5 update(gitea): bump version to 1.24.2 2025-06-21 11:03:45 +02:00
f8a5b865ae update(gitea): bump version to 1.24.1 2025-06-20 16:24:55 +02:00
a3f750c17d update(snipe_it): bump version to 8.1.16 2025-06-16 15:57:30 +02:00
b12a374ef1 update(gost): bump version to 5.125.1 2025-06-14 23:06:41 +02:00
aa6bf10e97 update(gitea): bump version to 1.24.0 2025-06-11 19:49:49 +02:00
78beaa1814 meta: add community.general@^10.0.0 dependency 2025-06-07 22:14:50 +02:00
fcbcb39e55 update(ghost): bump version to 5.121.0 2025-06-06 23:10:35 +02:00
a7b6189fa3 update(snipe_it): bump version to 8.1.15 2025-06-03 16:42:39 +02:00
cd0e305d34 update(ghost): bump version to 5.102.4 2025-05-30 17:16:02 +02:00
d09baa48fa update(keycloak): bump version to 26.2.5 2025-05-28 12:53:54 +02:00
3bb6928fad update(vaultwarden): bump version to 1.34.1 2025-05-27 16:25:46 +02:00
bce1d4ecee update(authelia): bump version to 4.39.4 2025-05-25 14:04:24 +02:00
4de87f2407 update(snipe_it): bump version to 8.1.4 2025-05-23 15:03:05 +02:00
2984018cd2 update(ghost): bump version to 5.120.0 2025-05-17 22:07:45 +02:00
536c988d64 update(gitea): bump version to 1.23.8 2025-05-13 15:54:51 +02:00
ef34c4de67 update(authelia): bump version to 4.39.3 2025-05-11 20:25:12 +02:00
f23a3538bd update(authelia): bump version to 4.39.2, change registry to ghcr.io 2025-05-10 23:31:32 +02:00
503c421b2f update(ghost): bump version to 5.119.2 2025-05-09 21:59:52 +02:00
46f26900fc update(keycloak): bump version to 26.2.4 2025-05-08 17:56:15 +02:00
0b9bfc1646 update(snipe_it): bump version to 8.1.3 2025-05-07 17:24:22 +02:00
79c8b6537e update(keycloak): bump version to 26.2.3 2025-05-05 16:11:18 +02:00
1de7bc2de9 update(snipe_it): bump version to 8.1.2 2025-05-05 16:08:35 +02:00
9587b4193c feat(phpldapadmin): add ansible role 2025-05-02 21:52:12 +02:00
f996c7a373 chore(vaultwarden): use strict env comparisions for container 2025-05-01 10:21:15 +02:00
e1866a1a41 update(keycloak): bump version to 26.2.2 2025-04-30 16:56:05 +02:00
800ebbae77 meta: update collection version to 0.1.15 2025-04-27 19:00:17 +02:00
6faba56371 update(keycloak): bump version to 26.2.1 2025-04-23 18:21:28 +02:00
05aec0581b update(ghost): bump version to 5.117.0 2025-04-17 17:45:11 +02:00
fbe33c06cf update(keycloak): bump version to 26.2.0 2025-04-12 11:34:44 +02:00
0e405cef07 update(keycloak): bump version to 26.1.5 2025-04-12 11:34:43 +02:00
42782b58a4 update(hedgedoc): bump version to 1.10.3 2025-04-10 17:08:45 +02:00
ee410b29a8 update(gitea): bump version to 1.23.7 2025-04-08 21:21:42 +02:00
1f7c4635a4 update(jellyfin): bump version to 10.10.7 2025-04-06 09:09:38 +02:00
7995eba69b update(ghost): bump version to 5.116.0 2025-04-04 21:59:18 +02:00
c766e2ef46 meta: bump galaxy version to 0.1.14 2025-03-28 16:05:11 +01:00
8e667d113a update(gitea): bump version to 1.23.6 2025-03-25 17:13:53 +01:00
c8d49760b1 update(ghost): bump version to 5.113.1 2025-03-20 22:06:35 +01:00
c28cba452c update(snipe_it): bump version to 8.0.4 2025-03-18 21:24:02 +01:00
ed5118ea95 update(authelia): bump version to 4.39.1 2025-03-18 20:33:33 +01:00
4d43f3c425 update(ghost): bump version to 5.113.0 2025-03-17 21:49:18 +01:00
3c789f2736 update(authelia): bump version to 4.39.0 2025-03-16 19:56:00 +01:00
62b99afa95 update(keycloak): bump version to 26.1.4 2025-03-14 22:32:25 +01:00
213cff7da7 update(ghost): bump version to 5.111.0 2025-03-07 21:34:55 +01:00
6ce6c3ce41 update(gitea): bump version to 1.23.5 2025-03-06 14:57:09 +01:00
70fa36ff98 update(snipe_it): bump version to 7.1.17 2025-03-03 21:09:04 +01:00
a4d56624e5 chore(jellyfin): allow passing more options to docker container 2025-03-02 21:23:27 +01:00
fc79dc4bc1 update(keycloak): bump version to 26.1.3 2025-02-28 19:15:31 +01:00
94404387cc feat(authelia): add state absent support 2025-02-26 20:51:21 +01:00
6a420416db update(ghost): bump version to 5.110.1 2025-02-26 20:42:02 +01:00
fac73c1a6a update(vouch_proxy): bump version to 0.41.0 2025-02-20 17:39:58 +01:00
307025181b update(gitea): bump version to 1.23.4 2025-02-19 15:18:07 +01:00
f7594fed77 update(jellyfin): bump version to 10.10.6 2025-02-17 12:42:21 +01:00
c72e87dfd5 update(authelia): bump version to 4.38.19 2025-02-16 14:56:02 +01:00
82fc10fd5f update(hedgedoc): bump version to 1.10.2 2025-02-15 10:45:31 +01:00
05145b3b21 feat(jellyfin): add podman as deployment method 2025-02-14 22:26:48 +01:00
1e234bf68b feat(vaultwarden): support podman as deployment method 2025-02-14 22:12:52 +01:00
6516780e16 meta: add containers.podman@^1.16.0 to collection requirements 2025-02-14 22:12:51 +01:00
06df5b790e feat(hedgedoc): support podman as deployment method 2025-02-14 22:12:50 +01:00
9bfd87f256 meta: bump galaxy version to 0.1.13 2025-02-12 21:59:50 +01:00
20a4cf4da4 update(keycloak): bump version to 26.1.2 2025-02-11 17:24:58 +01:00
60ce6ca758 update(vaultwarden): bump version to 1.33.2 2025-02-09 19:44:00 +01:00
a1039eaa45 update(ghost): bump version to 5.109.3 2025-02-07 21:35:11 +01:00
01ff782b14 update(gitea): bump version to 1.23.3 2025-02-06 17:31:40 +01:00
bc61a40771 update(keycloak): bump version to 26.1.1 2025-02-06 17:31:09 +01:00
94ddaf98f0 chore(keycloak): allow disabling mapping of local providers into the container image 2025-02-04 12:04:15 +01:00
23f5f560b6 update(vaultwarden): bump version to 1.33.1 2025-02-03 20:23:50 +01:00
a8f74baa53 meta: bump version to 0.1.12, require community.docker@^4.0.0, community.crypto@^2.22.0 2025-02-03 09:44:09 +01:00
836183ad55 update(hedgedoc): bump version to 1.10.1 2025-02-03 09:40:21 +01:00
0deea90113 update(ghost): bump version to 5.109.0 2025-02-02 19:50:54 +01:00
a5108c1bb6 feat(gitea): allow specifying container user for rootless mode 2025-01-31 13:11:54 +01:00
a278d5a438 meta: bump collection version to 0.1.11 2025-01-30 15:47:46 +01:00
6ff3590514 update(jellyfin): bump version to 10.10.5 2025-01-26 09:01:10 +01:00
801b4b2cbf update(vaultwarden): bump version to 1.33.0 2025-01-25 22:06:06 +01:00
5ea018e04c update(ghost): bump version to 5.107.2 2025-01-23 21:40:20 +01:00
842492c30d update(jellyfin): bump version to 10.10.4 2025-01-22 20:37:58 +01:00
249f2e8926 update(ghost): bump version to 5.107.0 2025-01-19 14:07:00 +01:00
0f75b2a4aa update(keycloak): bump version to 26.1.0 2025-01-18 12:36:11 +01:00
d934993817 update(keycloak): bump version to 26.0.8 2025-01-17 16:01:52 +01:00
4c65b70f97 update(gitea): bump version to 1.23.1 2025-01-10 19:21:04 +01:00
fe5ebb9531 update(gitea): bump version to 1.23.0 2025-01-09 20:18:45 +01:00
2d5b6a9357 update(authelia): bump version to 4.38.18 2025-01-01 20:45:01 +01:00
563e261ef3 fix(hedgedoc): jinja template syntax error 2024-12-29 15:18:46 +01:00
51a466a150 update(ghost): bump version to 5.105.0 2024-12-24 23:07:59 +01:00
7b9fed4a11 update(gitea): bump version to 1.22.6 2024-12-23 19:58:02 +01:00
25be7155e0 update(vaultwarden): bump version to 1.32.7 2024-12-21 23:04:35 +01:00
950d017889 update(authelia): bump version to 4.38.17 2024-12-14 22:33:27 +01:00
31639291f1 meta: update collection to 0.1.10 2024-12-08 13:54:25 +01:00
127a128a73 update(gitea): bump version to 1.22.4 2024-12-08 13:52:42 +01:00
6bf38f8273 update(ghost): bump version to 5.103.0 2024-12-05 23:18:32 +01:00
266057d11c update(keycloak): bump version to 26.0.7 2024-12-03 16:14:52 +01:00
afa91a622b update(keycloak): bump version to 26.0.6 2024-11-29 22:50:54 +01:00
d92262798a update(snipe_it): bump version to 7.1.15 2024-11-28 22:05:40 +01:00
4b13c448d0 update(ghost): bump version to 5.101.4 2024-11-27 20:04:01 +01:00
a9a988ec69 update(ghost): bump version to 5.101.3 2024-11-23 21:54:14 +01:00
d9de07c8f8 update(jellyfin): bump version to 10.10.3 2024-11-19 14:08:00 +01:00
c51dd4c142 meta: update collection to 0.1.9 2024-11-18 14:01:46 +01:00
bfd6449a71 update(vaultwarden): bump version to 1.32.5 2024-11-18 14:00:42 +01:00
7ebde915db update(ghost): bump version to 5.101.1 2024-11-15 21:07:30 +01:00
a18c8c3355 meta: bump collection version to 0.1.8 2024-11-11 08:34:17 +01:00
5a6ffc6991 update(vaultwarden): bump version to 1.32.4 2024-11-11 08:32:26 +01:00
e7ea03c00e update(jellyfin): bump version to 10.10.1 2024-11-10 19:52:04 +01:00
c7040c96f8 chore(keycloak): set keycloak hostname and header mode for proxy 2024-11-09 12:21:56 +01:00
d8d0b5c9e5 chore(keycloak): use fully-qualified module names 2024-11-08 18:30:18 +01:00
1d1f519e3a chore(keycloak): split upstream container image coordinates 2024-11-08 18:29:35 +01:00
11d5c81c60 update(keycloak): bump version to 26.0.5 2024-11-08 18:24:12 +01:00
f7eeb59288 update(keycloak): bump version to 25.0.6 2024-11-08 18:11:25 +01:00
72d8ac9644 feat(keycloak): add ansible role
Migrate role from `entropia.sso` collection
2024-11-08 18:05:19 +01:00
d3d6f89949 fix(authelia): correctly template session.redis config section, fix container restarts recreating the container 2024-11-02 10:48:05 +01:00
43d0dc171a update(openproject)!: bump version to release/14 2024-11-01 21:32:08 +01:00
d8dfb24df0 update(vaultwarden): bump version to 1.32.3 2024-10-31 09:53:41 +01:00
57c8dae0c4 meta: bump version to 0.1.7 2024-10-27 19:26:55 +01:00
6385b6f7a8 update(jellyfin): bump version to 10.10.0 2024-10-27 19:23:09 +01:00
7d09c9a88d feat(snipe_it): add ansible role for deployment 2024-10-27 18:35:22 +01:00
98c60a73c6 meta: bump version to 0.1.6 2024-10-22 20:42:24 +02:00
5ac019bace docs: fix typo 2024-10-19 17:33:13 +02:00
43fd798712 feat(vaultwarden): add ansible role 2024-10-19 17:26:50 +02:00
88dc6377ce fix(hedgedoc): incorrect module used 2024-10-19 17:13:24 +02:00
0a132b0ad5 meta: update collection version to 0.1.5, add galaxy tags 2024-10-10 17:01:35 +02:00
72942ee382 update(hedgedoc): bump version to 1.10.0 2024-10-10 16:59:06 +02:00
755e5d55f2 update(ghost): bump version to 5.96.0 2024-10-10 16:58:01 +02:00
5023a56b29 update(authelia): bump version to 4.38.15 2024-10-10 16:56:49 +02:00
17dfe4b2bb update(gitea): bump version to 1.22.3 2024-10-10 16:55:57 +02:00
cd122ebbdb fix(gitea): typo in variable name 2024-10-10 16:55:27 +02:00
0d914bd11c feat(hedgedoc): add deployment_method=podman, add docs 2024-10-09 20:06:48 +02:00
49ed240f10 fix(hedgedoc): add options ports and user to container creation task 2024-10-08 17:55:06 +02:00
81d6f809d7 meta: bump collection version to 0.1.4 2024-10-07 19:44:08 +02:00
b24ea1e925 feat(jellyfin): add playbook to collection, add state=absent support to role 2024-10-07 19:42:22 +02:00
912c32cb3e feat(hedgedoc): add ansible role for deployment 2024-10-07 19:09:52 +02:00
cde5f12e79 meta: bump galaxy version to 0.1.3 2024-10-03 22:37:43 +02:00
a8f5507eab meta: add role descriptions 2024-10-03 22:34:28 +02:00
ddfa8d6687 chore(jellyfin): migrate to fully-qualified module names 2024-10-03 22:25:46 +02:00
fd4cc0fe6a meta: require community.crypto@^2.0.0 in collection 2024-10-03 22:24:30 +02:00
3a15ed1157 chore(gitea): migrate to fully-qualified module names 2024-10-03 22:22:31 +02:00
a7fad79d05 chore(authelia): add container recreation option 2024-10-03 22:19:16 +02:00
f3d3617ec0 chore(authelia): migrate to fully-qualified module names 2024-10-03 22:18:34 +02:00
908b579f2c chore(authelia): more config migration in preparation for authelia 5.0.x 2024-10-03 22:05:08 +02:00
bab5b94500 update(ghost): bump version to 5.95.0 2024-10-03 21:30:48 +02:00
b5b4f67a08 chore(authelia): migrate away from deprecated config options 2024-10-03 18:01:40 +02:00
5e29e174d5 chore(authelia): add etc_hosts container option 2024-10-03 17:06:49 +02:00
6001399569 meta: bump collection version to 0.1.2, take issues on codeberg repo, require community.general>=3.0.0 2024-10-03 16:58:58 +02:00
87df054977 update(authelia): bump version to 4.38.15 2024-10-03 16:57:00 +02:00
8c89d40fcd chore(authelia): split container image into parts 2024-10-03 16:55:46 +02:00
f231d4e7d3 chore(gitea): split container_image_name into parts for easier overriding 2024-10-03 14:05:35 +02:00
80077af008 meta: bump collection version to 0.1.1 2024-09-21 11:29:19 +02:00
eeb66de8a4 update(ghost): bump version to 5.94.1 2024-09-21 11:28:56 +02:00
396f1b3a57 update(vouch_proxy): bump version to 0.40.0 2024-09-21 11:27:20 +02:00
be66a3fe7a update(jellyfin): bump version to 10.9.11 2024-09-21 11:26:19 +02:00
5bfca1a55c meta: require atleast ansible >= 2.15.0 2024-09-21 11:25:19 +02:00
70238d3bd4 meta: update galaxy collection version to 0.1.0 2024-09-21 10:25:17 +02:00
f6a97805de docs: update README links 2024-09-21 10:24:17 +02:00
b350a19bcc update(gitea): bump version to 1.22.2 2024-09-19 14:57:47 +02:00
74a3216a41 update(jellyfin): bump version to 10.9.8 2024-07-21 19:23:05 +02:00
ef6da18172 feat(openproject): add deployment using docker-compose 2024-03-31 14:27:53 +02:00
65a256e8b5 update(ghost): bump version to 5.78.0 2024-02-04 10:53:50 +01:00
6547f15bb4 update(gitea): bump version to 1.21.5 2024-02-04 10:44:19 +01:00
5f19b5d9a9 refactor(gitea): support using forgejo in the role 2023-10-07 22:18:02 +02:00
4a2d1dec92 update(gitea): bump version to 1.20.5 2023-10-07 17:46:02 +02:00
4632a1263a update(ghost): bump version to 5.67.0 2023-10-07 16:21:20 +02:00
e5924d5ecb chore(ghost): improve role task names and fix mount permissions 2023-10-07 16:16:53 +02:00
f2fe2fb034 meta: update collection to 0.0.3 2023-08-05 18:34:31 +02:00
e8e97a5d89 update(gitea): bump version to 1.20.2 2023-08-05 18:20:53 +02:00
5ea358e65d update(ghost): bump version to 5.58.0 2023-08-05 18:20:31 +02:00
82ff46ee99 meta: bump galaxy version to 0.0.2 2023-07-28 15:47:05 +02:00
8a2993e9c3 chore(restic)!: migrate restic role to finallycoffee.base collection 2023-07-28 15:33:53 +02:00
87094b81ec chore(minio)!: migrate minio role to finallycoffee.base collection 2023-07-28 15:24:08 +02:00
bbe369d525 chore(elasticsearch)!: migrate elasticsearch role to finallycoffee.base collection 2023-07-28 15:23:55 +02:00
ed56665ed8 chore(nginx)!: migrate nginx role to finallycoffee.base collection 2023-07-28 15:11:09 +02:00
98be926e89 chore: add ansible collection metadata 2023-07-19 19:14:47 +02:00
0fc751f7d6 chore(nginx): add README 2023-07-19 19:10:16 +02:00
271410f4c6 update(jellyfin): bump version to 10.8.10 2023-07-19 19:09:56 +02:00
e17369ae38 chore(jellyfin): add README 2023-07-19 19:08:36 +02:00
a3c2716b7f chore(ghost): add README 2023-07-19 19:08:10 +02:00
c8802b9dbf chore(vouch-proxy)!: rename role to vouch_proxy 2023-07-19 19:07:44 +02:00
4ef456efdf chore: update metadata 2023-07-17 21:05:05 +02:00
cd31d8b6af feat(nginx): add ansible role 2023-07-16 19:01:55 +02:00
20cb480915 feat(vouch-proxy): add ansible role for vouch-proxy 2023-07-16 18:58:33 +02:00
e1756fd4b0 update(authelia): bump version to 4.37.5 2023-07-14 12:15:16 +02:00
1e12c0fcfd update(gitea): bump version to 1.19.4 2023-07-14 12:07:25 +02:00
f368107966 update(gitea): bump version to 1.18.3 2023-02-09 21:09:49 +01:00
0aa621b510 feat(ghost): add role for deployment using docker 2023-02-06 21:22:21 +01:00
0c509f6b66 update(jellyfin): bump version to 10.8.6 2022-10-31 10:56:25 +01:00
a364a58717 update(elasticsearch): bump version to 7.17.7 2022-10-31 10:55:14 +01:00
ccd50cb8cf update(gitea): bump version to 1.17.3 2022-10-31 10:53:59 +01:00
1fe626fad5 feat(elasticsearch): add role for single-node deployment using docker containers 2022-08-26 09:00:02 +02:00
d4858c89f4 feat(authelia): allow customizing authelia by mapping the asset folder from the host 2022-08-26 08:48:36 +02:00
6658d7226c fix(authelia): notifier.smtp.startup_check_address changed from bool to email address 2022-08-11 16:52:52 +02:00
36224d0531 fix(authelia): prometheus metrics config was wrongly scoped to toplevel telemetry key 2022-08-11 16:49:35 +02:00
24be358a46 chore(authelia): authentication_backend.disable_password_reset was deprecated 2022-08-11 16:48:21 +02:00
c38e4f34dd update(authelia): bump version to 4.36.4 2022-08-11 16:40:30 +02:00
10a9779996 update(gitea): bump version to 1.17.0 2022-08-06 16:32:11 +02:00
b635a00a34 update(jellyfin): bump version to 10.8.1, switch to versioned role 2022-07-17 15:59:19 +02:00
159c4fda30 update(gitea): bump version to 1.16.9 2022-07-17 15:52:51 +02:00
1e104bf1fb update(authelia): bump version to 4.36.2 2022-07-17 15:51:34 +02:00
1417564e1d update(gitea): bump version to 1.16.8 2022-06-19 11:03:11 +02:00
148 changed files with 3690 additions and 533 deletions

View File

@@ -1,4 +1,4 @@
# `finallycoffee.service` ansible collection
# `finallycoffee.services` ansible collection
## Overview
@@ -8,20 +8,48 @@ concise area of concern.
## Roles
- [`roles/authelia`](roles/authelia/README.md): Deploys an [authelia.com](https://www.authelia.com)
- [`authelia`](roles/authelia/README.md): Deploys an [authelia.com](https://www.authelia.com)
instance, an authentication provider with beta OIDC provider support.
- [`roles/gitea`](roles/gitea/README.md): Deploy [gitea.io](https://gitea.io), a
- [`ghost`](roles/ghost/README.md): Deploys [ghost.org](https://ghost.org/), a simple to use
blogging and publishing platform.
- [`gitea`](roles/gitea/README.md): Deploy [gitea.io](https://gitea.io), a
lightweight, self-hosted git service.
- [`roles/jellyfin`](roles/jellyfin/README.md): Deploy [jellyfin.org](https://jellyfin.org),
- [`hedgedoc`](roles/hedgedoc/README.md): Deploy [hedgedoc](https://hedgedoc.org/),
a collaborative real-time markdown editor using websockts
- [`jellyfin`](roles/jellyfin/README.md): Deploy [jellyfin.org](https://jellyfin.org),
the free software media system for streaming stored media to any device.
- [`roles/restic`](roles/restic/README.md): Manage backups using restic
and persist them to a configurable backend.
- [`keycloak`](roles/keycloak/README.md): Deploy [keycloak](https://www.keycloak.org/),
the open source identity and access management solution.
- [`roles/minio`](roles/minio/README.md): Deploy [min.io](https://min.io), an
s3-compatible object storage server, using docker containers.
- [`openproject`](roles/openproject/README.md): Deploys an [openproject.org](https://www.openproject.org)
installation using the upstream provided docker-compose setup.
- [`pretix`](roles/pretix/README.md): Deploy [pretix](https://pretix.eu), the open source online ticketing solution.
- [`snipe_it`](roles/snipe_it/README.md): Deploys [Snipe-IT](https://snipeitapp.com/),
the free and open-source IT asset (and license) management with a powerful REST API
- [`vaultwarden`](roles/vaultwarden/README.md): Deploy [vaultwarden](https://github.com/dani-garcia/vaultwarden/),
an open-source implementation of the Bitwarden Server (formerly Bitwarden\_RS).
- [`vouch_proxy`](roles/vouch_proxy/README.md): Deploys [vouch-proxy](https://github.com/vouch/vouch-proxy),
an authorization proxy for arbitrary webapps working with `nginx`s' `auth_request` module.
## Playbooks
- [`authelia`](playbooks/authelia.md)
- [`hedgedoc`](playbooks/hedgedoc.md)
- [`jellyfin`](playbooks/jellyfin.md)
- [`keycloak`](playbooks/keycloak.md)
- [`gitea`](playbooks/gitea.md)
- [`phpldapadmin`](playbooks/phpldapadmin.md)
- [`snipe_it`](playbooks/snipe_it.md)
- [`vaultwarden`](playbooks/vaultwarden.md)
## License

View File

@@ -1,15 +1,29 @@
namespace: finallycoffee
name: services
version: 0.0.1
version: "0.2.2"
readme: README.md
authors:
- Johanna Dorothea Reichmann <transcaffeine@finallycoffee.eu>
- transcaffeine <transcaffeine@finally.coffee>
description: Various ansible roles useful for automating infrastructure
dependencies:
"community.docker": "^1.10.0"
license:
- CNPLv7+
"community.general": ">=11.0.0"
"community.crypto": ">=3.0.3"
"community.docker": ">=4.7.0"
"containers.podman": ">=1.16.0"
"finallycoffee.base": ">=0.3.0"
license_file: LICENSE.md
build_ignore:
- '*.tar.gz'
repository: https://git.finallycoffee.eu/finallycoffee.eu/services
issues: https://git.finallycoffee.eu/finallycoffee.eu/services/issues
repository: https://git.finally.coffee/finallycoffee/services
issues: https://codeberg.org/finallycoffee/ansible-collection-services/issues
tags:
- authelia
- gitea
- hedgedoc
- jellyfin
- vaultwarden
- snipeit
- docker
- phpldapadmin
- pretix
- keycloak

3
meta/runtime.yml Normal file
View File

@@ -0,0 +1,3 @@
---
requires_ansible: ">=2.15"

7
playbooks/anubis.yml Normal file
View File

@@ -0,0 +1,7 @@
---
- name: Ensure anubis is installed and configured
hosts: "{{ anubis_hosts | default('anubis') }}"
gather_facts: "{{ anubis_gather_facts | default(false) }}"
become: "{{ anubis_become | default(false) }}"
roles:
- role: finallycoffee.services.anubis

7
playbooks/authelia.md Normal file
View File

@@ -0,0 +1,7 @@
# `finallycoffee.services.authelia` ansible playbook
## Feature toggles
- `authelia_configure_postgesql_client` (default `false`)
- `authelia_configure_lego_rfc2136` (default `false`)
- `authelia_configure_caddy_reverse_proxy` (default `false`)

118
playbooks/authelia.yml Normal file
View File

@@ -0,0 +1,118 @@
---
- import_playbook: finallycoffee.databases.postgresql_client
when: authelia_configure_postgresql_client | default(false)
vars:
postgresql_hosts: >-2
{{ authelia_postgresql_hosts | default(authelia_hosts | default('authelia')) }}
postgresql_become: >-2
{{ authelia_postgresql_become | default(authelia_become | default(false)) }}
postgresql_client_username: "{{ authelia_database_user }}"
postgresql_client_password: "{{ authelia_database_pass }}"
postgresql_client_database: "{{ authelia_database_name }}"
postgresql_client_database_lc_ctype: 'C'
postgresql_client_database_lc_collate: 'C'
tags:
- authelia
- authelia-postgresql-client
- postgresql-client
- import_playbook: finallycoffee.base.lego_certificate
when: authelia_configure_lego_rfc2136 | default(false)
vars:
target_domains:
- "{{ authelia_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ authelia_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_dns_additional_records: "{{ authelia_dns_records }}"
target_hosts: >-2
{{ authelia_lego_hosts | default(authelia_hosts | default('authelia')) }}
target_become: >-2
{{ authelia_lego_become | default(authelia_become | default(false)) }}
target_gather_facts: >-2
{{ authelia_lego_gather_facts | default(false) }}
tags:
- authelia
- authelia-lego
- lego
- name: Install and configure authelia
hosts: "{{ authelia_hosts | default('authelia') }}"
become: "{{ authelia_become | default(false) }}"
gather_facts: "{{ authelia_gather_facts | default(false) }}"
pre_tasks:
- name: Ensure valkey user exists
ansible.builtin.user:
name: "{{ valkey_user }}"
state: present
system: true
create_home: false
register: valkey_user_info
when: valkey_state == 'present'
tags:
- authelia
- authelia-valkey
- name: Create host folder for valkey unix socket
ansible.builtin.file:
path: "{{ authelia_redis_unix_socket }}"
state: directory
mode: "0755"
owner: "{{ valkey_user_info.uid | default(valkey_user) }}"
group: "{{ valkey_user_info.group | default(valkey_user) }}"
when: valkey_state == 'present'
tags:
- authelia
- authelia-valkey
- valkey
roles:
- name: finallycoffee.databases.valkey
vars:
valkey_secret: "{{ authelia_redis_pass }}"
valkey_config_user:
- "default on +@all -DEBUG ~* >{{ valkey_secret }}"
valkey_config_unixsocketperm: 666
valkey_container_networks: []
valkey_container_purge_networks: true
valkey_container_volumes:
- "{{ authelia_redis_unix_socket }}:{{ authelia_redis_unix_socket }}"
valkey_container_image_registry: "{{ nexus_docker_hub_domain }}"
tags:
- authelia
- authelia-valkey
- name: finallycoffee.services.authelia
vars:
authelia_redis_host: "{{ valkey_config_unixsocket }}"
authelia_redis_port: ~
authelia_container_extra_volumes:
- "{{ authelia_redis_unix_socket }}:{{ authelia_redis_unix_socket }}"
- "{{ authelia_postgres_unix_socket }}:{{ authelia_postgres_unix_socket }}"
authelia_container_ports:
- "{{ authelia_host_bind_ip }}:{{ authelia_container_listen_port }}"
tags:
- authelia
vars:
valkey_instance: >-2
{{ authelia_instance_name | default('authelia') }}
authelia_redis_unix_socket: >-2
{{ authelia_redis_unix_socket_path
| default('/var/run/redis-' + valkey_instance + '-socket', true) }}
valkey_config_unixsocket: >-2
{{ authelia_valkey_config_unixsocket
| default(authelia_redis_unix_socket + '/redis.sock') }}
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: authelia_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ authelia_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ authelia_host_bind_ip }}"
target_hosts: >-2
{{ authelia_caddy_hosts | default(authelia_hosts | default('authelia')) }}
target_become: >-2
{{ authelia_caddy_become | default(authelia_become | default(false)) }}
target_gather_facts: >-2
{{ authelia_caddy_gather_facts | default(false) }}
tags:
- authelia
- authelia-caddy
- caddy

7
playbooks/gitea.md Normal file
View File

@@ -0,0 +1,7 @@
# `finallycoffee.services.gitea` ansible playbook
## Feature toggles
- `gitea_configure_postgesql_client` (default `true`)
- `gitea_configure_lego_rfc2136` (default `true`)
- `gitea_configure_caddy_reverse_proxy` (default `false`)

74
playbooks/gitea.yml Normal file
View File

@@ -0,0 +1,74 @@
---
- import_playbook: finallycoffee.databases.postgresql_client
when: gitea_configure_postgresql_client | default(true) | bool
vars:
postgresql_become: "{{ gitea_postgresql_client_become | default(true) }}"
postgresql_hosts: >-2
{{ gitea_postgresql_hosts | default(gitea_hosts | default('gitea')) }}
postgresql_client_username: "{{ gitea_database_user }}"
postgresql_client_password: "{{ gitea_database_pass }}"
postgresql_client_database: "{{ gitea_database_name }}"
postgresql_client_database_lc_collate: >-2
{{ gitea_postgresql_database_lc_collate | default('en_US.UTF-8') }}
postgresql_client_database_lc_ctype: >-2
{{ gitea_postgresql_database_lc_ctype | default('en_US.UTF-8') }}
tags:
- gitea-postgresql
- import_playbook: finallycoffee.base.lego_certificate
when: gitea_configure_lego_rfc2136 | default(true) | bool
vars:
target_domains:
- "{{ gitea_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ gitea_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_additional_records: "{{ gitea_dns_records }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_hosts: >-2
{{ gitea_lego_hosts | default(gitea_hosts | default('gitea')) }}
target_gather_facts: >-2
{{ gitea_gather_facts | default(false) | bool }}
tags:
- gitea-lego
- name: Install and configure gitea
hosts: "{{ gitea_hosts | default('gitea') }}"
become: "{{ gitea_become | default(true, true) }}"
gather_facts: "{{ gitea_gather_facts | default(false) | bool }}"
pre_tasks:
- name: Ensure referenced docker container networks are present
community.docker.docker_network:
name: "{{ network.name }}"
state: "present"
loop: "{{ gitea_container_networks | default([]) }}"
loop_control:
loop_var: "network"
label: "{{ network.name }}"
roles:
- name: finallycoffee.services.gitea
- import_playbook: finallycoffee.services.anubis
when: gitea_configure_anubis | default(false)
vars:
anubis_hosts: "{{ gitea_hosts | default('gitea') }}"
anubis_become: "{{ gitea_become | default(true, true) }}"
anubis_gather_facts: "{{ gitea_gather_facts | default(false) }}"
anubis_config_target: "http://{{ gitea_host_bind_ip }}"
anubis_config_bind: "{{ gitea_anubis_config_bind_ip }}"
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: gitea_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ gitea_domain }}"
caddy_reverse_proxy_backend_addr: >-2
http://{{ gitea_configure_anubis | default(false)
| ternary(gitea_anubis_config_bind_ip, gitea_host_bind_ip) }}
target_hosts: >-2
{{ gitea_caddy_hosts | default(gitea_hosts | default('gitea')) }}
target_become: >-2
{{ gitea_caddy_become | default(gitea_become | default(true, true)) }}
target_gather_facts: >-2
{{ gitea_caddy_gather_facts | default(false) }}
tags:
- gitea-caddy

7
playbooks/hedgedoc.md Normal file
View File

@@ -0,0 +1,7 @@
# `finallycoffee.services.hedgedoc` ansible playbook
## Feature toggles
- `hedgedoc_configure_postgesql_client` (default `true`)
- `hedgedoc_configure_lego_rfc2136` (default `true`)
- `hedgedoc_configure_caddy_reverse_proxy` (default `false`)

60
playbooks/hedgedoc.yml Normal file
View File

@@ -0,0 +1,60 @@
---
- import_playbook: finallycoffee.databases.postgresql_client
when: hedgedoc_configure_postgresql_client | default(true)
vars:
postgresql_hosts: >-2
{{ hedgedoc_postgresql_hosts | default(hedgedoc_hosts | default('hedgedoc')) }}
postgresql_become: >-2
{{ hedgedoc_postgresql_become | default(hedgedoc_become | default(true)) }}
postgresql_client_username: "{{ hedgedoc_database_user }}"
postgresql_client_password: "{{ hedgedoc_database_pass }}"
postgresql_client_database: "{{ hedgedoc_database_name }}"
postgresql_client_database_lc_collate: "en_US.UTF-8"
postgresql_client_database_lc_ctype: "en_US.UTF-8"
tags:
- hedgedoc
- hedgedoc-postgresql
- import_playbook: finallycoffee.base.lego_certificate
when: hedgedoc_configure_lego_rfc2136 | default(true)
vars:
target_hosts: >-2
{{ hedgedoc_lego_hosts | default(hedgedoc_hosts | default('hedgedoc')) }}
target_gather_facts: >-2
{{ hedgedoc_lego_gather_facts | default(hedgedoc_gather_facts | default(false)) }}
target_become: >-2
{{ hedgedoc_lego_become | default(hedgedoc_become | default(true, false)) }}
target_domains:
- "{{ hedgedoc_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ hedgedoc_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_additional_records: "{{ hedgedoc_dns_records }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
tags:
- hedgedoc
- hedgedoc-lego
- name: Deploy Hedgedoc
hosts: "{{ hedgedoc_hosts | default('hedgedoc') }}"
become: "{{ hedgedoc_become | default(true, false) }}"
gather_facts: "{{ hedgedoc_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.hedgedoc
tags:
- hedgedoc
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: hedgedoc_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ hedgedoc_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ hedgedoc_host_bind_ip }}"
target_hosts: >-2
{{ hedgedoc_caddy_hosts | default(hedgedoc_hosts | default('hedgedoc')) }}
target_become: >-2
{{ hedgedoc_caddy_become | default(hedgedoc_become | default(true, false)) }}
target_gather_facts: >-2
{{ hedgedoc_caddy_gather_facts | default(false) }}
tags:
- hedgedoc
- hedgedoc-caddy

6
playbooks/jellyfin.md Normal file
View File

@@ -0,0 +1,6 @@
# `finallycoffee.services.jellyfin` ansible playbook
## Feature toggles
- `jellyfin_configure_lego_rfc2136` (default `false`)
- `jellyfin_configure_caddy_reverse_proxy` (default `false`)

44
playbooks/jellyfin.yml Normal file
View File

@@ -0,0 +1,44 @@
---
- import_playbook: finallycoffee.base.lego_certificate
when: jellyfin_configure_lego_rfc2136 | default(false)
vars:
target_domains:
- "{{ jellyfin_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ jellyfin_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_dns_additional_records: "{{ jellyfin_dns_records }}"
target_hosts: >-2
{{ jellyfin_lego_hosts | default(jellyfin_hosts | default('jellyfin')) }}
target_become: >-2
{{ jellyfin_lego_become | default(jellyfin_become | default(false)) }}
target_gather_facts: >-2
{{ jellyfin_lego_gather_facts | default(false) }}
tags:
- jellyfin
- jellyfin-lego
- name: Install jellyfin, a selfhosted media streaming platform
hosts: "{{ jellyfin_hosts | default('jellyfin') }}"
become: "{{ jellyfin_become | default(false) }}"
gather_facts: "{{ jellyfin_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.jellyfin
tags:
- jellyfin
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: jellyfin_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ jellyfin_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ jellyfin_host_bind_ip }}"
target_hosts: >-2
{{ jellyfin_caddy_hosts | default(jellyfin_hosts | default('jellyfin')) }}
target_become: >-2
{{ jellyfin_caddy_become | default(jellyfin_become | default(false)) }}
target_gather_facts: >-2
{{ jellyfin_caddy_gather_facts | default(false) }}
tags:
- jellyfin
- jellyfin-caddy

7
playbooks/keycloak.md Normal file
View File

@@ -0,0 +1,7 @@
# `finallycoffee.services.keycloak` ansible playbook
## Feature toggles
- `keycloak_configure_postgesql_client` (default `false`)
- `keycloak_configure_lego_rfc2136` (default `true`)
- `keycloak_configure_caddy_reverse_proxy` (default `false`)

67
playbooks/keycloak.yml Normal file
View File

@@ -0,0 +1,67 @@
---
- import_playbook: finallycoffee.databases.postgresql_client
when: keycloak_configure_postgresql_client | default(false)
vars:
postgresql_hosts: >-2
{{ keycloak_postgresql_client_host | default(keycloak_hosts | default('keycloak')) }}
postgresql_become: >-2
{{ keycloak_postgresql_client_become | default(keycloak_become | default(false)) }}
postgresql_client_username: "{{ keycloak_database_username }}"
postgresql_client_password: "{{ keycloak_database_password }}"
postgresql_client_database: "{{ keycloak_database_database }}"
postgresql_client_database_lc_ctype: 'C'
postgresql_client_database_lc_collate: 'C'
postgresql_client_database_contype: host
postgresql_client_address: >-2
{{ keycloak_postgresql_client_address | default('172.17.0.0/24') }}
tags:
- keycloak
- keycloak-postgresql
- import_playbook: finallycoffee.base.lego_certificate
when: keycloak_configure_lego_rfc2136 | default(true) | bool
vars:
target_domains:
- "{{ keycloak_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ keycloak_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_additional_records: "{{ keycloak_dns_records }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_hosts: >-2
{{ keycloak_lego_hosts | default(keycloak_hosts | default('keycloak')) }}
target_become: >-2
{{ keycloak_lego_become | default(keycloak_become | default(false)) }}
target_gather_facts: >-2
{{ keycloak_lego_gather_facts | default(false) | bool }}
tags:
- keycloak
- keycloak-lego
- name: Set up and configure keycloak
hosts: "{{ keycloak_hosts | default('keycloak') }}"
become: "{{ keycloak_become | default(false) }}"
gather_facts: "{{ keycloak_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.keycloak
tags:
- keycloak
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: keycloak_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ keycloak_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ keycloak_host_bind_ip }}"
caddy_reverse_proxy_template_block: >-2
{{ keycloak_caddy_reverse_proxy_template_block | default(true, false) }}
caddy_reverse_proxy_block: >-2
{{ keycloak_caddy_reverse_proxy_block | default('') }}
target_hosts: >-2
{{ keycloak_caddy_hosts | default(keycloak_hosts | default('keycloak')) }}
target_become: >-2
{{ keycloak_caddy_become | default(keycloak_become | default(false)) }}
target_gather_facts: >-2
{{ keycloak_caddy_gather_facts | default(false) }}
tags:
- keycloak
- keycloak-caddy

View File

@@ -0,0 +1,6 @@
---
- name: Install openproject
hosts: "{{ openproject_hosts | default('openproject') }}"
become: "{{ openproject_become | default(true, false) }}"
roles:
- role: finallycoffee.services.openproject

View File

@@ -0,0 +1,6 @@
# `finallycoffee.services.phpldapadmin` ansible playbook
## Feature toggles
- `phpldapadmin_configure_lego_rfc2136` (default `false`)
- `phpldapadmin_configure_caddy_reverse_proxy` (default `false`)

View File

@@ -0,0 +1,44 @@
---
- import_playbook: finallycoffee.base.lego_certificate
when: phpldapadmin_configure_lego_rfc2136 | default(false)
vars:
target_domains:
- "{{ phpldapadmin_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ phpldapadmin_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_dns_additional_records: "{{ phpldapadmin_dns_records }}"
target_hosts: >-2
{{ phpldapadmin_lego_hosts | default(phpldapadmin_hosts | default('phpldapadmin')) }}
target_become: >-2
{{ phpldapadmin_lego_become | default(phpldapadmin_become | default(false)) }}
target_gather_facts: >-2
{{ phpldapadmin_lego_gather_facts | default(false) }}
tags:
- phpldapadmin
- phpldapadmin-lego
- name: Configure and run phpldapadmin
hosts: "{{ phpldapadmin_hosts | default('phpldapadmin', true) }}"
become: "{{ phpldapadmin_become | default(false) }}"
gather_facts: "{{ phpldapadmin_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.phpldapadmin
tags:
- phpldapadmin
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: phpldapadmin_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ phpldapadmin_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ phpldapadmin_host_bind_ip }}"
target_hosts: >-2
{{ phpldapadmin_caddy_hosts | default(phpldapadmin_hosts | default('phpldapadmin')) }}
target_become: >-2
{{ phpldapadmin_caddy_become | default(phpldapadmin_become | default(false)) }}
target_gather_facts: >-2
{{ phpldapadmin_caddy_gather_facts | default(false) }}
tags:
- phpldapadmin
- phpldapadmin-caddy

142
playbooks/pretix.yml Normal file
View File

@@ -0,0 +1,142 @@
---
- import_playbook: finallycoffee.databases.postgresql_client
when: pretix_configure_postgresql | default(true)
vars:
postgresql_hosts: "{{ pretix_hosts | default('pretix') }}"
postgresql_become: >-2
{{ pretix_postgresql_client_become | default(pretix_become | default(true)) }}
postgresql_client_database: "{{ pretix_postgresql_database | default('pretix') }}"
postgresql_client_username: "{{ pretix_postgresql_user | default('pretix') }}"
postgresql_client_password: >-2
{{ pretix_postgresql_password | mandatory(msg='pretix postgresql password is required') }}
tags:
- postgresql
- pretix
- pretix-postgresql
- import_playbook: finallycoffee.base.lego_certificate
when: pretix_acquire_lego_certificate | default(false)
vars:
target_hosts: "pretix"
target_domains:
- "{{ pretix_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ pretix_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_additional_records: "{{ pretix_dns_records }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_gather_facts: "{{ pretix_gather_facts | default(false) }}"
tags:
- lego
- pretix
- pretix-lego
- import_playbook: finallycoffee.databases.valkey
when: pretix_configure_valkey | default(true)
vars:
valkey_hosts: "{{ pretix_hosts | default('pretix') }}"
valkey_instance: "pretix"
valkey_secret: "{{ pretix_redis_secret | mandatory(msg='pretix valkey secret is required') }}"
valkey_config_user:
- "default on +@all -DEBUG ~* &* >{{ pretix_redis_secret }}"
valkey_container_ports:
- "{{ pretix_redis_bind_addr | default('127.0.10.1:6739') }}:{{ valkey_config_port }}"
valkey_config_bind:
- "0.0.0.0"
- "-::"
tags:
- pretix
- pretix-valkey
- name: Install and configure pretix
hosts: "{{ pretix_hosts | default('pretix') }}"
become: "{{ pretix_become | default(true) }}"
gather_facts: "{{ pretix_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.pretix
vars:
pretix_config_url: "https://{{ pretix_domain }}"
pretix_config_database_name: "{{ pretix_postgresql_database | default('pretix') }}"
pretix_config_database_user: "{{ pretix_postgresql_user | default('pretix') }}"
pretix_config_database_password: "{{ pretix_postgresql_password }}"
pretix_config_redis_location: >-2
redis://:{{ pretix_redis_secret }}@{{ pretix_redis_bind_addr }}/0
pretix_config_celery_backend: >-2
redis://:{{ pretix_redis_secret }}@{{ pretix_redis_bind_addr }}/1
pretix_config_celery_broker: >-2
redis://:{{ pretix_redis_secret }}@{{ pretix_redis_bind_addr }}/2
- role: finallycoffee.base.nginx
when: pretix_configure_nginx | default(true)
vars:
nginx_container_name: "nginx-pretix"
nginx_container_labels: "{{ pretix_nginx_container_labels | default({}, true) }}"
nginx_container_ports: "{{ pretix_nginx_container_ports | default([], true) }}"
nginx_config_file: "{{ nginx_base_path }}/nginx-pretix.conf"
nginx_config: |+
server {
listen 80 default_server;
server_name {{ pretix_domain }};
add_header Referrer-Policy same-origin;
add_header X-Content-Type-Options nosniff;
location / {
proxy_pass http://{{ pretix_config_wsgi_bind_addr }};
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
}
location /media/ {
alias {{ pretix_media_dir }}/;
expires 7d;
access_log off;
}
location ^~ /media/cachedfiles {
deny all;
return 404;
}
location ^~ /media/invoices {
deny all;
return 404;
}
location /static/staticfiles.json {
deny all;
return 404;
}
location /static/CACHE/manifest.json {
deny all;
return 404;
}
location /static/ {
alias {{ pretix_static_asset_dir }};
access_log off;
expires 365d;
add_header Cache-Control "public";
}
}
pretix_detected_python_version: >-2
python{{ ansible_python.version.major }}.{{ ansible_python.version.minor }}
pretix_static_asset_dir: >-2
{{ pretix_virtualenv_dir }}/lib/{{ pretix_python_version | default(pretix_detected_python_version) }}/site-packages/pretix/static.dist/
nginx_container_volumes:
- "{{ nginx_config_file }}:/etc/nginx/conf.d/nginx.conf:ro"
- "{{ pretix_media_dir }}:{{ pretix_media_dir }}:ro"
- "{{ pretix_static_asset_dir }}:{{ pretix_static_asset_dir }}:ro"
vars:
pretix_redis_bind_addr: "127.0.10.1:6739"
tags:
- pretix
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: pretix_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ pretix_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ pretix_host_bind_addr }}"
target_hosts: >-2
{{ pretix_caddy_hosts | default(pretix_hosts | default('pretix')) }}
target_become: >-2
{{ pretix_caddy_become | default(pretix_become | default(true, true)) }}
target_gather_facts: >-2
{{ pretix_caddy_gather_facts | default(false) }}
tags:
- pretix
- pretix-caddy
- caddy

7
playbooks/snipe_it.md Normal file
View File

@@ -0,0 +1,7 @@
# `finallycoffee.services.snipe_it` ansible playbook
## Feature toggles
- `snipe_it_configure_mariadb` (default `true`)
- `snipe_it_configure_lego_rfc2136` (default `false`)
- `snipe_it_configure_caddy_reverse_proxy` (default `false`)

58
playbooks/snipe_it.yml Normal file
View File

@@ -0,0 +1,58 @@
---
- import_playbook: finallycoffee.base.lego_certificate
when: snipe_it_configure_lego_rfc2136 | default(false)
vars:
target_domains:
- "{{ snipe_it_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ snipe_it_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_dns_additional_records: "{{ snipe_it_dns_records }}"
target_hosts: >-2
{{ snipe_it_lego_hosts | default(snipe_it_hosts | default('snipe_it')) }}
target_become: >-2
{{ snipe_it_lego_become | default(snipe_it_become | default(false)) }}
target_gather_facts: >-2
{{ snipe_it_lego_gather_facts | default(false) }}
tags:
- snipe-it
- snipe-it-lego
- name: Set up snipe-it, an asset management system
hosts: "{{ snipe_it_hosts | default('snipe_it') }}"
become: "{{ snipe_it_become | default(false) }}"
roles:
- role: finallycoffee.databases.mariadb
when: snipe_it_configure_mariadb | default(true, true)
vars:
mariadb_root_password: "{{ snipe_it_builtin_database_root_pass }}"
mariadb_database: "{{ snipe_it_config_db_database }}"
mariadb_username: "{{ snipe_it_config_db_username }}"
mariadb_password: "{{ snipe_it_config_db_password }}"
mariadb_container_name: "snipe-it-mysql"
mariadb_container_ports: "{{ snipe_it_builtin_database_container_ports }}"
mariadb_base_path: "/databases/snipe-it/mariadb"
tags:
- snipe-it
- snipe-it-mariadb
- role: finallycoffee.services.snipe_it
tags:
- snipe-it
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: snipe_it_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ snipe_it_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ snipe_it_host_bind_addr }}"
caddy_reverse_proxy_extra_config: >-2
{{ snipe_it_caddy_reverse_proxy_extra_config | default('') }}
target_hosts: >-2
{{ snipe_it_caddy_hosts | default(snipe_it_hosts | default('snipe_it')) }}
target_become: >-2
{{ snipe_it_caddy_become | default(snipe_it_become | default(false)) }}
target_gather_facts: >-2
{{ snipe_it_caddy_gather_facts | default(false) }}
tags:
- snipe-it
- snipe-it-caddy

View File

@@ -0,0 +1,43 @@
---
- import_playbook: finallycoffee.base.lego_certificate
when: unifi_controller_enable_lego_certificate | default(false) | bool
vars:
target_become: "{{ unifi_controller_become | default(false) }}"
target_hosts: "{{ unifi_controller_hosts | default('unifi_controller') }}"
target_gather_facts: "{{ unifi_controller_gather_facts | default(false) }}"
target_domains:
- "{{ unifi_controller_domain }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ unifi_controller_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_additional_records: "{{ unifi_controller_dns_records | default([]) }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
tags:
- unifi-controller
- unifi-controller-lego
- name: Deploy unifi controller
hosts: "{{ unifi_controller_hosts | default('unifi_controller') }}"
become: "{{ unifi_controller_become | default(false) }}"
gather_facts: "{{ unifi_controller_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.unifi_controller
tags:
- unifi-controller
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: unifi_controller_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ unifi_controller_domain }}"
caddy_reverse_proxy_backend_addr: "https://{{ unifi_controller_bind_addr }}"
caddy_reverse_proxy_extra_config: >-2
{{ unifi_controller_caddy_reverse_proxy_extra_config | default('', true) }}
target_hosts: >-2
{{ unifi_controller_caddy_hosts | default(unifi_controller_hosts | default('unifi_controller')) }}
target_become: >-2
{{ unifi_controller_caddy_become | default(unifi_controller_become | default(false)) }}
target_gather_facts: >-2
{{ unifi_controller_caddy_gather_facts | default(false) }}
tags:
- unifi-controller
- unifi-controller-caddy

6
playbooks/vaultwarden.md Normal file
View File

@@ -0,0 +1,6 @@
# `finallycoffee.services.vaultwarden` ansible playbook
## Feature toggles
- `vaultwarden_configure_lego_rfc2136` (default `false`)
- `vaultwarden_configure_caddy_reverse_proxy` (default `false`)

43
playbooks/vaultwarden.yml Normal file
View File

@@ -0,0 +1,43 @@
---
- import_playbook: finallycoffee.base.lego_certificate
when: vaultwarden_configure_lego_rfc2136 | default(false)
vars:
target_domains: "{{ vaultwarden_lego_cert_domains }}"
target_acme_zone: "{{ acme_domain }}"
target_acme_account_email: "{{ vaultwarden_lego_acme_account_email }}"
target_dns_server: "{{ dns_server }}"
target_dns_tsig_key: "{{ dns_tsig_keydata }}"
target_dns_additional_records: "{{ vaultwarden_dns_records }}"
target_hosts: >-2
{{ vaultwarden_lego_hosts | default(vaultwarden_hosts | default('vaultwarden')) }}
target_become: >-2
{{ vaultwarden_lego_become | default(vaultwarden_become | default(false)) }}
target_gather_facts: >-2
{{ vaultwarden_lego_gather_facts | default(false) }}
tags:
- vaultwarden
- vaultwarden-lego
- name: Install and configure vaultwarden
hosts: "{{ vaultwarden_hosts | default('vaultwarden') }}"
become: "{{ vaultwarden_become | default(false) }}"
gather_facts: "{{ vaultwarden_gather_facts | default(false) }}"
roles:
- role: finallycoffee.services.vaultwarden
tags:
- vaultwarden
- import_playbook: finallycoffee.base.caddy_reverse_proxy
when: vaultwarden_configure_caddy_reverse_proxy | default(false)
vars:
caddy_site_name: "{{ vaultwarden_domain }}"
caddy_reverse_proxy_backend_addr: "http://{{ vaultwarden_host_bind_ip }}"
target_hosts: >-2
{{ vaultwarden_caddy_hosts | default(vaultwarden_hosts | default('vaultwarden')) }}
target_become: >-2
{{ vaultwarden_caddy_become | default(vaultwarden_become | default(false)) }}
target_gather_facts: >-2
{{ vaultwarden_caddy_gather_facts | default(false) }}
tags:
- vaultwarden
- vaultwarden-caddy

5
roles/anubis/README.md Normal file
View File

@@ -0,0 +1,5 @@
# `finallycoffee.services.anubis`
Install [Anubis](https://anubis.techaro.lol/), a HTTP proxy which
detects (AI) scrapers by providing a lightweight, non-interactive
browser challenge to clients likely to match scrapers.

View File

@@ -0,0 +1,20 @@
---
anubis_config_dir: "{{ anubis_config_file | dirname }}"
anubis_config_file: "/etc/anubis/{{ anubis_service }}.env"
anubis_bot_policy_file: "{{ anubis_config_dir }}/{{ anubis_service }}.botPolicies.yaml"
anubis_config_bind: "8923"
anubis_config_metrics_bind: "[::1]:8240"
anubis_config_difficulty: "4"
anubis_config_policy_fname: "{{ anubis_bot_policy_file }}"
anubis_config_target: ~
anubis_default_config:
"BIND": "{{ anubis_config_bind }}"
"METRICS_BIND": "{{ anubis_config_metrics_bind }}"
"DIFFICULTY": "{{ anubis_config_difficulty }}"
"POLICY_FNAME": "{{ anubis_config_policy_fname }}"
"TARGET": "{{ anubis_config_target }}"
anubis_config: {}
anubis_merged_config: >-2
{{ anubis_default_config | combine(anubis_config | default({}, true)) }}

View File

@@ -0,0 +1,10 @@
---
anubis_version: "1.25.0"
anubis_base_path: "/opt/anubis"
anubis_bin_path: "{{ anubis_base_path }}/bin"
anubis_state: "present"
anubis_os_name: "linux"
anubis_architecture: "amd64"
anubis_service: "gitea"

View File

@@ -0,0 +1,32 @@
---
anubis_package_server: "https://github.com"
anubis_package_namespace: "TecharoHQ"
anubis_package_repository: "anubis"
# https://github.com/TecharoHQ/anubis/releases/download/v1.25.0/anubis-1.25.0-linux-amd64.tar.gz
anubis_package_url: >-2
{{
[
anubis_package_server,
anubis_package_namespace,
anubis_package_repository,
'releases/download',
'v' + anubis_version,
[
anubis_package_repository,
anubis_version,
anubis_os_name,
anubis_architecture
] | flatten | join('-') + '.tar.gz'
] | flatten | join('/')
}}
anubis_tarball_path: "{{ anubis_base_path }}/anubis-{{ anubis_version }}.tar.gz"
anubis_package_path: >-2
{{ anubis_bin_path }}/anubis-{{ anubis_version }}-{{ anubis_os_name }}-{{ anubis_architecture }}
anubis_tarball_binary: >-2
{{ anubis_package_path }}/bin/anubis
anubis_tarball_systemd_unit_path: >-2
{{ anubis_package_path }}/run/{{ anubis_systemd_template_service_name }}
anubis_tarball_bot_policies: >-2
{{ anubis_package_path }}/doc/botPolicies.yaml
anubis_tarball_default_config_file: >-2
{{ anubis_package_path }}/run/default.env

View File

@@ -0,0 +1,8 @@
---
anubis_systemd_service: "anubis@{{ anubis_service }}.service"
anubis_systemd_template_service_name: "anubis@.service"
anubis_systemd_unit_dir: "/etc/systemd/system"
anubis_systemd_service_enabled: >-2
{{ anubis_state == 'present' }}
anubis_systemd_service_state: >-2
{{ (anubis_state == 'present') | ternary('started', 'stopped') }}

View File

@@ -0,0 +1,5 @@
---
anubis_user: "anubis"
anubis_user_state: "{{ anubis_state }}"
anubis_user_system: true
anubis_user_create_home: false

View File

@@ -0,0 +1,10 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: anubis
description: Ansible role to deploy anubis
galaxy_tags:
- anubis
- ai
- llm

View File

@@ -0,0 +1,18 @@
---
- name: Ensure 'anubis_config_target' is populated
ansible.builtin.fail:
msg: >-2
Variable 'anubis_config_target' must be populated!
when: anubis_config_target | ansible.builtin.type_debug == 'NoneType'
- name: Configure anubis for service '{{ anubis_service }}'
ansible.builtin.lineinfile:
path: "{{ anubis_config_file }}"
line: "{{ config_entry.key }}={{ config_entry.value }}"
regexp: "^{{ config_entry.key }}="
state: present
when: anubis_state == 'present'
loop: "{{ anubis_merged_config | dict2items }}"
loop_control:
loop_var: "config_entry"
label: "{{ config_entry.key }}={{ config_entry.value }}"

View File

@@ -0,0 +1,10 @@
---
- name: Ensure systemd service {{ anubis_systemd_service }} is enabled
ansible.builtin.systemd_service:
name: "{{ anubis_systemd_service }}"
enabled: "{{ anubis_systemd_service_enabled }}"
- name: Ensure systemd service {{ anubis_systemd_service }} is {{ anubis_systemd_service_state }}
ansible.builtin.systemd_service:
name: "{{ anubis_systemd_service }}"
state: "{{ anubis_systemd_service_state }}"

View File

@@ -0,0 +1,51 @@
---
- name: Download and install anubis@{{ anubis_version }}
when: anubis_state == 'present'
block:
- name: Download anubis tarball from {{ anubis_package_url }} to '{{ anubis_tarball_path }}'
ansible.builtin.get_url:
url: "{{ anubis_package_url }}"
url_username: "{{ anubis_package_server_username | default(omit) }}"
url_password: "{{ anubis_package_server_password | default(omit) }}"
dest: "{{ anubis_tarball_path }}"
- name: Create folder '{{ anubis_bin_path }}' to extract archive into
ansible.builtin.file:
dest: "{{ anubis_bin_path }}"
state: directory
- name: Uncompress release tarball into {{ anubis_bin_path }}
ansible.builtin.unarchive:
src: "{{ anubis_tarball_path }}"
dest: "{{ anubis_bin_path }}"
remote_src: true
ignore_errors: "{{ ansible_check_mode }}"
- name: Ensure anubis binary is installed
ansible.builtin.copy:
src: "{{ anubis_tarball_binary }}"
dest: "/usr/bin/anubis"
remote_src: true
- name: Install systemd unit
ansible.builtin.copy:
src: "{{ anubis_tarball_systemd_unit_path }}"
dest: "{{ anubis_systemd_unit_dir }}"
remote_src: true
- name: Ensure configuration folder '{{ anubis_config_dir }}' exists
ansible.builtin.file:
dest: "{{ anubis_config_dir }}"
state: "directory"
- name: Copy default configuration to {{ anubis_config_file }}
ansible.builtin.copy:
src: "{{ anubis_tarball_default_config_file }}"
dest: "{{ anubis_config_file }}"
remote_src: true
- name: Copy bot policy for service '{{ anubis_service }}' to {{ anubis_bot_policy_file }}
ansible.builtin.copy:
src: "{{ anubis_tarball_bot_policies }}"
dest: "{{ anubis_bot_policy_file }}"
remote_src: true

View File

@@ -0,0 +1,33 @@
---
- name: Ensure 'anubis_state' is valid
ansible.builtin.fail:
msg: >-2
Invalid state '{{ anubis_state }}'! Supported
states are {{ anubis_states | join(', ') }}
when: anubis_state not in anubis_states
- name: Ensure anubis user '{{ anubis_user }}' is {{ anubis_user_state }}
ansible.builtin.user:
name: "{{ anubis_user }}"
state: "{{ anubis_user_state }}"
system: "{{ anubis_user_system }}"
create_home: "{{ anubis_user_create_home }}"
- name: Ensure anubis base path '{{ anubis_base_path }}' is {{ anubis_state }}
ansible.builtin.file:
path: "{{ anubis_base_path }}"
state: "directory"
when: anubis_state == 'present'
- name: Ensure anubis is installed
ansible.builtin.include_tasks:
file: "install.yml"
- name: Ensure anubis is configured
ansible.builtin.include_tasks:
file: "configure.yml"
when: anubis_state == 'present'
- name: Ensure anubis is deployed
ansible.builtin.include_tasks:
file: "deploy.yml"

View File

@@ -0,0 +1,4 @@
---
anubis_states:
- "present"
- "absent"

View File

@@ -1,25 +1,38 @@
---
authelia_version: 4.34.6
authelia_version: "4.39.16"
authelia_user: authelia
authelia_base_dir: /opt/authelia
authelia_domain: authelia.example.org
authelia_state: present
authelia_deployment_method: docker
authelia_config_dir: "{{ authelia_base_dir }}/config"
authelia_config_file: "{{ authelia_config_dir }}/config.yaml"
authelia_data_dir: "{{ authelia_base_dir }}/data"
authelia_asset_dir: "{{ authelia_base_dir }}/assets"
authelia_sqlite_storage_file: "{{ authelia_data_dir }}/authelia.sqlite3"
authelia_notification_storage_file: "{{ authelia_data_dir }}/notifications.txt"
authelia_user_storage_file: "{{ authelia_data_dir }}/user_database.yml"
authelia_container_name: authelia
authelia_container_image_name: docker.io/authelia/authelia
authelia_container_image_server: ghcr.io
authelia_container_image_namespace: authelia
authelia_container_image_name: authelia
authelia_container_image: >-2
{{
[
authelia_container_image_server,
authelia_container_image_namespace,
authelia_container_image_name
] | join('/')
}}
authelia_container_image_tag: ~
authelia_container_image_ref: "{{ authelia_container_image_name }}:{{ authelia_container_image_tag | default(authelia_version, true) }}"
authelia_container_image_ref: >-2
{{ authelia_container_image }}:{{ authelia_container_image_tag | default(authelia_version, true) }}
authelia_container_image_force_pull: "{{ authelia_container_image_tag | default(false, True) }}"
authelia_container_env:
PUID: "{{ authelia_run_user }}"
PGID: "{{ authelia_run_group }}"
PUID: "{{ authelia_run_user | string }}"
PGID: "{{ authelia_run_group | string }}"
authelia_container_labels: >-2
{{ authelia_container_base_labels | combine(authelia_container_extra_labels) }}
authelia_container_extra_labels: {}
@@ -41,11 +54,22 @@ authelia_config_jwt_secret: ~
authelia_config_default_redirection_url: ~
authelia_config_server_host: 0.0.0.0
authelia_config_server_port: "{{ authelia_container_listen_port }}"
authelia_config_server_address: >-2
{{ authelia_config_server_host }}:{{ authelia_config_server_port }}
authelia_config_server_path: ""
authelia_config_server_read_buffer_size: 4096
authelia_config_server_write_buffer_size: 4096
authelia_config_server_enable_pprof: true
authelia_config_server_enable_expvars: true
authelia_config_server_asset_path: "/config/assets/"
authelia_config_server_buffers_read: 4096
authelia_config_server_read_buffer_size: >-2
{{ authelia_config_server_buffers_read }}
authelia_config_server_buffers_write: 4096
authelia_config_server_write_buffer_size: >-2
{{ authelia_config_server_buffers_write }}
authelia_config_server_endpoints_enable_pprof: true
authelia_config_server_enable_pprof: >-2
{{ authelia_config_server_endpoints_enable_pprof }}
authelia_config_server_endpoints_enable_expvars: true
authelia_config_server_enable_expvars: >-2
{{ authelia_config_server_endpoints_enable_expvars }}
authelia_config_server_disable_healthcheck:
authelia_config_server_tls_key: ~
authelia_config_server_tls_certificate: ~
@@ -55,6 +79,8 @@ authelia_config_log_level: info
authelia_config_log_format: json
authelia_config_log_file_path: ~
authelia_config_log_keep_stdout: false
authelia_config_telemetry_metrics_enabled: false
authelia_config_telemetry_metrics_address: '0.0.0.0:9959'
authelia_config_totp_disable: true
authelia_config_totp_issuer: "{{ authelia_domain }}"
authelia_config_totp_algorithm: sha1
@@ -66,7 +92,11 @@ authelia_config_webauthn_disable: true
authelia_config_webauthn_timeout: 60s
authelia_config_webauthn_display_name: "Authelia ({{ authelia_domain }})"
authelia_config_webauthn_attestation_conveyance_preference: indirect
authelia_config_webauthn_user_verification: preferred
authelia_config_webauthn_user_verification: "preferred"
authelia_config_webauthn_selection_criteria_user_verification: >-2
{{ authelia_config_webauthn_user_verification }}
authelia_config_webauthn_selection_criteria_discoverability: "preferred"
authelia_config_webauthn_selection_criteria_attachment: ""
authelia_config_duo_api_hostname: ~
authelia_config_duo_api_integration_key: ~
authelia_config_duo_api_secret_key: ~
@@ -76,11 +106,13 @@ authelia_config_ntp_version: 4
authelia_config_ntp_max_desync: 3s
authelia_config_ntp_disable_startup_check: false
authelia_config_ntp_disable_failure: false
authelia_config_authentication_backend_disable_reset_password: false
authelia_config_authentication_backend_refresh_interval: 5m
authelia_config_authentication_backend_password_reset_disable: false
authelia_config_authentication_backend_password_reset_custom_url: ~
authelia_config_authentication_backend_ldap_implementation: custom
authelia_config_authentication_backend_ldap_url: ldap://127.0.0.1:389
authelia_config_authentication_backend_ldap_address: >-2
{{ authelia_config_authentication_backend_ldap_url }}
authelia_config_authentication_backend_ldap_timeout: 5s
authelia_config_authentication_backend_ldap_start_tls: false
authelia_config_authentication_backend_ldap_tls_skip_verify: false
@@ -90,10 +122,18 @@ authelia_config_authentication_backend_ldap_additional_users_dn: "ou=users"
authelia_config_authentication_backend_ldap_users_filter: "(&(|({username_attribute}={input})({mail_attribute}={input}))(objectClass=inetOrgPerson))"
authelia_config_authentication_backend_ldap_additional_groups_dn: "ou=groups"
authelia_config_authentication_backend_ldap_groups_filter: "(member={dn})"
authelia_config_authentication_backend_ldap_attributes_username: uid
authelia_config_authentication_backend_ldap_username_attribute: >-2
{{ authelia_config_authentication_backend_ldap_attributes_username }}
authelia_config_authentication_backend_ldap_attributes_mail: mail
authelia_config_authentication_backend_ldap_mail_attribute: >-2
{{ authelia_config_authentication_backend_ldap_attributes_mail }}
authelia_config_authentication_backend_ldap_attributes_display_name: displayName
authelia_config_authentication_backend_ldap_display_name_attribute: >-2
{{ authelia_config_authentication_backend_ldap_attributes_display_name }}
authelia_config_authentication_backend_ldap_group_name_attribute: cn
authelia_config_authentication_backend_ldap_username_attribute: uid
authelia_config_authentication_backend_ldap_mail_attribute: mail
authelia_config_authentication_backend_ldap_display_name_attribute: displayName
authelia_config_authentication_backend_ldap_attributes_group_name: >-2
{{ authelia_config_authentication_backend_ldap_group_name_attribute }}
authelia_config_authentication_backend_ldap_user: ~
authelia_config_authentication_backend_ldap_password: ~
authelia_config_authentication_backend_file_path: ~
@@ -121,6 +161,21 @@ authelia_config_session_secret: ~
authelia_config_session_expiration: 1h
authelia_config_session_inactivity: 5m
authelia_config_session_remember_me_duration: 1M
authelia_config_session_remember_me: >-2
{{ authelia_config_session_remember_me_duration }}
authelia_config_session_cookies:
- "{{ authelia_config_session_cookies_default }}"
authelia_config_session_cookies_default_domain: >-2
{{ authelia_config_session_domain }}
authelia_config_session_cookies_default_authelia_url: >-2
https://{{ authelia_config_session_cookies_default_domain }}
authelia_config_session_cookies_default_default_redirection_url: >-2
{{ authelia_config_default_redirection_url }}
authelia_config_session_cookies_default:
domain: "{{ authelia_config_session_cookies_default_domain }}"
authelia_url: "{{ authelia_config_session_cookies_default_authelia_url }}"
default_redirection_url: >-2
{{ authelia_config_session_cookies_default_default_redirection_url }}
authelia_config_session_redis_host: "{{ authelia_redis_host }}"
authelia_config_session_redis_port: "{{ authelia_redis_port }}"
authelia_config_session_redis_username: "{{ authelia_redis_user }}"
@@ -145,23 +200,31 @@ authelia_config_storage_postgres_ssl_certificate: disable
authelia_config_storage_postgres_ssl_key: disable
authelia_config_notifier_disable_startup_check: false
authelia_config_notifier_filesystem_filename: ~
authelia_config_notifier_smtp_host: "{{ authelia_smtp_host }}"
authelia_config_notifier_smtp_port: "{{ authelia_stmp_port }}"
authelia_config_notifier_smtp_address: "{{ authelia_smtp_host }}:{{ authelia_stmp_port }}"
authelia_config_notifier_smtp_username: "{{ authelia_smtp_user }}"
authelia_config_notifier_smtp_password: "{{ authelia_smtp_pass }}"
authelia_config_notifier_smtp_timeout: 5s
authelia_config_notifier_smtp_sender: "Authelia on {{ authelia_domain }} <admin@{{ authelia_domain }}>"
authelia_config_notifier_smtp_identifier: "{{ authelia_domain }}"
authelia_config_notifier_smtp_subject: "[Authelia @ {{ authelia_domain }}] {title}"
authelia_config_notifier_smtp_startup_check_address: false
authelia_config_notifier_smtp_startup_check_address: "authelia-test@{{ authelia_domain }}"
authelia_config_notifier_smtp_disable_require_tls: false
authelia_config_notifier_smtp_disable_html_emails: false
authelia_config_notifier_smtp_tls_skip_verify: false
authelia_config_notifier_smtp_tls_minimum_version: "{{ authelia_tls_minimum_version }}"
#authelia_config_identity_provider_
authelia_config_identity_validation_reset_password_jwt_secret: >-2
{{ authelia_config_jwt_secret }}
authelia_config_identity_validation_reset_password_jwt_lifespan: "5 minutes"
authelia_config_identity_validation_reset_password_jwt_algorithm: "HS256"
authelia_database_type: ~
authelia_database_host: ~
authelia_database_port: ~
authelia_database_address: >-2
{{ authelia_database_host }}{{
(authelia_database_port | default(false, true) | bool)
| ternary(':' + authelia_database_port, '')
}}
authelia_database_user: authelia
authelia_database_pass: ~
authelia_database_name: authelia

View File

@@ -4,5 +4,7 @@
docker_container:
name: "{{ authelia_container_name }}"
state: started
restart: yes
restart: true
comparisons:
'*': ignore
listen: restart-authelia

View File

@@ -0,0 +1,9 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: authelia
description: Ansible role to deploy authelia using docker
galaxy_tags:
- authelia
- docker

View File

@@ -0,0 +1,61 @@
---
- name: Ensure container mounts are present
when: authelia_state == 'present'
block:
- name: Ensure sqlite database file exists before mounting it
ansible.builtin.file:
path: "{{ authelia_sqlite_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_storage_local_path | default(false, true)
- name: Ensure user database exists before mounting it
ansible.builtin.file:
path: "{{ authelia_user_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_authentication_backend_file_path | default(false, true)
- name: Ensure notification reports file exists before mounting it
ansible.builtin.file:
path: "{{ authelia_notification_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_notifier_filesystem_filename | default(false, true)
- name: Ensure authelia container image is {{ authelia_state }}
community.docker.docker_image:
name: "{{ authelia_container_image_ref }}"
state: "{{ authelia_state }}"
source: pull
force_source: "{{ authelia_container_image_force_pull }}"
register: authelia_container_image_info
- name: Ensure authelia container is {{ authelia_container_state }}
community.docker.docker_container:
name: "{{ authelia_container_name }}"
image: "{{ authelia_container_image_ref }}"
env: "{{ authelia_container_env }}"
user: "{{ authelia_run_user }}:{{ authelia_run_group }}"
ports: "{{ authelia_container_ports | default(omit, true) }}"
labels: "{{ authelia_container_labels }}"
volumes: "{{ authelia_container_volumes }}"
networks: "{{ authelia_container_networks | default(omit, true) }}"
etc_hosts: "{{ authelia_container_etc_hosts | default(omit, true) }}"
purge_networks: "{{ authelia_container_purge_networks | default(omit, true)}}"
restart_policy: "{{ authelia_container_restart_policy }}"
recreate: "{{ authelia_container_recreate | default(omit, true) }}"
state: "{{ authelia_container_state }}"
register: authelia_container_info

View File

@@ -1,16 +1,30 @@
---
- name: Check for valid state
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ authelia_state }}'.
Supported states are {{ authelia_states | join(', ') }}.
when: authelia_state not in authelia_states
- name: Ensure user {{ authelia_user }} exists
user:
- name: Check for valid authelia deployment method
ansible.builtin.fail:
msg: >-2
Unsupported deployment method '{{ authelia_deployment_method }}'.
Supported states are {{ authelia_deployment_methods | join(', ') }}.
when: authelia_deployment_method not in authelia_deployment_methods
- name: Ensure user {{ authelia_user }} is {{ authelia_state }}
ansible.builtin.user:
name: "{{ authelia_user }}"
state: present
state: "{{ authelia_state }}"
system: true
create_home: false
register: authelia_user_info
- name: Ensure host directories are created with correct permissions
file:
- name: Ensure host directories are {{ authelia_state }}
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
state: "{{ (authelia_state == 'present') | ternary('directory', 'absent') }}"
owner: "{{ item.owner | default(authelia_user) }}"
group: "{{ item.group | default(authelia_user) }}"
mode: "{{ item.mode | default('0750') }}"
@@ -21,68 +35,19 @@
mode: "0750"
- path: "{{ authelia_data_dir }}"
mode: "0750"
- path: "{{ authelia_asset_dir }}"
mode: "0750"
- name: Ensure config file is generated
copy:
- name: Ensure config file is {{ authelia_state }}
ansible.builtin.copy:
content: "{{ authelia_config | to_nice_yaml(indent=2, width=10000) }}"
dest: "{{ authelia_config_file }}"
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
notify: restart-authelia
when: authelia_state == 'present'
- name: Ensure sqlite database file exists before mounting it
file:
path: "{{ authelia_sqlite_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_storage_local_path | default(false, true)
- name: Ensure user database exists before mounting it
file:
path: "{{ authelia_user_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_authentication_backend_file_path | default(false, true)
- name: Ensure notification reports file exists before mounting it
file:
path: "{{ authelia_notification_storage_file }}"
state: touch
owner: "{{ authelia_run_user }}"
group: "{{ authelia_run_group }}"
mode: "0640"
access_time: preserve
modification_time: preserve
when: authelia_config_notifier_filesystem_filename | default(false, true)
- name: Ensure authelia container image is present
community.docker.docker_image:
name: "{{ authelia_container_image_ref }}"
state: present
source: pull
force_source: "{{ authelia_container_image_force_pull }}"
register: authelia_container_image_info
- name: Ensure authelia container is running
docker_container:
name: "{{ authelia_container_name }}"
image: "{{ authelia_container_image_ref }}"
env: "{{ authelia_container_env }}"
user: "{{ authelia_run_user }}:{{ authelia_run_group }}"
ports: "{{ authelia_container_ports | default(omit, true) }}"
labels: "{{ authelia_container_labels }}"
volumes: "{{ authelia_container_volumes }}"
networks: "{{ authelia_container_networks | default(omit, true) }}"
purge_networks: "{{ authelia_container_purge_networks | default(omit, true)}}"
restart_policy: "{{ authelia_container_restart_policy }}"
state: "{{ authelia_container_state }}"
register: authelia_container_info
- name: Deploy authelia using {{ authelia_deployment_method }}
ansible.builtin.include_tasks:
file: "deploy-{{ authelia_deployment_method }}.yml"

View File

@@ -1,10 +1,16 @@
---
authelia_states:
- "present"
- "absent"
authelia_deployment_methods:
- "docker"
authelia_run_user: "{{ (authelia_user_info.uid) if authelia_user_info is defined else authelia_user }}"
authelia_run_group: "{{ (authelia_user_info.group) if authelia_user_info is defined else authelia_user }}"
authelia_container_base_volumes: >-2
{{ [ authelia_config_file + ":/config/configuration.yml:ro"]
+ ([authelia_asset_dir + '/:' + authelia_config_server_asset_path + ':ro'] if authelia_asset_dir | default(false, true) else [])
+ ([ authelia_sqlite_storage_file + ":" + authelia_config_storage_local_path + ":z" ]
if authelia_config_storage_local_path | default(false, true) else [])
+ ([ authelia_notification_storage_file + ":" + authelia_config_notifier_filesystem_filename + ":z" ]
@@ -19,8 +25,8 @@ authelia_container_base_labels:
authelia_config: "{{ authelia_base_config | combine(authelia_extra_config, recursive=True) }}"
authelia_top_level_config:
theme: "{{ authelia_config_theme }}"
jwt_secret: "{{ authelia_config_jwt_secret }}"
log: "{{ authelia_config_log }}"
telemetry: "{{ authelia_config_telemetry }}"
totp: "{{ authelia_config_totp }}"
webauthn: "{{ authelia_config_webauthn }}"
duo_api: "{{ authelia_config_duo_api }}"
@@ -32,12 +38,11 @@ authelia_top_level_config:
regulation: "{{ authelia_config_regulation }}"
storage: "{{ authelia_config_storage }}"
notifier: "{{ authelia_config_notifier }}"
identity_validation: "{{ authelia_config_identity_validation }}"
authelia_base_config: >-2
{{
authelia_top_level_config
| combine({"default_redirection_url": authelia_config_default_redirection_url}
if authelia_config_default_redirection_url | default(false, true) else {})
| combine(({"server": authelia_config_server })
| combine({"tls": authelia_config_server_tls}
if authelia_config_server_tls_key | default(false, true) else {}))
@@ -46,17 +51,20 @@ authelia_base_config: >-2
authelia_config_server: >-2
{{
{
"host": authelia_config_server_host,
"port": authelia_config_server_port,
"path": authelia_config_server_path,
"read_buffer_size": authelia_config_server_read_buffer_size,
"write_buffer_size": authelia_config_server_write_buffer_size,
"enable_pprof": authelia_config_server_enable_pprof,
"enable_expvars": authelia_config_server_enable_expvars,
"address": authelia_config_server_address,
"asset_path": authelia_config_server_asset_path,
"disable_healthcheck": authelia_config_server_disable_healthcheck,
"endpoints": authelia_config_server_endpoints,
"buffers": authelia_config_server_buffers,
} | combine({"headers": {"csp_template": authelia_config_server_headers_csp_template}}
if authelia_config_server_headers_csp_template | default(false, true) else {})
}}
authelia_config_server_endpoints:
enable_expvars: "{{ authelia_config_server_endpoints_enable_expvars }}"
enable_pprof: "{{ authelia_config_server_endpoints_enable_pprof }}"
authelia_config_server_buffers:
read: "{{ authelia_config_server_buffers_read }}"
write: "{{ authelia_config_server_buffers_write }}"
authelia_config_server_tls:
key: "{{ authelia_config_server_tls_key }}"
certificate: "{{ authelia_config_server_tls_certificate }}"
@@ -72,6 +80,10 @@ authelia_config_log: >-2
| combine({"keep_stdout": authelia_config_log_keep_stdout}
if authelia_config_log_file_path | default(false, true) else {})
}}
authelia_config_telemetry:
metrics:
enabled: "{{ authelia_config_telemetry_metrics_enabled }}"
address: "{{ authelia_config_telemetry_metrics_address }}"
authelia_config_totp:
disable: "{{ authelia_config_totp_disable }}"
issuer: "{{ authelia_config_totp_issuer }}"
@@ -85,7 +97,10 @@ authelia_config_webauthn:
timeout: "{{ authelia_config_webauthn_timeout }}"
display_name: "{{ authelia_config_webauthn_display_name }}"
attestation_conveyance_preference: "{{ authelia_config_webauthn_attestation_conveyance_preference }}"
user_verification: "{{ authelia_config_webauthn_user_verification }}"
selection_criteria:
attachment: "{{ authelia_config_webauthn_selection_criteria_attachment }}"
discoverability: "{{ authelia_config_webauthn_selection_criteria_discoverability }}"
user_verification: "{{ authelia_config_webauthn_selection_criteria_user_verification }}"
authelia_config_duo_api:
hostname: "{{ authelia_config_duo_api_hostname }}"
integration_key: "{{ authelia_config_duo_api_integration_key }}"
@@ -101,7 +116,6 @@ authelia_config_ntp:
authelia_config_authentication_backend: >-2
{{
{
"disable_reset_password": authelia_config_authentication_backend_disable_reset_password,
"refresh_interval": authelia_config_authentication_backend_refresh_interval,
}
| combine({"password_reset": authelia_config_authentication_backend_password_reset}
@@ -112,9 +126,10 @@ authelia_config_authentication_backend: >-2
}}
authelia_config_authentication_backend_password_reset:
custom_url: "{{ authelia_config_authentication_backend_password_reset_custom_url }}"
disable: "{{ authelia_config_authentication_backend_password_reset_disable }}"
authelia_config_authentication_backend_ldap:
implementation: "{{ authelia_config_authentication_backend_ldap_implementation }}"
url: "{{ authelia_config_authentication_backend_ldap_url }}"
address: "{{ authelia_config_authentication_backend_ldap_address }}"
timeout: "{{ authelia_config_authentication_backend_ldap_timeout }}"
start_tls: "{{ authelia_config_authentication_backend_ldap_start_tls }}"
tls:
@@ -125,10 +140,11 @@ authelia_config_authentication_backend_ldap:
additional_groups_dn: "{{ authelia_config_authentication_backend_ldap_additional_groups_dn }}"
users_filter: "{{ authelia_config_authentication_backend_ldap_users_filter }}"
groups_filter: "{{ authelia_config_authentication_backend_ldap_groups_filter }}"
group_name_attribute: "{{ authelia_config_authentication_backend_ldap_group_name_attribute }}"
username_attribute: "{{ authelia_config_authentication_backend_ldap_username_attribute }}"
mail_attribute: "{{ authelia_config_authentication_backend_ldap_mail_attribute }}"
display_name_attribute: "{{ authelia_config_authentication_backend_ldap_display_name_attribute }}"
attributes:
username: "{{ authelia_config_authentication_backend_ldap_attributes_username }}"
mail: "{{ authelia_config_authentication_backend_ldap_attributes_mail }}"
display_name: "{{ authelia_config_authentication_backend_ldap_attributes_display_name }}"
group_name: "{{ authelia_config_authentication_backend_ldap_attributes_group_name }}"
user: "{{ authelia_config_authentication_backend_ldap_user }}"
password: "{{ authelia_config_authentication_backend_ldap_password }}"
authelia_config_authentication_backend_file:
@@ -160,14 +176,19 @@ authelia_config_access_control:
default_policy: "{{ authelia_config_access_control_default_policy }}"
networks: "{{ authelia_config_access_control_networks }}"
rules: "{{ authelia_config_access_control_rules }}"
authelia_config_session:
authelia_config_session: >-2
{{ authelia_config_session_base
| combine(({'redis': authelia_config_session_redis}
if authelia_config_session_redis_host else {}), recursive=true)
}}
authelia_config_session_base:
name: "{{ authelia_config_session_name }}"
domain: "{{ authelia_config_session_domain }}"
same_site: "{{ authelia_config_session_same_site }}"
secret: "{{ authelia_config_session_secret }}"
expiration: "{{ authelia_config_session_expiration }}"
inactivity: "{{ authelia_config_session_inactivity }}"
remember_me_duration: "{{ authelia_config_session_remember_me_duration }}"
remember_me: "{{ authelia_config_session_remember_me }}"
cookies: "{{ authelia_config_session_cookies }}"
authelia_config_session_redis: >-2
{{
{
@@ -211,15 +232,13 @@ authelia_config_storage: >-2
authelia_config_storage_local:
path: "{{ authelia_config_storage_local_path }}"
authelia_config_storage_mysql:
host: "{{ authelia_database_host }}"
port: "{{ authelia_config_storage_mysql_port }}"
host: "{{ authelia_database_address }}"
database: "{{ authelia_database_name }}"
username: "{{ authelia_database_user }}"
password: "{{ authelia_database_pass }}"
timeout: "{{ authelia_database_timeout }}"
authelia_config_storage_postgres:
host: "{{ authelia_database_host }}"
port: "{{ authelia_config_storage_postgres_port }}"
address: "{{ authelia_database_address }}"
database: "{{ authelia_database_name }}"
schema: public
username: "{{ authelia_database_user }}"
@@ -243,8 +262,7 @@ authelia_config_notifier: >-2
authelia_config_notifier_filesystem:
filename: "{{ authelia_config_notifier_filesystem_filename }}"
authelia_config_notifier_smtp:
host: "{{ authelia_config_notifier_smtp_host }}"
port: "{{ authelia_config_notifier_smtp_port }}"
address: "{{ authelia_config_notifier_smtp_address }}"
timeout: "{{ authelia_config_notifier_smtp_timeout }}"
username: "{{ authelia_config_notifier_smtp_username }}"
password: "{{ authelia_config_notifier_smtp_password }}"
@@ -257,3 +275,9 @@ authelia_config_notifier_smtp:
tls:
skip_verify: "{{ authelia_config_notifier_smtp_tls_skip_verify }}"
minimum_version: "{{ authelia_config_notifier_smtp_tls_minimum_version }}"
authelia_config_identity_validation:
reset_password: "{{ authelia_config_identity_validation_reset_password }}"
authelia_config_identity_validation_reset_password:
jwt_secret: "{{ authelia_config_identity_validation_reset_password_jwt_secret }}"
jwt_lifespan: "{{ authelia_config_identity_validation_reset_password_jwt_lifespan }}"
jwt_algorithm: "{{ authelia_config_identity_validation_reset_password_jwt_algorithm }}"

18
roles/ghost/README.md Normal file
View File

@@ -0,0 +1,18 @@
# `finallycoffee.services.ghost` ansible role
[Ghost](https://ghost.org/) is a self-hosted blog with rich media capabilities,
which this role deploys in a docker container.
## Requirements
Ghost requires a MySQL-database (like mariadb) for storing it's data, which
can be configured using the `ghost_database_(host|username|password|database)` variables.
Setting `ghost_domain` to a fully-qualified domain on which ghost should be reachable
is also required.
Ghosts configuration can be changed using the `ghost_config` variable.
Container arguments which are equivalent to `community.docker.docker_container` can be
provided in the `ghost_container_[...]` syntax (e.g. `ghost_container_ports` to expose
ghosts port to the host).

View File

@@ -0,0 +1,38 @@
---
ghost_domain: ~
ghost_version: "6.21.0"
ghost_user: ghost
ghost_user_group: ghost
ghost_base_path: /opt/ghost
ghost_data_path: "{{ ghost_base_path }}/data"
ghost_config_path: "{{ ghost_base_path }}/config"
ghost_config_file: "{{ ghost_config_path }}/ghost.env"
ghost_database_username: ghost
ghost_database_password: ~
ghost_database_database: ghost
ghost_database_host: ~
ghost_base_config:
url: "https://{{ ghost_domain }}"
database__client: mysql
database__connection__host: "{{ ghost_database_host }}"
database__connection__user: "{{ ghost_database_username }}"
database__connection__password: "{{ ghost_database_password }}"
database__connection__database: "{{ ghost_database_database }}"
ghost_config: {}
ghost_container_name: ghost
ghost_container_image_name: docker.io/ghost
ghost_container_image_tag: ~
ghost_container_base_volumes:
- "{{ ghost_data_path }}:{{ ghost_container_data_directory }}:rw"
ghost_container_extra_volumes: []
ghost_container_volumes:
"{{ ghost_container_base_volumes + ghost_container_extra_volumes }}"
ghost_container_base_labels:
version: "{{ ghost_version }}"
ghost_container_extra_labels: {}
ghost_container_restart_policy: "unless-stopped"
ghost_container_networks: ~
ghost_container_purge_networks: ~
ghost_container_etc_hosts: ~
ghost_container_state: started

10
roles/ghost/meta/main.yml Normal file
View File

@@ -0,0 +1,10 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: ghost
description: Ansible role to deploy ghost (https://ghost.org) using docker
galaxy_tags:
- ghost
- blog
- docker

View File

@@ -0,0 +1,57 @@
---
- name: Ensure ghost group is created
ansible.builtin.group:
name: "{{ ghost_user_group }}"
state: present
system: true
- name: Ensure ghost user is created
ansible.builtin.user:
name: "{{ ghost_user }}"
groups:
- "{{ ghost_user_group }}"
append: true
state: present
system: true
- name: Ensure host paths for docker volumes exist for ghost
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
mode: "0750"
owner: "{{ item.owner | default(ghost_user) }}"
group: "{{ item.group | default(ghost_user_group) }}"
loop:
- path: "{{ ghost_base_path }}"
- path: "{{ ghost_data_path }}"
owner: "1000"
- path: "{{ ghost_config_path }}"
- name: Ensure ghost configuration file is templated
ansible.builtin.template:
src: "ghost.env.j2"
dest: "{{ ghost_config_file }}"
owner: "{{ ghost_user }}"
group: "{{ ghost_user_group }}"
mode: "0644"
- name: Ensure ghost container image is present on host
community.docker.docker_image:
name: "{{ ghost_container_image }}"
state: present
source: pull
force_source: "{{ ghost_container_image_tag is defined }}"
- name: Ensure ghost container '{{ ghost_container_name }}' is {{ ghost_container_state }}
community.docker.docker_container:
name: "{{ ghost_container_name }}"
image: "{{ ghost_container_image }}"
ports: "{{ ghost_container_ports | default(omit, true) }}"
labels: "{{ ghost_container_labels }}"
volumes: "{{ ghost_container_volumes }}"
env_file: "{{ ghost_config_file }}"
etc_hosts: "{{ ghost_container_etc_hosts | default(omit, true) }}"
networks: "{{ ghost_container_networks | default(omit, true) }}"
purge_networks: "{{ ghost_container_purge_networks | default(omit, true) }}"
restart_policy: "{{ ghost_container_restart_policy }}"
state: "{{ ghost_container_state }}"

View File

@@ -0,0 +1,3 @@
{% for key, value in ghost_config_complete.items() %}
{{ key }}={{ value }}
{% endfor %}

10
roles/ghost/vars/main.yml Normal file
View File

@@ -0,0 +1,10 @@
---
ghost_container_image: "{{ ghost_container_image_name}}:{{ ghost_container_image_tag | default(ghost_version, true) }}"
ghost_container_labels: >-2
{{ ghost_container_base_labels
| combine(ghost_container_extra_labels) }}
ghost_container_data_directory: "/var/lib/ghost/content"
ghost_config_complete: >-2
{{ ghost_base_config | combine(ghost_config, recursive=True) }}

View File

@@ -1,7 +1,7 @@
---
gitea_version: "1.16.4"
gitea_version: "1.25.5"
gitea_user: git
gitea_run_user: "{{ gitea_user }}"
gitea_base_path: "/opt/gitea"
gitea_data_path: "{{ gitea_base_path }}/data"
@@ -9,17 +9,30 @@ gitea_data_path: "{{ gitea_base_path }}/data"
gitea_domain: ~
# container config
gitea_container_name: "git"
gitea_container_image_name: "docker.io/gitea/gitea"
gitea_container_name: "{{ gitea_user }}"
gitea_container_image_server: "docker.io"
gitea_container_image_name: "gitea"
gitea_container_image_namespace: gitea
gitea_container_image_fq_name: >-
{{
[
gitea_container_image_server,
gitea_container_image_namespace,
gitea_container_image_name
] | join('/')
}}
gitea_container_image_tag: "{{ gitea_version }}"
gitea_container_image: "{{ gitea_container_image_name }}:{{ gitea_container_image_tag }}"
gitea_container_image: >-2
{{ gitea_container_image_fq_name }}:{{ gitea_container_image_tag }}
gitea_container_networks: []
gitea_container_purge_networks: ~
gitea_container_restart_policy: "unless-stopped"
gitea_container_extra_env: {}
gitea_contianer_extra_labels: {}
gitea_container_extra_labels: {}
gitea_container_extra_ports: []
gitea_container_extra_volumes: []
gitea_container_state: started
gitea_container_user: ~
# container defaults
gitea_container_base_volumes:
@@ -31,8 +44,8 @@ gitea_container_base_ports:
- "127.0.0.1:{{ git_container_port_ssh }}:{{ git_container_port_ssh }}"
gitea_container_base_env:
USER_UID: "{{ gitea_user_res.uid | default(gitea_user) }}"
USER_GID: "{{ gitea_user_res.group | default(gitea_user) }}"
USER_UID: "{{ gitea_user_res.uid | default(gitea_user) | string }}"
USER_GID: "{{ gitea_user_res.group | default(gitea_user) | string }}"
gitea_container_base_labels:
version: "{{ gitea_version }}"
@@ -40,10 +53,10 @@ gitea_container_base_labels:
gitea_config_mailer_enabled: false
gitea_config_mailer_type: ~
gitea_config_mailer_from_addr: ~
gitea_config_mailer_host: ~
gitea_config_mailer_smtp_addr: ~
gitea_config_mailer_user: ~
gitea_config_mailer_passwd: ~
gitea_config_mailer_tls: ~
gitea_config_mailer_protocol: ~
gitea_config_mailer_sendmail_path: ~
gitea_config_metrics_enabled: false

10
roles/gitea/meta/main.yml Normal file
View File

@@ -0,0 +1,10 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: gitea
description: Ansible role to deploy gitea using docker
galaxy_tags:
- gitea
- git
- docker

View File

@@ -1,14 +1,14 @@
---
- name: Create gitea user
user:
- name: Ensure gitea user '{{ gitea_user }}' is present
ansible.builtin.user:
name: "{{ gitea_user }}"
state: present
system: no
state: "present"
system: false
create_home: true
register: gitea_user_res
- name: Ensure host directories exist
file:
ansible.builtin.file:
path: "{{ item }}"
owner: "{{ gitea_user_res.uid }}"
group: "{{ gitea_user_res.group }}"
@@ -18,7 +18,7 @@
- "{{ gitea_data_path }}"
- name: Ensure .ssh folder for gitea user exists
file:
ansible.builtin.file:
path: "/home/{{ gitea_user }}/.ssh"
state: directory
owner: "{{ gitea_user_res.uid }}"
@@ -37,16 +37,16 @@
register: gitea_user_ssh_key
- name: Create forwarding script
copy:
ansible.builtin.copy:
dest: "/usr/local/bin/gitea"
owner: "{{ gitea_user_res.uid }}"
group: "{{ gitea_user_res.group }}"
mode: 0700
content: |
ssh -p {{ gitea_public_ssh_server_port }} -o StrictHostKeyChecking=no {{ gitea_user }}@127.0.0.1 -i /home/{{ gitea_user }}/.ssh/id_ssh_ed25519 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
ssh -p {{ gitea_public_ssh_server_port }} -o StrictHostKeyChecking=no {{ gitea_run_user }}@127.0.0.1 -i /home/{{ gitea_user }}/.ssh/id_ssh_ed25519 "SSH_ORIGINAL_COMMAND=\"$SSH_ORIGINAL_COMMAND\" $0 $@"
- name: Add host pubkey to git users authorized_keys file
lineinfile:
ansible.builtin.lineinfile:
path: "/home/{{ gitea_user }}/.ssh/authorized_keys"
line: "{{ gitea_user_ssh_key.public_key }} Gitea:Host2Container"
state: present
@@ -56,26 +56,28 @@
mode: 0600
- name: Ensure gitea container image is present
docker_image:
community.docker.docker_image:
name: "{{ gitea_container_image }}"
state: present
source: pull
force_source: "{{ gitea_container_image.endswith(':latest') }}"
- name: Ensure container '{{ gitea_container_name }}' with gitea is running
docker_container:
- name: Ensure container '{{ gitea_container_name }}' with gitea is {{ gitea_container_state }}
community.docker.docker_container:
name: "{{ gitea_container_name }}"
image: "{{ gitea_container_image }}"
env: "{{ gitea_container_env }}"
labels: "{{ gitea_container_labels }}"
volumes: "{{ gitea_container_volumes }}"
networks: "{{ gitea_container_networks | default(omit, True) }}"
purge_networks: "{{ gitea_container_purge_networks | default(omit, True) }}"
published_ports: "{{ gitea_container_ports }}"
restart_policy: "{{ gitea_container_restart_policy }}"
state: started
state: "{{ gitea_container_state }}"
user: "{{ gitea_container_user | default(omit, true) }}"
- name: Ensure given configuration is set in the config file
ini_file:
ansible.builtin.ini_file:
path: "{{ gitea_data_path }}/gitea/conf/app.ini"
section: "{{ section }}"
option: "{{ option }}"

View File

@@ -14,7 +14,7 @@ gitea_container_port_ssh: 22
gitea_config_base:
RUN_MODE: prod
RUN_USER: "{{ gitea_user }}"
RUN_USER: "{{ gitea_run_user }}"
server:
SSH_DOMAIN: "{{ gitea_domain }}"
DOMAIN: "{{ gitea_domain }}"
@@ -24,11 +24,11 @@ gitea_config_base:
mailer:
ENABLED: "{{ gitea_config_mailer_enabled }}"
MAILER_TYP: "{{ gitea_config_mailer_type }}"
HOST: "{{ gitea_config_mailer_host }}"
SMTP_ADDR: "{{ gitea_config_mailer_smtp_addr }}"
USER: "{{ gitea_config_mailer_user }}"
PASSWD: "{{ gitea_config_mailer_passwd }}"
IS_TLS_ENABLED: "{{ gitea_config_mailer_tls }}"
FROM: "{{ gitea_config_mailer_from_addr }}"
PROTOCOL: "{{ gitea_config_mailer_protocol }}"
FROM: "{{ gitea_config_mailer_from }}"
SENDMAIL_PATH: "{{ gitea_config_mailer_sendmail_path }}"
metrics:
ENABLED: "{{ gitea_config_metrics_enabled }}"

21
roles/hedgedoc/README.md Normal file
View File

@@ -0,0 +1,21 @@
# `finallycoffee.services.hedgedoc` ansible role
Role to deploy and configure hedgedoc using `docker` or `podman`.
To configure hedgedoc, set either the config as complex data
directly in `hedgedoc_config` or use the flattened variables
from the `hedgedoc_config_*` prefix (see
[defaults/main/config.yml](defaults/main/config.yml)).
To remove hedgedoc, set `hedgedoc_state: absent`. Note that this
will delete all data directories aswell, removing any traces this
role created on the target (except database contents).
# Required configuration
- `hedgedoc_config_domain` - Domain of the hedgedoc instance
- `hedgedoc_config_session_secret` - session secret for hedgedoc
## Deployment methods
To set the desired deployment method, set `hedgedoc_deployment_method` to a
supported deployment methods (see [vars/main.yml](vars/main.yml#5)).

View File

@@ -0,0 +1,52 @@
---
hedgedoc_config_domain: ~
hedgedoc_config_log_level: "info"
hedgedoc_config_session_secret: ~
hedgedoc_config_protocol_use_ssl: true
hedgedoc_config_hsts_enable: true
hedgedoc_config_csp_enable: true
hedgedoc_config_cookie_policy: 'lax'
hedgedoc_config_allow_free_url: true
hedgedoc_config_allow_email_register: false
hedgedoc_config_allow_anonymous: true
hedgedoc_config_allow_gravatar: true
hedgedoc_config_require_free_url_authentication: true
hedgedoc_config_default_permission: 'full'
hedgedoc_config_db_username: hedgedoc
hedgedoc_config_db_password: ~
hedgedoc_config_db_database: hedgedoc
hedgedoc_config_db_host: localhost
hedgedoc_config_db_port: 5432
hedgedoc_config_db_dialect: postgres
hedgedoc_config_database:
username: "{{ hedgedoc_config_db_username }}"
password: "{{ hedgedoc_config_db_password }}"
database: "{{ hedgedoc_config_db_database }}"
host: "{{ hedgedoc_config_db_host }}"
port: "{{ hedgedoc_config_db_port | int }}"
dialect: "{{ hedgedoc_config_db_dialect }}"
hedgedoc_config_base:
production:
domain: "{{ hedgedoc_config_domain }}"
loglevel: "{{ hedgedoc_config_log_level }}"
sessionSecret: "{{ hedgedoc_config_session_secret }}"
protocolUseSSL: "{{ hedgedoc_config_protocol_use_ssl }}"
cookiePolicy: "{{ hedgedoc_config_cookie_policy }}"
allowFreeURL: "{{ hedgedoc_config_allow_free_url }}"
allowAnonymous: "{{ hedgedoc_config_allow_anonymous }}"
allowEmailRegister: "{{ hedgedoc_config_allow_email_register }}"
allowGravatar: "{{ hedgedoc_config_allow_gravatar }}"
requireFreeURLAuthentication: >-2
{{ hedgedoc_config_require_free_url_authentication }}
defaultPermission: "{{ hedgedoc_config_default_permission }}"
hsts:
enable: "{{ hedgedoc_config_hsts_enable }}"
csp:
enable: "{{ hedgedoc_config_csp_enable }}"
db: "{{ hedgedoc_config_database }}"
hedgedoc_config: ~
hedgedoc_full_config: >-2
{{ hedgedoc_config_base | default({}, true)
| combine(hedgedoc_config | default({}, true), recursive=True) }}

View File

@@ -0,0 +1,57 @@
---
hedgedoc_container_image_registry: quay.io
hedgedoc_container_image_namespace: hedgedoc
hedgedoc_container_image_name: hedgedoc
hedgedoc_container_image_flavour: alpine
hedgedoc_container_image_tag: ~
hedgedoc_container_image: >-2
{{
([
hedgedoc_container_image_registry,
hedgedoc_container_image_namespace | default([], true),
hedgedoc_container_image_name,
] | flatten | join('/'))
+ ':'
+ hedgedoc_container_image_tag | default(
hedgedoc_version + (
((hedgedoc_container_image_flavour is string)
and (hedgedoc_container_image_flavour | length > 0))
| ternary('-' +
hedgedoc_container_image_flavour | default('', true),
''
)
),
true
)
}}
hedgedoc_container_image_source: pull
hedgedoc_container_name: hedgedoc
hedgedoc_container_state: >-2
{{ (hedgedoc_state == 'present') | ternary('started', 'absent') }}
hedgedoc_container_config_file: "/hedgedoc/config.json"
hedgedoc_container_upload_path: "/hedgedoc/public/uploads"
hedgedoc_container_env: ~
hedgedoc_container_user: >-2
{{ hedgedoc_run_user_id }}:{{ hedgedoc_run_group_id }}
hedgedoc_container_ports: ~
hedgedoc_container_networks: ~
hedgedoc_container_etc_hosts: ~
hedgedoc_container_base_volumes:
- "{{ hedgedoc_config_file }}:{{ hedgedoc_container_config_file }}:ro"
- "{{ hedgedoc_uploads_path }}:{{ hedgedoc_container_upload_path }}:rw"
hedgedoc_container_volumes: ~
hedgedoc_container_all_volumes: >-2
{{ hedgedoc_container_base_volumes | default([], true)
+ hedgedoc_container_volumes | default([], true) }}
hedgedoc_container_base_labels:
version: "{{ hedgedoc_container_tag | default(hedgedoc_version, true) }}"
hedgedoc_container_labels: ~
hedgedoc_container_network_mode: ~
hedgedoc_container_all_labels: >-2
{{ hedgedoc_container_base_labels | default({}, true)
| combine(hedgedoc_container_labels | default({}, true)) }}
hedgedoc_container_restart_policy: >-2
{{ (hedgedoc_deployment_method == 'docker')
| ternary('unless-stopped', 'on-failure') }}

View File

@@ -0,0 +1,9 @@
---
hedgedoc_user: hedgedoc
hedgedoc_version: "1.10.7"
hedgedoc_state: present
hedgedoc_deployment_method: docker
hedgedoc_config_file: "/etc/hedgedoc/config.json"
hedgedoc_uploads_path: "/var/lib/hedgedoc-uploads"

View File

@@ -0,0 +1,5 @@
---
hedgedoc_run_user_id: >-2
{{ hedgedoc_user_info.uid | default(hedgedoc_user) }}
hedgedoc_run_group_id: >-2
{{ hedgedoc_user_info.group | default(hedgedoc_user) }}

View File

@@ -0,0 +1,12 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: hedgedoc
description: >-2
Deploy hedgedoc, a collaborative markdown editor, using docker
galaxy_tags:
- hedgedoc
- markdown
- collaboration
- docker

View File

@@ -0,0 +1,23 @@
---
- name: Check for valid state
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ hedgedoc_state }}'. Supported
states are {{ hedgedoc_states | join(', ') }}.
when: hedgedoc_state not in hedgedoc_states
- name: Check for valid deployment method
ansible.builtin.fail:
msg: >-2
Deployment method '{{ hedgedoc_deployment_method }}'
is not supported. Supported are:
{{ hedgedoc_deployment_methods | join(', ') }}
when: hedgedoc_deployment_method not in hedgedoc_deployment_methods
- name: Ensure required variables are given
ansible.builtin.fail:
msg: "Required variable '{{ item }}' is undefined!"
loop: "{{ hedgedoc_required_arguments }}"
when: >-2
item not in hostvars[inventory_hostname]
or hostvars[inventory_hostname][item] | length == 0

View File

@@ -0,0 +1,31 @@
---
- name: Ensure container image '{{ hedgedoc_container_image }}' is {{ hedgedoc_state }}
community.docker.docker_image:
name: "{{ hedgedoc_container_image }}"
state: "{{ hedgedoc_state }}"
source: "{{ hedgedoc_container_image_source }}"
force_source: >-2
{{ hedgedoc_container_force_source | default(
hedgedoc_container_image_tag | default(false, true), true) }}
register: hedgedoc_container_image_info
until: hedgedoc_container_image_info is success
retries: 5
delay: 3
- name: Ensure container '{{ hedgedoc_container_name }}' is {{ hedgedoc_container_state }}
community.docker.docker_container:
name: "{{ hedgedoc_container_name }}"
image: "{{ hedgedoc_container_image }}"
env: "{{ hedgedoc_container_env | default(omit, true) }}"
user: "{{ hedgedoc_container_user | default(omit, true) }}"
ports: "{{ hedgedoc_container_ports | default(omit, true) }}"
labels: "{{ hedgedoc_container_all_labels }}"
volumes: "{{ hedgedoc_container_all_volumes }}"
etc_hosts: "{{ hedgedoc_container_etc_hosts | default(omit, true) }}"
dns_servers: >-2
{{ hedgedoc_container_dns_servers | default(omit, true) }}
network_mode: >-2
{{ hedgedoc_container_network_mode | default(omit, true) }}
restart_policy: >-2
{{ hedgedoc_container_restart_policy | default(omit, true) }}
state: "{{ hedgedoc_container_state }}"

View File

@@ -0,0 +1,31 @@
---
- name: Ensure container image '{{ hedgedoc_container_image }}' is {{ hedgedoc_state }}
containers.podman.podman_image:
name: "{{ hedgedoc_container_image }}"
state: "{{ hedgedoc_state }}"
pull: "{{ (hedgedoc_container_image_source == 'pull') | bool }}"
force: >-2
{{ hedgedoc_container_force_source | default(
hedgedoc_container_image_tag | default(false, true), true) }}
register: hedgedoc_container_image_info
until: hedgedoc_container_image_info is success
retries: 5
delay: 3
- name: Ensure container '{{ hedgedoc_container_name }}' is {{ hedgedoc_container_state }}
containers.podman.podman_container:
name: "{{ hedgedoc_container_name }}"
image: "{{ hedgedoc_container_image }}"
env: "{{ hedgedoc_container_env | default(omit, true) }}"
user: "{{ hedgedoc_container_user | default(omit, true) }}"
ports: "{{ hedgedoc_container_ports | default(omit, true) }}"
labels: "{{ hedgedoc_container_all_labels }}"
volumes: "{{ hedgedoc_container_all_volumes }}"
etc_hosts: "{{ hedgedoc_container_etc_hosts | default(omit, true) }}"
dns_servers: >-2
{{ hedgedoc_container_dns_servers | default(omit, true) }}
network_mode: >-2
{{ hedgedoc_container_network_mode | default(omit, true) }}
restart_policy: >-2
{{ hedgedoc_container_restart_policy | default(omit, true) }}
state: "{{ hedgedoc_container_state }}"

View File

@@ -0,0 +1,21 @@
---
- name: Check preconditions
ansible.builtin.include_tasks:
file: "check.yml"
- name: Ensure user '{{ hedgedoc_user }}' is {{ hedgedoc_state }}
ansible.builtin.user:
name: "{{ hedgedoc_user }}"
state: "{{ hedgedoc_state }}"
system: "{{ hedgedoc_user_system | default(true, false) }}"
register: hedgedoc_user_info
- name: Ensure configuration file '{{ hedgedoc_config_file }}' is {{ hedgedoc_state }}
ansible.builtin.copy:
dest: "{{ hedgedoc_config_file }}"
content: "{{ hedgedoc_full_config | to_nice_json }}"
when: hedgedoc_state == 'present'
- name: Ensure hedgedoc is deployed using {{ hedgedoc_deployment_method }}
ansible.builtin.include_tasks:
file: "deploy-{{ hedgedoc_deployment_method }}.yml"

View File

@@ -0,0 +1,11 @@
---
hedgedoc_states:
- present
- absent
hedgedoc_deployment_methods:
- docker
- podman
hedgedoc_required_arguments:
- hedgedoc_config_domain
- hedgedoc_config_session_secret

15
roles/jellyfin/README.md Normal file
View File

@@ -0,0 +1,15 @@
# `finallycoffee.services.jellyfin` ansible role
This role runs [Jellyfin](https://jellyfin.org/), a free software media system,
in a docker container.
## Usage
`jellyfin_domain` contains the FQDN which jellyfin should listen to. Most configuration
is done in the software itself.
Jellyfin runs in host networking mode by default, as that is needed for some features like
network discovery with chromecasts and similar.
Media can be mounted into jellyfin using `jellyfin_media_volumes`, taking a list of strings
akin to `community.docker.docker_container`'s `volumes` key.

View File

@@ -1,6 +1,8 @@
---
jellyfin_user: jellyfin
jellyfin_version: "10.11.6"
jellyfin_state: present
jellyfin_deployment_method: docker
jellyfin_base_path: /opt/jellyfin
jellyfin_config_path: "{{ jellyfin_base_path }}/config"
@@ -10,11 +12,17 @@ jellyfin_media_volumes: []
jellyfin_container_name: jellyfin
jellyfin_container_image_name: "docker.io/jellyfin/jellyfin"
jellyfin_container_image_tag: "latest"
jellyfin_container_image_ref: "{{ jellyfin_container_image_name }}:{{ jellyfin_container_image_tag }}"
jellyfin_container_image_tag: ~
jellyfin_container_image_ref: >-2
{{ jellyfin_container_image_name }}:{{ jellyfin_container_image_tag | default(jellyfin_version, true) }}
jellyfin_container_image_source: pull
jellyfin_container_state: >-2
{{ (jellyfin_state == 'present') | ternary('started', 'absent') }}
jellyfin_container_network_mode: host
jellyfin_container_networks: ~
jellyfin_container_volumes: "{{ jellyfin_container_base_volumes + jellyfin_media_volumes }}"
jellyfin_container_labels: "{{ jellyfin_container_base_labels | combine(jellyfin_container_extra_labels) }}"
jellyfin_container_extra_labels: {}
jellyfin_container_restart_policy: "unless-stopped"
jellyfin_host_directories:

View File

@@ -0,0 +1,10 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: jellyfin
description: Ansible role to deploy jellyfin using docker
galaxy_tags:
- jellyfin
- streaming
- docker

View File

@@ -0,0 +1,26 @@
---
- name: Ensure container image '{{ jellyfin_container_image_ref }}' is {{ jellyfin_state }}
community.docker.docker_image:
name: "{{ jellyfin_container_image_ref }}"
state: "{{ jellyfin_state }}"
source: "{{ jellyfin_container_image_source }}"
force_source: "{{ jellyfin_container_image_tag | default(false, true) }}"
register: jellyfin_container_image_pull_result
until: jellyfin_container_image_pull_result is succeeded
retries: 5
delay: 3
- name: Ensure container '{{ jellyfin_container_name }}' is {{ jellyfin_container_state }}
community.docker.docker_container:
name: "{{ jellyfin_container_name }}"
image: "{{ jellyfin_container_image_ref }}"
env: "{{ jellyfin_container_env | default(omit, true) }}"
user: "{{ jellyfin_uid }}:{{ jellyfin_gid }}"
labels: "{{ jellyfin_container_labels }}"
volumes: "{{ jellyfin_container_volumes }}"
ports: "{{ jellyfin_container_ports | default(omit, true) }}"
networks: "{{ jellyfin_container_networks | default(omit, true) }}"
network_mode: "{{ jellyfin_container_network_mode }}"
etc_hosts: "{{ jellyfin_container_etc_hosts | default(omit, true) }}"
restart_policy: "{{ jellyfin_container_restart_policy }}"
state: "{{ jellyfin_container_state }}"

View File

@@ -0,0 +1,22 @@
---
- name: Ensure container image '{{ jellyfin_container_image_ref }}' is {{ jellyfin_state }}
containers.podman.podman_image:
name: "{{ jellyfin_container_image_ref }}"
state: "{{ jellyfin_state }}"
pull: "{{ (jellyfin_container_image_source == 'pull') | bool }}"
force: "{{ jellyfin_container_image_tag | default(false, true) }}"
register: jellyfin_container_image_pull_result
until: jellyfin_container_image_pull_result is succeeded
retries: 5
delay: 3
- name: Ensure container '{{ jellyfin_container_name }}' is {{ jellyfin_container_state }}
containers.podman.podman_container:
name: "{{ jellyfin_container_name }}"
image: "{{ jellyfin_container_image_ref }}"
user: "{{ jellyfin_uid }}:{{ jellyfin_gid }}"
labels: "{{ jellyfin_container_labels }}"
volumes: "{{ jellyfin_container_volumes }}"
network: "{{ jellyfin_container_networks | default(omit, True) }}"
restart_policy: "{{ jellyfin_container_restart_policy }}"
state: "{{ jellyfin_container_state }}"

View File

@@ -1,35 +1,35 @@
---
- name: Check if state is valid
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ jellyfin_state }}'. Supported
states are {{ jellyfin_states | join(', ') }}.
when: jellyfin_state not in jellyfin_states
- name: Ensure user '{{ jellyfin_user }}' for jellyfin is created
user:
- name: Check if deployment method is valid
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ jellyfin_deployment_method }}'. Supported
states are {{ jellyfin_deployment_methods | join(', ') }}.
when: jellyfin_deployment_method not in jellyfin_deployment_methods
- name: Ensure jellyfin user '{{ jellyfin_user }}' is {{ jellyfin_state }}
ansible.builtin.user:
name: "{{ jellyfin_user }}"
state: present
system: yes
state: "{{ jellyfin_state }}"
system: "{{ jellyfin_user_system | default(true, true) }}"
register: jellyfin_user_info
- name: Ensure host directories for jellyfin exist
file:
- name: Ensure host directories for jellyfin are {{ jellyfin_state }}
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
state: >-2
{{ (jellyfin_state == 'present') | ternary('directory', 'absent') }}
owner: "{{ item.owner | default(jellyfin_uid) }}"
group: "{{ item.group | default(jellyfin_gid) }}"
mode: "{{ item.mode }}"
loop: "{{ jellyfin_host_directories }}"
- name: Ensure container image for jellyfin is available
docker_image:
name: "{{ jellyfin_container_image_ref }}"
state: present
source: pull
force_source: "{{ jellyfin_container_image_tag in ['stable', 'unstable'] }}"
- name: Ensure container '{{ jellyfin_container_name }}' is running
docker_container:
name: "{{ jellyfin_container_name }}"
image: "{{ jellyfin_container_image_ref }}"
user: "{{ jellyfin_uid }}:{{ jellyfin_gid }}"
volumes: "{{ jellyfin_container_volumes }}"
networks: "{{ jellyfin_container_networks | default(omit, True) }}"
network_mode: "{{ jellyfin_container_network_mode }}"
restart_policy: "{{ jellyfin_container_restart_policy }}"
state: started
- name: Ensure jellyfin is deployed using {{ jellyfin_deployment_method }}
ansible.builtin.include_tasks:
file: "deploy-{{ jellyfin_deployment_method }}.yml"

View File

@@ -1,5 +1,14 @@
---
jellyfin_states:
- present
- absent
jellyfin_deployment_methods:
- docker
- podman
jellyfin_container_base_volumes:
- "{{ jellyfin_config_path }}:/config:z"
- "{{ jellyfin_cache_path }}:/cache:z"
jellyfin_container_base_labels:
version: "{{ jellyfin_version }}"

16
roles/keycloak/README.md Normal file
View File

@@ -0,0 +1,16 @@
# `finallycoffee.services.keycloak` ansible role
Ansible role for deploying keycloak, currently only supports docker.
Migrated from `entropia.sso.keycloak`.
## Required variables
- `keycloak_database_password` - password for the database user
- `keycloak_config_hostname` - public domain of the keycloak server
## Database configuration
- `keycloak_database_hostname` - hostname of the database server, defaults to `localhost`
- `keycloak_database_username` - username to use when connecting to the database server, defaults to `keycloak`
- `keycloak_database_database` - name of the database to use, defaults to `keycloak`

View File

@@ -0,0 +1,51 @@
---
keycloak_version: "26.5.5"
keycloak_container_name: keycloak
keycloak_container_image_upstream_registry: quay.io
keycloak_container_image_upstream_namespace: keycloak
keycloak_container_image_upstream_name: keycloak
keycloak_container_image_upstream: >-2
{{
([
keycloak_container_image_upstream_registry | default([]),
keycloak_container_image_upstream_namespace | default([]),
keycloak_container_image_upstream_name,
] | flatten | join('/'))
}}
keycloak_container_image_name: "keycloak:{{ keycloak_version }}-custom"
keycloak_container_database_vendor: postgres
keycloak_base_path: /opt/keycloak
keycloak_container_build_directory: "{{ keycloak_base_path }}/build"
keycloak_container_build_jar_directory: providers
keycloak_container_build_flags: {}
keycloak_provider_jars_directory: "{{ keycloak_base_path }}/providers"
keycloak_build_provider_jars_directory: "{{ keycloak_container_build_directory }}/{{ keycloak_container_build_jar_directory }}"
keycloak_database_hostname: localhost
keycloak_database_port: 5432
keycloak_database_username: keycloak
keycloak_database_password: ~
keycloak_database_database: keycloak
keycloak_container_env: {}
keycloak_container_labels: ~
keycloak_container_volumes: ~
keycloak_container_restart_policy: unless-stopped
keycloak_container_command: >-2
start
--db-username {{ keycloak_database_username }}
--db-password {{ keycloak_database_password }}
--db-url jdbc:postgresql://{{ keycloak_database_hostname }}{{ keycloak_database_port | ternary(':' ~ keycloak_database_port, '') }}/{{ keycloak_database_database }}
{{ keycloak_container_extra_start_flags | default([]) | join(' ') }}
--proxy-headers xforwarded
--hostname {{ keycloak_config_hostname }}
--optimized
keycloak_config_health_enabled: true
keycloak_config_metrics_enabled: true
keycloak_config_hostname: localhost
keycloak_config_admin_username: admin
keycloak_config_admin_password: ~

View File

@@ -0,0 +1,13 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: keycloak
description: Deploy keycloak, the opensource identity and access management solution
galaxy_tags:
- keycloak
- sso
- oidc
- oauth2
- iam
- docker

View File

@@ -0,0 +1,72 @@
---
- name: Ensure build directory exists
ansible.builtin.file:
name: "{{ keycloak_container_build_directory }}"
state: directory
recurse: yes
mode: 0700
tags:
- keycloak-build-container
- name: Ensure provider jars directory exists
ansible.builtin.file:
name: "{{ keycloak_provider_jars_directory }}"
state: directory
mode: 0775
tags:
- keycloak-build-container
- name: Ensure Dockerfile is templated
ansible.builtin.template:
src: Dockerfile.j2
dest: "{{ keycloak_container_build_directory }}/Dockerfile"
mode: 0700
register: keycloak_buildfile_info
tags:
- keycloak-container
- keycloak-build-container
- name: Ensure upstream Keycloak container image '{{ keycloak_container_image_upstream }}:{{ keycloak_version }}' is present
community.docker.docker_image:
name: "{{ keycloak_container_image_upstream }}:{{ keycloak_version }}"
source: pull
state: present
register: keycloak_container_image_upstream_status
tags:
- keycloak-container
- keycloak-build-container
- name: Ensure custom keycloak container image '{{ keycloak_container_image_name }}' is built
community.docker.docker_image:
name: "{{ keycloak_container_image_name }}"
build:
args:
DB_VENDOR: "{{ keycloak_container_database_vendor }}"
KC_ADMIN_PASSWORD: "{{ keycloak_config_admin_password }}"
dockerfile: "{{ keycloak_container_build_directory }}/Dockerfile"
path: "{{ keycloak_container_build_directory }}"
source: build
state: present
force_source: "{{ keycloak_buildfile_info.changed or keycloak_container_image_upstream_status.changed or (keycloak_force_rebuild_container | default(false))}}"
register: keycloak_container_image_status
tags:
- keycloak-container
- keycloak-build-container
- name: Ensure keycloak container is running
community.docker.docker_container:
name: "{{ keycloak_container_name }}"
image: "{{ keycloak_container_image_name }}"
env: "{{ keycloak_container_env | default(omit, true) }}"
ports: "{{ keycloak_container_ports | default(omit, true) }}"
hostname: "{{ keycloak_container_hostname | default(omit) }}"
labels: "{{ keycloak_container_labels | default(omit, true) }}"
volumes: "{{ keycloak_container_volumes | default(omit, true) }}"
restart_policy: "{{ keycloak_container_restart_policy }}"
recreate: "{{ keycloak_container_force_recreate | default(false) or (keycloak_container_image_status.changed if keycloak_container_image_status is defined else false) }}"
etc_hosts: "{{ keycloak_container_etc_hosts | default(omit) }}"
state: started
command: "{{ keycloak_container_command }}"
tags:
- keycloak-container

View File

@@ -0,0 +1,43 @@
FROM {{ keycloak_container_image_upstream }}:{{ keycloak_version }} as builder
# Enable health and metrics support
ENV KC_HEALTH_ENABLED={{ keycloak_config_health_enabled | ternary('true', 'false') }}
ENV KC_METRICS_ENABLED={{ keycloak_config_metrics_enabled | ternary('true', 'false') }}
# Configure a database vendor
ARG DB_VENDOR
ENV KC_DB=$DB_VENDOR
WORKDIR {{ keycloak_container_working_directory }}
{% if keycloak_container_image_add_local_providers | default(true) %}
ADD ./providers/* providers/
{% endif %}
# Workaround to set correct mode on jar files
USER root
RUN chmod -R 0770 providers/*
USER keycloak
RUN {{ keycloak_container_working_directory }}/bin/kc.sh --verbose \
{% for argument in keycloak_container_build_flags | dict2items(key_name='flag', value_name='value') %}
--{{- argument['flag'] -}}{{- argument['value'] | default(false, true) | ternary('=' + argument['value'], '') }} \
{% endfor%}
build{% if keycloak_container_build_features | default([]) | length > 0 %} \
{% endif %}
{% if keycloak_container_build_features | default([]) | length > 0 %}
--features="{{ keycloak_container_build_features | join(',') }}"
{% endif %}
FROM {{ keycloak_container_image_upstream }}:{{ keycloak_version }}
COPY --from=builder {{ keycloak_container_working_directory }}/ {{ keycloak_container_working_directory }}/
ENV KC_HOSTNAME={{ keycloak_config_hostname }}
ENV KEYCLOAK_ADMIN={{ keycloak_config_admin_username }}
ARG KC_ADMIN_PASSWORD
{% if keycloak_version | split('.') | first | int > 21 %}
ENV KEYCLOAK_ADMIN_PASSWORD=$KC_ADMIN_PASSWORD
{% else %}
ENV KEYCLOAK_PASSWORD=$KC_ADMIN_PASSWORD
{% endif %}
ENTRYPOINT ["{{ keycloak_container_working_directory }}/bin/kc.sh"]

View File

@@ -0,0 +1,3 @@
---
keycloak_container_working_directory: /opt/keycloak

View File

@@ -1,29 +0,0 @@
# `finallycoffee.services.minio` ansible role
## Overview
This role deploys a [min.io](https://min.io) server (s3-compatible object storage server)
using the official docker container image.
## Configuration
The role requires setting the password for the `root` user (name can be changed by
setting `minio_root_username`) in `minio_root_password`. That user has full control
over the minio-server instance.
### Useful config hints
Most configuration is done by setting environment variables in
`minio_container_extra_env`, for example:
```yaml
minio_container_extra_env:
# disable the "console" web browser UI
MINIO_BROWSER: off
# enable public prometheus metrics on `/minio/v2/metrics/cluster`
MINIO_PROMETHEUS_AUTH_TYPE: public
```
When serving minio (or any s3-compatible server) on a "subfolder",
see https://docs.aws.amazon.com/AmazonS3/latest/userguide/RESTRedirect.html
and https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html

View File

@@ -1,40 +0,0 @@
---
minio_user: ~
minio_data_path: /opt/minio
minio_create_user: false
minio_manage_host_filesystem: false
minio_root_username: root
minio_root_password: ~
minio_container_name: minio
minio_container_image_name: docker.io/minio/minio
minio_container_image_tag: latest
minio_container_image: "{{ minio_container_image_name }}:{{ minio_container_image_tag }}"
minio_container_networks: []
minio_container_ports: []
minio_container_base_volumes:
- "{{ minio_data_path }}:{{ minio_container_data_path }}:z"
minio_container_extra_volumes: []
minio_container_base_env:
MINIO_ROOT_USER: "{{ minio_root_username }}"
MINIO_ROOT_PASSWORD: "{{ minio_root_password }}"
minio_container_extra_env: {}
minio_container_labels: {}
minio_container_command:
- "server"
- "{{ minio_container_data_path }}"
- "--console-address \":{{ minio_container_listen_port_console }}\""
minio_container_restart_policy: "unless-stopped"
minio_container_image_force_source: "{{ (minio_container_image_tag == 'latest')|bool }}"
minio_container_listen_port_api: 9000
minio_container_listen_port_console: 8900
minio_container_data_path: /storage

View File

@@ -1,37 +0,0 @@
---
- name: Ensure minio run user is present
user:
name: "{{ minio_user }}"
state: present
system: yes
when: minio_create_user
- name: Ensure filesystem mounts ({{ minio_data_path }}) for container volumes are present
file:
path: "{{ minio_data_path }}"
state: directory
user: "{{ minio_user|default(omit, True) }}"
group: "{{ minio_user|default(omit, True) }}"
when: minio_manage_host_filesystem
- name: Ensure container image for minio is present
community.docker.docker_image:
name: "{{ minio_container_image }}"
state: present
source: pull
force_source: "{{ minio_container_image_force_source }}"
- name: Ensure container {{ minio_container_name }} is running
docker_container:
name: "{{ minio_container_name }}"
image: "{{ minio_container_image }}"
volumes: "{{ minio_container_volumes }}"
env: "{{ minio_container_env }}"
labels: "{{ minio_container_labels }}"
networks: "{{ minio_container_networks }}"
ports: "{{ minio_container_ports }}"
user: "{{ minio_user|default(omit, True) }}"
command: "{{ minio_container_command }}"
restart_policy: "{{ minio_container_restart_policy }}"
state: started

View File

@@ -1,5 +0,0 @@
---
minio_container_volumes: "{{ minio_container_base_volumes + minio_container_extra_volumes }}"
minio_container_env: "{{ minio_container_base_env | combine(minio_container_extra_env) }}"

View File

@@ -0,0 +1,21 @@
# `finallycoffee.services.openproject` ansible role
Deploys [openproject](https://www.openproject.org/) using docker-compose.
## Configuration
To set configuration variables for OpenProject, set them in `openproject_compose_overrides`:
```yaml
openproject_compose_overrides:
version: "3.7"
services:
proxy:
[...]
volumes:
pgdata:
driver: local
driver_opts:
o: bind
type: none
device: /var/lib/postgresql
```

View File

@@ -0,0 +1,11 @@
---
openproject_base_path: "/opt/openproject"
openproject_upstream_git_url: "https://github.com/opf/openproject-deploy.git"
openproject_upstream_git_branch: "stable/14"
openproject_compose_project_path: "{{ openproject_base_path }}"
openproject_compose_project_name: "openproject"
openproject_compose_project_env_file: "{{ openproject_compose_project_path }}/.env"
openproject_compose_project_override_file: "{{ openproject_compose_project_path }}/docker-compose.override.yml"
openproject_compose_project_env: {}

View File

@@ -0,0 +1,38 @@
---
- name: Ensure base directory '{{ openproject_base_path }}' is present
ansible.builtin.file:
path: "{{ openproject_base_path }}"
state: directory
- name: Ensure upstream repository is cloned
ansible.builtin.git:
dest: "{{ openproject_base_path }}"
repo: "{{ openproject_upstream_git_url }}"
version: "{{ openproject_upstream_git_branch }}"
clone: true
depth: 1
- name: Ensure environment is configured
ansible.builtin.lineinfile:
line: "{{ item.key}}={{ item.value}}"
path: "{{ openproject_compose_project_env_file }}"
state: present
create: true
loop: "{{ openproject_compose_project_env | dict2items(key_name='key', value_name='value') }}"
- name: Ensure docker compose overrides are set
ansible.builtin.copy:
dest: "{{ openproject_compose_project_override_file }}"
content: "{{ openproject_compose_overrides | default({}) | to_nice_yaml }}"
- name: Ensure containers are pulled
community.docker.docker_compose_v2:
project_src: "{{ openproject_compose_project_path }}"
project_name: "{{ openproject_compose_project_name }}"
pull: "missing"
- name: Ensure services are running
community.docker.docker_compose_v2:
project_src: "{{ openproject_compose_project_path }}"
project_name: "{{ openproject_compose_project_name }}"
state: "present"

View File

@@ -0,0 +1,3 @@
# `finallycoffee.services.phpldapadmin`
Role to deploy and configure [phpldapadmin](https://github.com/leenooks/phpLDAPadmin).

View File

@@ -0,0 +1,39 @@
---
phpldapadmin_container_name: phpldapadmin
phpldapadmin_container_image_registry: docker.io
phpldapadmin_container_image_namespace: phpldapadmin
phpldapadmin_container_image_name: phpldapadmin
phpldapadmin_container_image_repository: >-2
{{
[
phpldapadmin_container_image_registry | default([], true),
phpldapadmin_container_image_namespace | default([], true),
phpldapadmin_container_image_name
] | flatten | join('/')
}}
phpldapadmin_container_image: >-2
{{
[
phpldapadmin_container_image_repository,
phpldapadmin_container_image_tag | default(phpldapadmin_version, true)
] | join(':')
}}
phpldapadmin_container_image_tag: ~
phpldapadmin_container_image_source: pull
phpldapadmin_container_image_force_source: >-2
{{ phpldapadmin_container_image_tag | default(false, true) }}
phpldapadmin_container_env: ~
phpldapadmin_container_user: ~
phpldapadmin_container_ports: ~
phpldapadmin_container_labels: ~
phpldapadmin_container_volumes: ~
phpldapadmin_container_networks: ~
phpldapadmin_container_network_mode: ~
phpldapadmin_container_dns_servers: ~
phpldapadmin_container_etc_hosts: ~
phpldapadmin_container_memory: ~
phpldapadmin_container_memory_swap: ~
phpldapadmin_container_memory_reservation: ~
phpldapadmin_container_restart_policy: "on-failure"
phpldapadmin_container_state: >-2
{{ (phpldapadmin_state == 'present') | ternary('started', 'absent') }}

View File

@@ -0,0 +1,5 @@
---
phpldapadmin_version: "2.3.9"
phpldapadmin_state: present
phpldapadmin_deployment_method: docker

View File

@@ -0,0 +1,27 @@
---
- name: Ensure phpldapadmin container image '{{ phpldapadmin_container_image }}' is {{ phpldapadmin_state }}
community.docker.docker_image:
name: "{{ phpldapadmin_container_image }}"
state: "{{ phpldapadmin_state }}"
source: "{{ phpldapadmin_container_image_source }}"
force_source: "{{ phpldapadmin_container_image_force_source }}"
- name: Ensure phpldapadmin container '{{ phpldapadmin_container_name }}' is {{ phpldapadmin_container_state }}
community.docker.docker_container:
name: "{{ phpldapadmin_container_name }}"
image: "{{ phpldapadmin_container_image }}"
env: "{{ phpldapadmin_container_env | default(omit, true) }}"
user: "{{ phpldapadmin_container_user | default(omit, true) }}"
ports: "{{ phpldapadmin_container_ports | default(omit, true) }}"
labels: "{{ phpldapadmin_container_labels | default(omit, true) }}"
volumes: "{{ phpldapadmin_container_volumes | default(omit, true) }}"
networks: "{{ phpldapadmin_container_networks | default(omit, true) }}"
network_mode: "{{ phpldapadmin_container_network_mode | default(omit, true) }}"
dns_servers: "{{ phpldapadmin_container_dns_servers | default(omit, true) }}"
etc_hosts: "{{ phpldapadmin_container_etc_hosts | default(omit, true) }}"
memory: "{{ phpldapadmin_container_memory | default(omit, true) }}"
memory_swap: "{{ phpldapadmin_container_memory_swap | default(omit, true) }}"
memory_reservation: >-2
{{ phpldapadmin_container_memory_reservation | default(omit, true) }}
restart_policy: "{{ phpldapadmin_container_restart_policy | default(omit, true) }}"
state: "{{ phpldapadmin_container_state }}"

View File

@@ -0,0 +1,18 @@
---
- name: Ensure 'phpldapadmin_state' is valid
ansible.builtin.fail:
msg: >-2
Unsupported state '{{ phpldapadmin_state }}'!
Supported states are {{ phpldapadmin_states | join(', ') }}
when: phpldapadmin_state not in phpldapadmin_states
- name: Ensure 'phpldapadmin_deployment_method' is valid
ansible.builtin.fail:
msg: >-2
Unsupported deployment method '{{ phpldapadmin_deployment_method }}'!
Supported deployment methods are {{ phpldapadmin_deployment_methods | join(', ') }}
when: phpldapadmin_deployment_method not in phpldapadmin_deployment_methods
- name: Deploy using {{ phpldapadmin_deployment_method }}
ansible.builtin.import_tasks:
file: "deploy-{{ phpldapadmin_deployment_method }}.yml"

View File

@@ -0,0 +1,6 @@
---
phpldapadmin_states:
- "present"
- "absent"
phpldapadmin_deployment_methods:
- "docker"

54
roles/pretix/README.md Normal file
View File

@@ -0,0 +1,54 @@
# `finallycoffee.services.pretix` ansible role
Deploy [pretix](https://pretix.eu) using ansible. Note that this
role does not configure pretix beyond its own configuration file,
and requires changing a default admin password after a successful
installation.
## Configuration
For all available configuration options, see [`defaults/main/config.yml`](defaults/main/config.yml)
and other supporting files in the [`defaults/main/`](defaults/main/) folder.
To add custom configuration to pretix, populate them in `pretix_config`,
where they will be (recusively) merged into the default configuration.
### Required
- `pretix_domain`: domain of the pretix instance
- `pretix_postgresql_password`: password for the (default: postgresql) database
- `pretix_config_redis_location`: connection string for the main pretix redis database
- `pretix_config_celery_backend`: connection string for the celery backend, can be a (different!) redis database
- `pretix_config_celery_broker`: connection string for the celery broker, can be a (yet another different) redis database
For examples on how a redis server (like valkey) can be configured
for redis, see [`playbooks/pretix.yml`](../../playbooks/pretix.yml).
### Mailing
Set up mails in pretix by populating the following variables:
- `pretix_config_mail_host`: domain/IP and optional port of the SMTP server
- `pretix_config_mail_user`: SMTP user to authenticate
- `pretix_config_mail_password`: password for the SMTP user
### Plugins
To install more plugins, list the wanted `pypi` packages as a list in
`pretix_plugins`. They will be installed in the created virtualenv, and migrations and an asset rebuild will be automatically started.
If your plugin requires custom configuration (f.ex.: `pretix-oidc`),
add the configuration into `pretix_config`.
## Troubleshooting
### virtualenv
By default, the virtualenv is located in `/var/lib/pretix/virtualenv`.
This can be controlled by setting `pretix_virtualenv_dir`.
NOTE: To fix a broken virtualenv, try setting `pretix_virtualenv_state` to `forcereinstall` (see
[`ansible.builtin.pip` on docs.ansible.com](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/pip_module.html)).
NOTE: To install pip packages or execute migrations in the virtualenv, ansible
needs to become the unprivilated `pretix_user` (default: `pretix`). This might
require having the `acl` system package installed.

View File

@@ -0,0 +1,86 @@
---
pretix_config_instance_name: "My pretix installation"
pretix_config_url: "https://pretix.example.org"
pretix_config_currency: "EUR"
pretix_config_data_dir: "{{ pretix_data_dir }}"
pretix_config_trust_x_forwarded_for: "on"
pretix_config_trust_x_forwarded_proto: "on"
pretix_config_wsgi_name: "pretix"
pretix_config_wsgi_workers: 4
pretix_config_wsgi_max_requests: 100
pretix_config_wsgi_log_level: "info"
pretix_config_wsgi_bind_addr: "127.0.0.1:8345"
pretix_config_worker_log_level: "{{ pretix_config_wsgi_log_level }}"
pretix_config_database_backend: postgresql
pretix_config_database_name: pretix
pretix_config_database_user: pretix
pretix_config_database_password: ~
pretix_config_database_host: ""
pretix_config_mail_host: ~
pretix_config_mail_from: "tickets@example.org"
pretix_config_mail_user: ~
pretix_config_mail_password: ~
pretix_config_mail_tls: true
pretix_config_mail_ssl: false
pretix_config_redis_location: ~
pretix_config_redis_sessions: true
pretix_config_celery_backend: ~
pretix_config_celery_broker: ~
pretix_app_config:
url: "{{ pretix_config_url }}"
instance_name: "{{ pretix_config_instance_name }}"
datadir: "{{ pretix_config_data_dir }}"
trust_x_forwarded_for: "{{ pretix_config_trust_x_forwarded_for }}"
trust_x_forwarded_proto: "{{ pretix_config_trust_x_forwarded_proto }}"
currency: "{{ pretix_config_currency }}"
pretix_database_config:
backend: "{{ pretix_config_database_backend }}"
name: "{{ pretix_config_database_name }}"
user: "{{ pretix_config_database_user }}"
password: "{{ pretix_config_database_password }}"
host: "{{ pretix_config_database_host }}"
pretix_mail_minimal_config:
host: "{{ pretix_config_mail_host }}"
from: "{{ pretix_config_mail_from }}"
pretix_mail_config: >-2
{{ pretix_mail_minimal_config
| combine({'user': pretix_config_mail_user} if pretix_config_mail_user else {})
| combine({'password': pretix_config_mail_password} if pretix_config_mail_password else {})
| combine({'ssl': pretix_config_mail_ssl | bool | ternary('on', 'off')} if pretix_config_mail_ssl else {})
| combine({'tls': pretix_config_mail_tls | bool | ternary('on', 'off')} if pretix_config_mail_tls else {})
}}
pretix_redis_config:
location: "{{ pretix_config_redis_location }}"
sessions: "{{ pretix_config_redis_sessions | bool | ternary('true', 'false') }}"
pretix_celery_config:
backend: "{{ pretix_config_celery_backend }}"
broker: "{{ pretix_config_celery_broker }}"
pretix_config: {}
pretix_default_config:
pretix: "{{ pretix_app_config }}"
database: "{{ pretix_database_config }}"
mail: "{{ pretix_mail_config }}"
redis: "{{ pretix_redis_config }}"
celery: "{{ pretix_celery_config }}"
pretix_config_merged: >-2
{{ pretix_default_config | combine(pretix_config | default({}), recursive=True) }}
pretix_config_file_content: |+2
{% for kv in (pretix_config_merged | dict2items) %}
[{{ kv.key }}]
{% for entry in ((kv.value | default({}, true)) | dict2items) %}
{{ entry.key }}={{ entry.value }}
{% endfor %}
{% endfor %}

View File

@@ -0,0 +1,16 @@
---
pretix_version: "2026.2.0"
pretix_state: "present"
pretix_deployment_method: "systemd"
pretix_config_file: "/etc/pretix/pretix.cfg"
pretix_config_file_owner: "{{ pretix_user_id }}"
pretix_config_file_group: "{{ pretix_group_id }}"
pretix_config_file_mode: "0640"
pretix_config_dir: "{{ pretix_config_file | dirname }}"
pretix_install_dir: "/var/lib/pretix"
pretix_virtualenv_dir: "{{ pretix_install_dir }}/virtualenv"
pretix_data_dir: "{{ pretix_install_dir }}/data"
pretix_media_dir: "{{ pretix_data_dir }}/media"
pretix_plugins: []

View File

@@ -0,0 +1,22 @@
---
pretix_debian_packages:
- "git"
- "build-essential"
- "python3-dev"
- "python3-venv"
- "python3"
- "python3-pip"
- "libxml2-dev"
- "libxslt1-dev"
- "libffi-dev"
- "zlib1g-dev"
- "libssl-dev"
- "gettext"
- "libpq-dev"
- "libjpeg-dev"
- "libopenjp2-7-dev"
- "nodejs"
pretix_packages:
"debian":
"12": "{{ pretix_debian_packages }}"

View File

@@ -0,0 +1,50 @@
---
pretix_systemd_unit_description: "pretix web service"
pretix_systemd_unit_after: "network.target"
pretix_systemd_unit_file_path: >-2
/etc/systemd/system/{{ pretix_systemd_service_name }}
pretix_systemd_service_name: "pretix.service"
pretix_systemd_service_user: "{{ pretix_user }}"
pretix_systemd_service_group: "{{ pretix_user }}"
pretix_systemd_service_environment:
VIRTUAL_ENV: "{{ pretix_virtualenv_dir }}"
PATH: "{{ pretix_virtualenv_dir }}/bin:/usr/local/bin:/usr/bin:/bin"
pretix_systemd_service_working_directory: "{{ pretix_install_dir }}"
pretix_systemd_service_exec_start: >-2
{{ pretix_virtualenv_dir }}/bin/gunicorn pretix.wsgi
--name {{ pretix_config_wsgi_name }}
--workers {{ pretix_config_wsgi_workers }}
--max-requests {{ pretix_config_wsgi_max_requests }}
--log-level={{ pretix_config_wsgi_log_level }}
--bind={{ pretix_config_wsgi_bind_addr }}
pretix_systemd_service_restart: "on-failure"
pretix_systemd_install_wanted_by: "multi-user.target"
# pretix worker
pretix_worker_systemd_service_name: "pretix-worker.service"
pretix_worker_systemd_service_description: "pretix worker service"
pretix_worker_systemd_unit_file_path: >-2
/etc/systemd/system/{{ pretix_worker_systemd_service_name }}
pretix_worker_systemd_service_exec_start: >-2
{{ pretix_virtualenv_dir }}/bin/celery
-A pretix.celery_app worker
-l {{ pretix_config_worker_log_level }}
# pretix cron
pretix_cron_systemd_service_name: "pretix-cron.service"
pretix_cron_systemd_service_description: "pretix cron service"
pretix_cron_systemd_unit_file_path: >-2
/etc/systemd/system/{{ pretix_cron_systemd_service_name }}
pretix_cron_systemd_service_exec_start: >-2
python3 -m pretix runperiodic
pretix_cron_systemd_timer_name: "pretix-cron.timer"
pretix_cron_systemd_timer_description: "pretix cron timer"
pretix_cron_systemd_timer_file_path: >-2
/etc/systemd/system/{{ pretix_cron_systemd_timer_name }}
pretix_cron_systemd_timer_on_active_sec: 1800
pretix_cron_systemd_timer_on_startup_sec: >-2
{{ pretix_cron_systemd_timer_on_active_sec }}
pretix_cron_systemd_timer_accuracy_sec: 60

View File

@@ -0,0 +1,7 @@
---
pretix_user: "pretix"
pretix_user_system: true
pretix_user_create_home: false
pretix_user_id: "{{ pretix_user_info.uid | default(pretix_user) }}"
pretix_group_id: "{{ pretix_user_info.group | default(pretix_user) }}"

View File

@@ -0,0 +1,11 @@
---
pretix_virtualenv_state: "{{ pretix_state }}"
pretix_virtualenv_packages:
- "pip"
- "setuptools"
- "wheel"
- "gunicorn"
- "pretix=={{ pretix_version }}"
pretix_virtualenv_site_packages: false
pretix_virtualenv_command: "python3 -m venv"

View File

@@ -0,0 +1,6 @@
---
- name: Ensure pretix systemd service is restarted
listen: pretix_restart
ansible.builtin.systemd_service:
name: "{{ pretix_systemd_service_name }}"
state: "restarted"

View File

@@ -0,0 +1,9 @@
---
allow_duplicates: true
dependencies: []
galaxy_info:
role_name: pretix
description: Ansible role to deploy pretix (https://pretix.eu)
galaxy_tags:
- pretix
- ticketing

View File

@@ -0,0 +1,14 @@
---
- name: Ensure 'pretix_state' is valid
ansible.builtin.fail:
msg: >-2
Unsupported pretix_state '{{ pretix_state }}'.
Supported states are {{ pretix_states | join(', ') }}
when: pretix_state not in pretix_states
- name: Ensure 'pretix_deployment_method' is valid
ansible.builtin.fail:
msg: >-2
Unsupported pretix_state '{{ pretix_deployment_method }}'.
Supported states are {{ pretix_deployment_methods | join(', ') }}
when: pretix_deployment_method not in pretix_deployment_methods

View File

@@ -0,0 +1,10 @@
---
- name: Ensure configuration file is written
ansible.builtin.copy:
dest: "{{ pretix_config_file }}"
content: "{{ pretix_config_file_content }}"
owner: "{{ pretix_config_file_owner }}"
group: "{{ pretix_config_file_group }}"
mode: "{{ pretix_config_file_mode }}"
when: pretix_state == 'present'
register: pretix_config_file_info

View File

@@ -0,0 +1,64 @@
---
- name: Ensure virtualenv in {{ pretix_virtualenv_dir }} is present
ansible.builtin.pip:
name: "{{ pretix_virtualenv_packages + pretix_plugins }}"
state: "{{ pretix_virtualenv_state }}"
chdir: "{{ pretix_install_dir }}"
virtualenv: "{{ pretix_virtualenv_dir }}"
virtualenv_command: "{{ pretix_virtualenv_command | default(omit, true) }}"
virtualenv_site_packages: "{{ pretix_virtualenv_site_packages }}"
become: true
become_user: "{{ pretix_user }}"
register: pretix_virtualenv_info
# TODO: determine to only do this on a) upgrades or b) initial deployis
- name: Ensure pretix database migrations are run
ansible.builtin.command:
cmd: "{{ pretix_virtualenv_dir }}/bin/python -m pretix migrate"
chdir: "{{ pretix_install_dir }}"
environment:
VIRTUAL_ENV: "{{ pretix_virtualenv_dir }}"
become: true
become_user: "{{ pretix_user }}"
notify: pretix_restart
when:
- pretix_state == 'present'
- pretix_virtualenv_info.changed or pretix_config_file_info.changed
# TODO: determine to only do this on a) upgrades or b) initial deployis
- name: Ensure pretix static assets are built
ansible.builtin.command:
cmd: "{{ pretix_virtualenv_dir }}/bin/python -m pretix rebuild"
chdir: "{{ pretix_install_dir }}"
environment:
VIRTUAL_ENV: "{{ pretix_virtualenv_dir }}"
become: true
become_user: "{{ pretix_user }}"
notify: pretix_restart
when:
- pretix_state == 'present'
- pretix_virtualenv_info.changed or pretix_config_file_info.changed
- name: Ensure pretix systemd service is enabled
ansible.builtin.systemd_service:
name: "{{ _service }}"
enabled: true
when: pretix_state == 'present'
loop:
- "{{ pretix_systemd_service_name }}"
- "{{ pretix_worker_systemd_service_name }}"
- "{{ pretix_cron_systemd_service_name }}"
- "{{ pretix_cron_systemd_timer_name }}"
loop_control:
loop_var: _service
- name: Ensure pretix systemd service is {{ pretix_state }}
ansible.builtin.systemd_service:
name: "{{ _service }}"
state: "{{ (pretix_state == 'present') | ternary('started', 'stopped') }}"
loop:
- "{{ pretix_systemd_service_name }}"
- "{{ pretix_worker_systemd_service_name }}"
- "{{ pretix_cron_systemd_timer_name }}"
loop_control:
loop_var: _service

Some files were not shown because too many files have changed in this diff Show More