130 lines
5.2 KiB
Plaintext
130 lines
5.2 KiB
Plaintext
variant: flatcar
|
|
version: 1.0.0
|
|
|
|
systemd:
|
|
units:
|
|
# Gitea Actions runner. Registers once on first start and keeps its
|
|
# identity (the .runner file) in /var/lib/oswald_runner on the VM's own
|
|
# root disk -- not ephemeral, so it does not self-delete after each job
|
|
# (that caused stale offline entries whenever the container was
|
|
# interrupted before finishing a job; see flatcar-todo.md). Reusing the
|
|
# same registration also means the token never needs rotating.
|
|
#
|
|
# /var/lib/oswald_runner survives container restarts and VM reboots (it's
|
|
# on disk, not in the container), but not a VM rebuild (taint): that
|
|
# recreates the disk from the image, so the runner re-registers fresh
|
|
# next boot. Old entries from before this change, or from any future
|
|
# rebuild, still need manual cleanup in Gitea's runner admin page.
|
|
#
|
|
# GITEA_RUNNER_REGISTRATION_TOKEN is templated in from Infisical
|
|
# (GITEA_RUNNER_TOKEN in secrets.tmpl) by main.tf, not stored here. It
|
|
# still ends up in plaintext in the rendered Ignition snippet on the
|
|
# node's storage -- see the caveat in flatcar-todo.md.
|
|
- name: oswald_runner.service
|
|
enabled: true
|
|
contents: |
|
|
[Unit]
|
|
Description=Gitea Actions runner
|
|
After=docker.service
|
|
Requires=docker.service
|
|
[Service]
|
|
TimeoutStartSec=0
|
|
ExecStartPre=-/usr/bin/docker rm --force oswald_runner
|
|
ExecStart=/usr/bin/docker run --name oswald_runner \
|
|
-e GITEA_INSTANCE_URL=https://git.atlashorizon.net \
|
|
-e GITEA_RUNNER_REGISTRATION_TOKEN=${gitea_runner_token} \
|
|
-e GITEA_RUNNER_NAME=oswald_runner \
|
|
-v /var/lib/oswald_runner:/data \
|
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
docker.io/gitea/runner:3
|
|
ExecStop=/usr/bin/docker stop oswald_runner
|
|
Restart=always
|
|
RestartSec=5s
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
# n8n workflow automation, served publicly at n8n.atlashorizon.net.
|
|
#
|
|
# Prerequisites, all of which must exist before the VM is rebuilt:
|
|
# - an "n8n" Postgres database and role on argo.lan.atlashorizon.net
|
|
# - N8N_DB_PASSWORD and N8N_ENCRYPTION_KEY in Infisical (see
|
|
# secrets.tmpl); generate the key with `openssl rand -hex 32`
|
|
# - n8n.atlashorizon.net terminating TLS and proxying to this host's
|
|
# :5678 (not managed here)
|
|
#
|
|
# Workflows, credentials and execution history all live in Postgres, so
|
|
# a taint loses nothing. The encryption key is what makes that true:
|
|
# without a fixed one n8n generates its own under /home/node/.n8n, and
|
|
# the credentials in Postgres become undecryptable the moment the VM
|
|
# disk goes. Never rotate it without re-entering every credential.
|
|
- name: n8n.service
|
|
enabled: true
|
|
contents: |
|
|
[Unit]
|
|
Description=n8n workflow automation
|
|
After=docker.service
|
|
Requires=docker.service
|
|
[Service]
|
|
TimeoutStartSec=0
|
|
ExecStartPre=/usr/bin/docker pull docker.n8n.io/n8nio/n8n:2.40.5
|
|
ExecStartPre=-/usr/bin/docker rm --force n8n
|
|
# /var/lib/n8n holds only what is left in /home/node/.n8n once the
|
|
# database and key are external: installed community nodes and
|
|
# n8n's own config file. Losing it to a taint means reinstalling
|
|
# community nodes, nothing more.
|
|
#
|
|
# N8N_PROXY_HOPS=1: requests arrive through the reverse proxy, so
|
|
# n8n takes the client IP from X-Forwarded-For (rate limiting and
|
|
# audit logs would otherwise see only the proxy).
|
|
ExecStart=/usr/bin/docker run --name n8n \
|
|
-e DB_TYPE=postgresdb \
|
|
-e DB_POSTGRESDB_HOST=argo.lan.atlashorizon.net \
|
|
-e DB_POSTGRESDB_PORT=5432 \
|
|
-e DB_POSTGRESDB_DATABASE=n8n \
|
|
-e DB_POSTGRESDB_USER=n8n \
|
|
-e DB_POSTGRESDB_PASSWORD=${n8n_db_password} \
|
|
-e N8N_ENCRYPTION_KEY=${n8n_encryption_key} \
|
|
-e N8N_HOST=n8n.atlashorizon.net \
|
|
-e N8N_PROTOCOL=https \
|
|
-e WEBHOOK_URL=https://n8n.atlashorizon.net/ \
|
|
-e N8N_PROXY_HOPS=1 \
|
|
-v /var/lib/n8n:/home/node/.n8n \
|
|
-p 5678:5678 \
|
|
docker.n8n.io/n8nio/n8n:2.40.5
|
|
ExecStop=/usr/bin/docker stop n8n
|
|
Restart=always
|
|
RestartSec=5s
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
- name: dozzle-agent.service
|
|
enabled: true
|
|
contents: |
|
|
[Unit]
|
|
Description=Dozzle Agent
|
|
After=docker.service
|
|
Requires=docker.service
|
|
[Service]
|
|
TimeoutStartSec=0
|
|
ExecStartPre=-/usr/bin/docker rm --force dozzle-agent
|
|
ExecStart=/usr/bin/docker run --name dozzle-agent \
|
|
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
-p 7007:7007 \
|
|
amir20/dozzle:v11.1.1 agent
|
|
ExecStop=/usr/bin/docker stop dozzle-agent
|
|
Restart=always
|
|
RestartSec=5s
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
|
|
storage:
|
|
directories:
|
|
- path: /var/lib/oswald_runner
|
|
mode: 0755
|
|
# The n8n image runs as the "node" user (uid 1000), which needs to own
|
|
# its data directory.
|
|
- path: /var/lib/n8n
|
|
mode: 0700
|
|
user:
|
|
id: 1000
|
|
group:
|
|
id: 1000
|