diff --git a/Makefile.common b/Makefile.common index 8aa7987..cf3d65c 100644 --- a/Makefile.common +++ b/Makefile.common @@ -93,12 +93,12 @@ TARGET_EXAMPLES_SYSCTLD_FILES = $(patsubst sysctl.d/examples/%, $(TARGET_CHROOT) TARGET_EXAMPLES_PROFILED_FILES = $(patsubst profile.d/examples/%, $(TARGET_CHROOT)/etc/profile.d/%, $(EXAMPLES_PROFILED_FILES)) # All configuration files to be installed -TARGET_FILES = $(addprefix $(TARGET_CHROOT)/etc/containers/systemd/, $(QUADLETS_FILES)) \ +TARGET_FILES += $(addprefix $(TARGET_CHROOT)/etc/containers/systemd/, $(QUADLETS_FILES)) \ $(addprefix $(TARGET_CHROOT)/etc/systemd/system/, $(SYSTEMD_FILES)) \ $(TARGET_CONFIG_FILES) $(TARGET_TMPFILESD_FILES) $(TARGET_SYSCTLD_FILES) $(TARGET_PROFILED_FILES) # All example configuration files to be installed -TARGET_EXAMPLE_FILES = $(TARGET_EXAMPLES_CONFIG_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES) $(TARGET_EXAMPLES_PROFILED_FILES) +TARGET_EXAMPLE_FILES += $(TARGET_EXAMPLES_CONFIG_FILES) $(TARGET_EXAMPLES_TMPFILESD_FILES) $(TARGET_EXAMPLES_SYSCTLD_FILES) $(TARGET_EXAMPLES_PROFILED_FILES) # Dependencies on other projects # List here the names of other projects (directories at the top-level) that this project depends on. @@ -203,7 +203,7 @@ $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME): install-config: $(TARGET_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME) # Copy all example configuration files provided by this project. -install-examples: $(TARGET_EXAMPLE_FILES) $(TARGET_CHROOT)/var/lib/quadlets/$(PROJECT_NAME) +install-examples: $(TARGET_EXAMPLE_FILES) # Copy all quadlets and systemd files provided by this project. install-files: install-files-pre install-config install-examples @@ -274,9 +274,10 @@ install-pre:: # This target can be extended by Makefiles sourcing this one. install-post:: -# Uninstall all quadlets and systemd units installed by this project. +# All files to be removed during uninstallation, sorted in reverse order to remove files before their parent directories. +uninstall: FILES_TO_REMOVE := $(shell echo $(TARGET_FILES) $(TARGET_EXAMPLE_FILES) | tr ' ' '\n' | sort -ur | tr '\n' ' ') -uninstall: FILES_TO_REMOVE := $(call reverse,$(TARGET_EXAMPLE_FILES) $(TARGET_FILES)) +# Uninstall all quadlets and systemd units installed by this project. uninstall: pre-requisites uninstall-pre @run() { echo $$*; "$$@"; }; \ set -Eeuo pipefail; \ @@ -478,7 +479,7 @@ clean: clean-pre pre-requisites echo "Aborted."; exit 1; \ fi; \ fi - rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /var/run/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/ + rm -rf /var/lib/quadlets/$(PROJECT_NAME)/ /run/quadlets/$(PROJECT_NAME)/ /etc/quadlets/$(PROJECT_NAME)/ $(MAKE) clean-post # All phony targets diff --git a/keycloak/Makefile b/keycloak/Makefile new file mode 100644 index 0000000..ec4b0ae --- /dev/null +++ b/keycloak/Makefile @@ -0,0 +1,25 @@ +## +## Makefile for Keycloak quadlet +## + +DEPENDENCIES = postgresql traefik + +# Keycloak quadlet is mapped to the 10007 user (keycloak) and 10000 group (itix-svc) +PROJECT_UID = 10007 +PROJECT_GID = 10000 + +# PostgreSQL initialization scripts +TARGET_POSTGRESQL_FILES = $(patsubst other/postgresql/%, $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%, $(wildcard other/postgresql/*)) +TARGET_EXAMPLE_FILES += $(TARGET_POSTGRESQL_FILES) +$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%.sql: other/postgresql/%.sql + install -m 0600 -o 10004 -g 10000 $< $@ + +# Traefik configuration files +TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) +$(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% + install -m 0644 -o 10001 -g 10000 $< $@ + +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + diff --git a/keycloak/config/container/Containerfile b/keycloak/config/container/Containerfile new file mode 100644 index 0000000..6e0c3e6 --- /dev/null +++ b/keycloak/config/container/Containerfile @@ -0,0 +1,13 @@ +FROM quay.io/keycloak/keycloak:latest AS builder +ENV KC_DB=postgres \ + KC_HEALTH_ENABLED=true \ + KC_METRICS_ENABLED=true \ + KC_HTTP_ENABLED=true \ + KC_HTTP_ACCESS_LOG_ENABLED=true +WORKDIR /opt/keycloak +RUN /opt/keycloak/bin/kc.sh build + +FROM quay.io/keycloak/keycloak:latest +COPY --from=builder /opt/keycloak/ /opt/keycloak/ +ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] +CMD ["start --optimized"] diff --git a/keycloak/config/examples/config.env b/keycloak/config/examples/config.env new file mode 100644 index 0000000..abe7762 --- /dev/null +++ b/keycloak/config/examples/config.env @@ -0,0 +1,18 @@ +# See https://www.keycloak.org/server/all-config for all available configuration options +KC_DB=postgres +KC_DB_URL_DATABASE=keycloak +KC_DB_URL_HOST=127.0.0.1 +KC_DB_URL_PORT=5432 +KC_DB_USERNAME=keycloak +KC_DB_PASSWORD=keycloak +KC_HOSTNAME=http://keycloak +KC_HEALTH_ENABLED=true +KC_METRICS_ENABLED=true +KC_BOOTSTRAP_ADMIN_USERNAME=admin +KC_BOOTSTRAP_ADMIN_PASSWORD=keycloak +KC_HTTP_ENABLED=true +KC_HTTP_PORT=8080 +KC_HTTP_HOST=127.0.0.1 +KC_HTTP_ACCESS_LOG_ENABLED=true +KC_PROXY_HEADERS=xforwarded +KC_PROXY_TRUSTED_ADDRESSES=127.0.0.1 diff --git a/keycloak/fcos.bu b/keycloak/fcos.bu new file mode 100644 index 0000000..13ff8fb --- /dev/null +++ b/keycloak/fcos.bu @@ -0,0 +1,13 @@ +variant: fcos +version: 1.4.0 +ignition: + config: + merge: + - local: base.ign + - local: traefik.ign + - local: traefik-examples.ign + - local: postgresql.ign + - local: postgresql-examples.ign + - local: keycloak.ign + - local: keycloak-examples.ign + - local: local.ign diff --git a/keycloak/keycloak-build.timer b/keycloak/keycloak-build.timer new file mode 100644 index 0000000..329c79a --- /dev/null +++ b/keycloak/keycloak-build.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Keycloak Container image build timer +Documentation=https://www.keycloak.org/server/containers +PartOf=keycloak.target + +[Timer] +OnCalendar=weekly +Persistent=true + +[Install] +WantedBy=keycloak.target diff --git a/keycloak/keycloak.build b/keycloak/keycloak.build new file mode 100644 index 0000000..2e12e9c --- /dev/null +++ b/keycloak/keycloak.build @@ -0,0 +1,10 @@ +[Unit] +Description=Keycloak Container image build +Documentation=https://www.keycloak.org/server/containers +Wants=network-online.target +After=network-online.target + +[Build] +File=/etc/quadlets/keycloak/container/Containerfile +ImageTag=localhost/keycloak:latest +SetWorkingDirectory=/etc/quadlets/keycloak/container diff --git a/keycloak/keycloak.container b/keycloak/keycloak.container new file mode 100644 index 0000000..96063ea --- /dev/null +++ b/keycloak/keycloak.container @@ -0,0 +1,44 @@ +[Unit] +Description=Keycloak Service +Documentation=https://www.keycloak.org/server/containers +After=network.target keycloak-build.service +Wants=keycloak-build.service + +# Only start if Keycloak has been configured +ConditionPathExists=/etc/quadlets/keycloak/config.env + +# Start/stop this unit when the target is started/stopped +PartOf=keycloak.target + +[Container] +ContainerName=keycloak +Image=localhost/keycloak:latest +AutoUpdate=local + +# Network configuration +Network=host + +# Keycloak specific commands +Exec=start --optimized + +# Health check +HealthCmd=curl -sSf http://127.0.0.1:8080/health +HealthInterval=30s +HealthTimeout=10s +HealthStartPeriod=10s +HealthRetries=3 + +# Configuration file +EnvironmentFile=/etc/quadlets/keycloak/config.env + +[Service] +Restart=always +RestartSec=10 +TimeoutStartSec=120 +TimeoutStopSec=30 + +# Wait for PostgreSQL to be ready on localhost +ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1' + +[Install] +WantedBy=keycloak.target \ No newline at end of file diff --git a/keycloak/keycloak.target b/keycloak/keycloak.target new file mode 100644 index 0000000..6bdd253 --- /dev/null +++ b/keycloak/keycloak.target @@ -0,0 +1,11 @@ +[Unit] +Description=Keycloak Service Target +Documentation=man:systemd.target(5) +Requires=postgresql.target keycloak.service keycloak-build.timer +After=postgresql.target keycloak.service keycloak-build.timer + +# Allow isolation - can stop/start this target independently +AllowIsolate=yes + +[Install] +WantedBy=multi-user.target diff --git a/keycloak/other/postgresql/keycloak.sql b/keycloak/other/postgresql/keycloak.sql new file mode 100644 index 0000000..6356b10 --- /dev/null +++ b/keycloak/other/postgresql/keycloak.sql @@ -0,0 +1,5 @@ +-- Initialization script for Keycloak database and user +CREATE USER keycloak WITH PASSWORD 'keycloak'; +CREATE DATABASE keycloak OWNER keycloak; +GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak; +ALTER ROLE keycloak SET client_encoding TO 'utf8'; \ No newline at end of file diff --git a/keycloak/other/traefik/keycloak.yaml b/keycloak/other/traefik/keycloak.yaml new file mode 100644 index 0000000..6bcb0e9 --- /dev/null +++ b/keycloak/other/traefik/keycloak.yaml @@ -0,0 +1,16 @@ +http: + routers: + keycloak: + rule: "Host(`keycloak`)" + entryPoints: + - http + #- https + middlewares: + service: "keycloak" + #tls: + # certResolver: le + services: + keycloak: + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" diff --git a/keycloak/overlay.bu b/keycloak/overlay.bu new file mode 100644 index 0000000..5255a06 --- /dev/null +++ b/keycloak/overlay.bu @@ -0,0 +1,9 @@ +variant: fcos +version: 1.4.0 +passwd: + users: + - name: keycloak + uid: 10007 + gecos: Keycloak + home_dir: /var/lib/quadlets/keycloak + primary_group: itix-svc diff --git a/miniflux/Makefile b/miniflux/Makefile new file mode 100644 index 0000000..4ed051d --- /dev/null +++ b/miniflux/Makefile @@ -0,0 +1,25 @@ +## +## Makefile for Miniflux quadlet +## + +DEPENDENCIES = postgresql traefik + +# Miniflux quadlet is mapped to the 10010 user (miniflux) and 10000 group (itix-svc) +PROJECT_UID = 10010 +PROJECT_GID = 10000 + +# PostgreSQL initialization scripts +TARGET_POSTGRESQL_FILES = $(patsubst other/postgresql/%, $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%, $(wildcard other/postgresql/*)) +TARGET_EXAMPLE_FILES += $(TARGET_POSTGRESQL_FILES) +$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%.sql: other/postgresql/%.sql + install -m 0600 -o 10004 -g 10000 $< $@ + +# Traefik configuration files +TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) +$(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% + install -m 0644 -o 10001 -g 10000 $< $@ + +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + diff --git a/miniflux/config/examples/miniflux.conf b/miniflux/config/examples/miniflux.conf new file mode 100644 index 0000000..a9fc427 --- /dev/null +++ b/miniflux/config/examples/miniflux.conf @@ -0,0 +1,9 @@ +DATABASE_URL=postgres://miniflux:miniflux@localhost/miniflux?sslmode=disable +PORT=8080 +#HTTPS=1 +BASE_URL=http://miniflux/ +RUN_MIGRATIONS=1 +CREATE_ADMIN=1 +ADMIN_USERNAME=admin +ADMIN_PASSWORD=miniflux +HTTP_CLIENT_TIMEOUT=120 diff --git a/miniflux/fcos.bu b/miniflux/fcos.bu new file mode 100644 index 0000000..b60b885 --- /dev/null +++ b/miniflux/fcos.bu @@ -0,0 +1,13 @@ +variant: fcos +version: 1.4.0 +ignition: + config: + merge: + - local: base.ign + - local: traefik.ign + - local: traefik-examples.ign + - local: postgresql.ign + - local: postgresql-examples.ign + - local: miniflux.ign + - local: miniflux-examples.ign + - local: local.ign diff --git a/miniflux/miniflux.container b/miniflux/miniflux.container new file mode 100644 index 0000000..f9ba6b0 --- /dev/null +++ b/miniflux/miniflux.container @@ -0,0 +1,48 @@ +[Unit] +Description=Miniflux RSS Reader +Documentation=https://github.com/miniflux/v2 +After=network.target + +# Only start if Miniflux has been configured +ConditionPathExists=/etc/quadlets/miniflux/miniflux.conf + +# Start/stop this unit when the target is started/stopped +PartOf=miniflux.target + +[Container] +ContainerName=miniflux +Image=ghcr.io/miniflux/miniflux:latest +AutoUpdate=registry + +# Network configuration +Network=host + +# No need for root privileges +User=10010 +Group=10000 + +# Command and arguments +Entrypoint=/usr/bin/miniflux +Exec=-c /etc/miniflux/miniflux.conf + +# Volume mounts +Volume=/etc/quadlets/miniflux/miniflux.conf:/etc/miniflux/miniflux.conf:ro,z + +# Health check +HealthCmd=/usr/bin/miniflux -healthcheck auto +HealthInterval=30s +HealthTimeout=10s +HealthStartPeriod=10s +HealthRetries=3 + +[Service] +Restart=always +RestartSec=10 +TimeoutStartSec=120 +TimeoutStopSec=30 + +# Wait for PostgreSQL to be ready on localhost +ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1' + +[Install] +WantedBy=miniflux.target diff --git a/miniflux/miniflux.target b/miniflux/miniflux.target new file mode 100644 index 0000000..57a586f --- /dev/null +++ b/miniflux/miniflux.target @@ -0,0 +1,13 @@ +[Unit] +Description=Miniflux Service Target +Documentation=man:systemd.target(5) +Requires=postgresql.target miniflux.service +After=postgresql.target miniflux.service + +# Allow isolation - can stop/start this target independently +AllowIsolate=yes +# Only start if Miniflux has been configured +ConditionPathExists=/etc/quadlets/miniflux/miniflux.conf + +[Install] +WantedBy=multi-user.target diff --git a/miniflux/other/postgresql/miniflux.sql b/miniflux/other/postgresql/miniflux.sql new file mode 100644 index 0000000..4ebd741 --- /dev/null +++ b/miniflux/other/postgresql/miniflux.sql @@ -0,0 +1,5 @@ +-- Initialization script for Miniflux database and user +CREATE USER miniflux WITH PASSWORD 'miniflux'; +CREATE DATABASE miniflux OWNER miniflux; +GRANT ALL PRIVILEGES ON DATABASE miniflux TO miniflux; +ALTER ROLE miniflux SET client_encoding TO 'utf8'; diff --git a/miniflux/other/traefik/miniflux.yaml b/miniflux/other/traefik/miniflux.yaml new file mode 100644 index 0000000..c67b2ce --- /dev/null +++ b/miniflux/other/traefik/miniflux.yaml @@ -0,0 +1,16 @@ +http: + routers: + miniflux: + rule: "Host(`miniflux`)" + entryPoints: + - http + #- https + middlewares: + service: "miniflux" + #tls: + # certResolver: le + services: + miniflux: + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" diff --git a/miniflux/overlay.bu b/miniflux/overlay.bu new file mode 100644 index 0000000..398caf6 --- /dev/null +++ b/miniflux/overlay.bu @@ -0,0 +1,9 @@ +variant: fcos +version: 1.4.0 +passwd: + users: + - name: miniflux + uid: 10010 + gecos: Miniflux + home_dir: /var/lib/quadlets/miniflux + primary_group: itix-svc diff --git a/nextcloud/Makefile b/nextcloud/Makefile index b55c155..bc92393 100644 --- a/nextcloud/Makefile +++ b/nextcloud/Makefile @@ -8,37 +8,44 @@ DEPENDENCIES = postgresql traefik PROJECT_UID = 10008 PROJECT_GID = 10000 -TOP_LEVEL_DIR := .. -include $(TOP_LEVEL_DIR)/Makefile.common - -.PHONY: test test-set-nextcloud-major +# PostgreSQL initialization scripts +TARGET_POSTGRESQL_FILES = $(patsubst other/postgresql/%, $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%, $(wildcard other/postgresql/*)) +TARGET_EXAMPLE_FILES += $(TARGET_POSTGRESQL_FILES) +$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%.sql: other/postgresql/%.sql + install -m 0600 -o 10004 -g 10000 $< $@ -NEXTCLOUD_MAJOR_START ?= 25 -NEXTCLOUD_MAJOR_LAST ?= 31 -test-set-nextcloud-major: - sed -i 's/^NEXTCLOUD_MAJOR=.*/NEXTCLOUD_MAJOR=$(NEXTCLOUD_MAJOR_START)/' config/examples/config.env +# Traefik configuration files +TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) +$(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% + install -m 0644 -o 10001 -g 10000 $< $@ +# Additional Nextcloud directories and files +TARGET_FILES += $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/redis $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/redis: install -m 0700 -o $(PROJECT_UID) -g $(PROJECT_GID) -d $@ +TARGET_FILES += $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/data +TARGET_FILES += $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/config $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/data $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/config: install -m 0700 -o $(PROJECT_UID) -g $(PROJECT_GID) -d $@ $(TARGET_CHROOT)/etc/quadlets/nextcloud/www.conf: config/www.conf install -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) -D $< $@ +TARGET_FILES += $(TARGET_CHROOT)/etc/quadlets/nextcloud/collabora-seccomp-profile.json $(TARGET_CHROOT)/etc/quadlets/nextcloud/collabora-seccomp-profile.json: curl -sSfL -o $@ https://raw.githubusercontent.com/CollaboraOnline/online/refs/heads/main/docker/cool-seccomp-profile.json -install-config: $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/redis $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/data $(TARGET_CHROOT)/var/lib/quadlets/nextcloud/config $(TARGET_CHROOT)/etc/quadlets/nextcloud/collabora-seccomp-profile.json - -install-examples: $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/nextcloud.sql $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/nextcloud.yaml $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/collabora.yaml +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common -$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/nextcloud.sql: other/nextcloud.sql - install -m 0600 -o 10004 -g 10000 $< $@ +.PHONY: test test-set-nextcloud-major -$(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/nextcloud.yaml $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/collabora.yaml: $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%.yaml: other/traefik-%.yaml - install -m 0644 -o 10001 -g 10000 $< $@ +NEXTCLOUD_MAJOR_START ?= 25 +NEXTCLOUD_MAJOR_LAST ?= 31 +test-set-nextcloud-major: + sed -i 's/^NEXTCLOUD_MAJOR=.*/NEXTCLOUD_MAJOR=$(NEXTCLOUD_MAJOR_START)/' config/examples/config.env test: @run() { echo $$*; "$$@"; }; \ diff --git a/nextcloud/other/nextcloud.sql b/nextcloud/other/postgresql/nextcloud.sql similarity index 100% rename from nextcloud/other/nextcloud.sql rename to nextcloud/other/postgresql/nextcloud.sql diff --git a/nextcloud/other/traefik-collabora.yaml b/nextcloud/other/traefik/collabora.yaml similarity index 82% rename from nextcloud/other/traefik-collabora.yaml rename to nextcloud/other/traefik/collabora.yaml index c5438ac..5ce6dd0 100644 --- a/nextcloud/other/traefik-collabora.yaml +++ b/nextcloud/other/traefik/collabora.yaml @@ -4,8 +4,11 @@ http: rule: "Host(`collabora`)" entryPoints: - http + #- https middlewares: service: "collabora" + #tls: + # certResolver: le services: collabora: loadBalancer: diff --git a/nextcloud/other/traefik-nextcloud.yaml b/nextcloud/other/traefik/nextcloud.yaml similarity index 82% rename from nextcloud/other/traefik-nextcloud.yaml rename to nextcloud/other/traefik/nextcloud.yaml index 96d9c31..2ce8614 100644 --- a/nextcloud/other/traefik-nextcloud.yaml +++ b/nextcloud/other/traefik/nextcloud.yaml @@ -4,8 +4,11 @@ http: rule: "Host(`nextcloud`)" entryPoints: - http + #- https middlewares: service: "nextcloud" + #tls: + # certResolver: le services: nextcloud: loadBalancer: diff --git a/postgresql/Makefile b/postgresql/Makefile index df4d24b..bb92571 100644 --- a/postgresql/Makefile +++ b/postgresql/Makefile @@ -6,6 +6,10 @@ PROJECT_UID = 10004 PROJECT_GID = 10000 +TARGET_FILES += $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d +$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d: + install -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) -D -d $@ + # Include common Makefile TOP_LEVEL_DIR := .. include $(TOP_LEVEL_DIR)/Makefile.common @@ -17,11 +21,6 @@ PG_MAJOR_LAST ?= 18 test-set-pgmajor: sed -i 's/^PG_MAJOR=.*/PG_MAJOR=$(PG_MAJOR_START)/' config/examples/config.env -$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d: - install -m 0755 -o $(PROJECT_UID) -g $(PROJECT_GID) -D -d $@ - -install-config: $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d - # Integration tests for PostgreSQL quadlet: backup, restore + major version upgrade (14 to 18) test: uninstall clean test-set-pgmajor install @echo "Running PostgreSQL integration tests..."; \ diff --git a/restic-server/Makefile b/restic-server/Makefile index 3d840d3..fb4cc0d 100644 --- a/restic-server/Makefile +++ b/restic-server/Makefile @@ -8,15 +8,13 @@ DEPENDENCIES = traefik PROJECT_UID = 10022 PROJECT_GID = 10000 -TOP_LEVEL_DIR := .. -include $(TOP_LEVEL_DIR)/Makefile.common - -SYSTEMD_MAIN_UNIT_NAMES += restic-server.service - +# Traefik configuration files TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) - -install-examples: $(TARGET_TRAEFIK_FILES) - +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% install -m 0644 -o 10001 -g 10000 $< $@ +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + +SYSTEMD_MAIN_UNIT_NAMES += restic-server.service diff --git a/seedbox/Makefile b/seedbox/Makefile index 6ccc7e1..9a4e224 100644 --- a/seedbox/Makefile +++ b/seedbox/Makefile @@ -2,23 +2,24 @@ ## Makefile for Seedbox quadlet ## -DEPENDENCIES = traefik +DEPENDENCIES = traefik samba # Seedbox quadlet is mapped to the 10017 user (seedbox) and 10000 group (itix-svc) PROJECT_UID = 10017 PROJECT_GID = 10000 -TOP_LEVEL_DIR := .. -include $(TOP_LEVEL_DIR)/Makefile.common - -TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +# Samba configuration files TARGET_SAMBA_FILES = $(patsubst other/samba/%, $(TARGET_CHROOT)/etc/quadlets/samba/smb.conf.d/%, $(wildcard other/samba/*)) - -install-examples: $(TARGET_TRAEFIK_FILES) $(TARGET_SAMBA_FILES) - +TARGET_EXAMPLE_FILES += $(TARGET_SAMBA_FILES) $(TARGET_CHROOT)/etc/quadlets/samba/smb.conf.d/%: other/samba/% install -m 0644 -o root -g root $< $@ +# Traefik configuration files +TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% install -m 0644 -o 10001 -g 10000 $< $@ +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + diff --git a/traefik/config/examples/conf.d/ping.yaml b/traefik/config/examples/conf.d/ping.yaml index 44ffb33..c7d2889 100644 --- a/traefik/config/examples/conf.d/ping.yaml +++ b/traefik/config/examples/conf.d/ping.yaml @@ -7,7 +7,6 @@ http: service: "ping@internal" middlewares: - localhost-only - services: {} middlewares: localhost-only: ipAllowList: diff --git a/vaultwarden/Makefile b/vaultwarden/Makefile new file mode 100644 index 0000000..4fe0bb6 --- /dev/null +++ b/vaultwarden/Makefile @@ -0,0 +1,25 @@ +## +## Makefile for Vaultwarden quadlet +## + +DEPENDENCIES = postgresql traefik + +# Vaultwarden quadlet is mapped to the 10020 user (vaultwarden) and 10000 group (itix-svc) +PROJECT_UID = 10020 +PROJECT_GID = 10000 + +# PostgreSQL initialization scripts +TARGET_POSTGRESQL_FILES = $(patsubst other/postgresql/%, $(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%, $(wildcard other/postgresql/*)) +TARGET_EXAMPLE_FILES += $(TARGET_POSTGRESQL_FILES) +$(TARGET_CHROOT)/etc/quadlets/postgresql/init.d/%.sql: other/postgresql/%.sql + install -m 0600 -o 10004 -g 10000 $< $@ + +# Traefik configuration files +TARGET_TRAEFIK_FILES = $(patsubst other/traefik/%, $(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%, $(wildcard other/traefik/*)) +TARGET_EXAMPLE_FILES += $(TARGET_TRAEFIK_FILES) +$(TARGET_CHROOT)/etc/quadlets/traefik/conf.d/%: other/traefik/% + install -m 0644 -o 10001 -g 10000 $< $@ + +TOP_LEVEL_DIR := .. +include $(TOP_LEVEL_DIR)/Makefile.common + diff --git a/vaultwarden/config/examples/config.env b/vaultwarden/config/examples/config.env new file mode 100644 index 0000000..c19c7c0 --- /dev/null +++ b/vaultwarden/config/examples/config.env @@ -0,0 +1,41 @@ +# Public URL where Vaultwarden will be accessible +DOMAIN=http://vaultwarden + +# Listening address and port +ROCKET_ADDRESS=127.0.0.1 +ROCKET_PORT=8080 + +# Database configuration +DATABASE_URL=postgresql://vaultwarden:vaultwarden@localhost:5432/vaultwarden + +# Generated using the following command: +# echo -n 'Ch4ng3M3!' | argon2 "$(openssl rand -base64 32)" -e -id -k 65540 -t 3 -p 4 +ADMIN_TOKEN=$argon2id$v=19$m=65540,t=3,p=4$cnV0dFVjODhCcDRyR2E1azNRM2NNTDAvamxNUzJpdklrVkpaRmQ5Sm95WT0$mS2zqCE1fTOYSEg0q8pffD2C/6cFctTZQXVxlZ5Of8E + +# Features +SIGNUPS_ALLOWED=true +INVITATIONS_ALLOWED=false + +# Email (SMTP) Configuration +#SMTP_HOST=smtp.gmail.com +#SMTP_FROM= +#SMTP_PORT=587 +#SMTP_SECURITY=starttls +#SMTP_USERNAME= +#SMTP_PASSWORD= + +# Enable Mobile Push Notifications +# Get a key from https://bitwarden.com/host/ +#PUSH_ENABLED=true +#PUSH_INSTALLATION_ID= +#PUSH_INSTALLATION_KEY= +#PUSH_RELAY_URI=https://api.bitwarden.eu +#PUSH_IDENTITY_URI=https://identity.bitwarden.eu + +# Logging Configuration +LOG_LEVEL=info +EXTENDED_LOGGING=true + +# Performance Configuration +#ROCKET_WORKERS=10 +#ROCKET_LIMITS={json=10485760} diff --git a/vaultwarden/fcos.bu b/vaultwarden/fcos.bu new file mode 100644 index 0000000..cd8f01f --- /dev/null +++ b/vaultwarden/fcos.bu @@ -0,0 +1,13 @@ +variant: fcos +version: 1.4.0 +ignition: + config: + merge: + - local: base.ign + - local: traefik.ign + - local: traefik-examples.ign + - local: postgresql.ign + - local: postgresql-examples.ign + - local: vaultwarden.ign + - local: vaultwarden-examples.ign + - local: local.ign diff --git a/vaultwarden/other/postgresql/vaultwarden.sql b/vaultwarden/other/postgresql/vaultwarden.sql new file mode 100644 index 0000000..148e263 --- /dev/null +++ b/vaultwarden/other/postgresql/vaultwarden.sql @@ -0,0 +1,5 @@ +-- Initialization script for Vaultwarden database and user +CREATE USER vaultwarden WITH PASSWORD 'vaultwarden'; +CREATE DATABASE vaultwarden OWNER vaultwarden; +GRANT ALL PRIVILEGES ON DATABASE vaultwarden TO vaultwarden; +ALTER ROLE vaultwarden SET client_encoding TO 'utf8'; \ No newline at end of file diff --git a/vaultwarden/other/traefik/vaultwarden.yaml b/vaultwarden/other/traefik/vaultwarden.yaml new file mode 100644 index 0000000..637c73a --- /dev/null +++ b/vaultwarden/other/traefik/vaultwarden.yaml @@ -0,0 +1,16 @@ +http: + routers: + vaultwarden: + rule: "Host(`vaultwarden`)" + entryPoints: + - http + #- https + middlewares: + service: "vaultwarden" + #tls: + # certResolver: le + services: + vaultwarden: + loadBalancer: + servers: + - url: "http://127.0.0.1:8080" diff --git a/vaultwarden/overlay.bu b/vaultwarden/overlay.bu new file mode 100644 index 0000000..f2abba9 --- /dev/null +++ b/vaultwarden/overlay.bu @@ -0,0 +1,9 @@ +variant: fcos +version: 1.4.0 +passwd: + users: + - name: vaultwarden + uid: 10020 + gecos: Vaultwarden + home_dir: /var/lib/quadlets/vaultwarden + primary_group: itix-svc diff --git a/vaultwarden/tmpfiles.d/vaultwarden.conf b/vaultwarden/tmpfiles.d/vaultwarden.conf new file mode 100644 index 0000000..72786ff --- /dev/null +++ b/vaultwarden/tmpfiles.d/vaultwarden.conf @@ -0,0 +1 @@ +d$ /var/lib/virtiofs/data/vaultwarden 0700 10020 10000 - diff --git a/vaultwarden/vaultwarden.container b/vaultwarden/vaultwarden.container new file mode 100644 index 0000000..b88552e --- /dev/null +++ b/vaultwarden/vaultwarden.container @@ -0,0 +1,48 @@ +[Unit] +Description=Vaultwarden +Documentation=https://github.com/dani-garcia/vaultwarden +After=network.target var-lib-virtiofs-data.mount +Requires=var-lib-virtiofs-data.mount + +# Only start if Vaultwarden has been configured +ConditionPathExists=/etc/quadlets/vaultwarden/config.env + +# Start/stop this unit when the target is started/stopped +PartOf=vaultwarden.target + +[Container] +ContainerName=vaultwarden +Image=quay.io/vaultwarden/server:latest-alpine +AutoUpdate=registry + +# No need for root privileges +User=10020 +Group=10000 + +# Network configuration +Network=host + +# Environment file +EnvironmentFile=/etc/quadlets/vaultwarden/config.env + +# Volume mounts +Volume=/var/lib/virtiofs/data/vaultwarden:/data:z + +# Health check +HealthCmd=curl -sSf http://127.0.0.1:8080/ +HealthInterval=30s +HealthTimeout=10s +HealthStartPeriod=10s +HealthRetries=3 + +[Service] +Restart=always +RestartSec=10 +TimeoutStartSec=120 +TimeoutStopSec=30 + +# Wait for PostgreSQL to be ready on localhost +ExecStartPre=/bin/sh -c 'exec 2>/dev/null; for try in $(seq 0 12); do if ! /bin/true 5<> /dev/tcp/127.0.0.1/5432; then echo "Waiting for PostgreSQL to be available..."; sleep 5; else exit 0; fi; done; exit 1' + +[Install] +WantedBy=vaultwarden.target \ No newline at end of file diff --git a/vaultwarden/vaultwarden.target b/vaultwarden/vaultwarden.target new file mode 100644 index 0000000..4cebe11 --- /dev/null +++ b/vaultwarden/vaultwarden.target @@ -0,0 +1,13 @@ +[Unit] +Description=Vaultwarden Service Target +Documentation=man:systemd.target(5) +Requires=postgresql.target vaultwarden.service +After=postgresql.target vaultwarden.service + +# Allow isolation - can stop/start this target independently +AllowIsolate=yes +# Only start if Vaultwarden has been configured +ConditionPathExists=/etc/quadlets/vaultwarden/config.env + +[Install] +WantedBy=multi-user.target