Stable #1

Merged
nick merged 13 commits from stable into main 2026-10-25 15:54:21 -07:00
8 changed files with 449 additions and 1 deletions

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
name: renovate
on:
schedule:
- cron: "0 */6 * * *"
workflow_dispatch:
jobs:
renovate:
runs-on: ubuntu-latest
container:
image: ghcr.io/renovatebot/renovate:44.181.6
steps:
- name: Run Renovate
run: renovate
env:
RENOVATE_PLATFORM: gitea
RENOVATE_ENDPOINT: https://git.atlashorizon.net/api/v1
RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
RENOVATE_REPOSITORIES: AtlasHorizon/compose
RENOVATE_GIT_AUTHOR: "Renovate Bot <[email protected]>"
GITHUB_COM_TOKEN: ${{ secrets.RENOVATE_GITHUB_COM_TOKEN }}
LOG_LEVEL: info
+86
View File
@@ -0,0 +1,86 @@
# Please see https://github.com/maelgangloff/domain-watchdog
services:
domainwatchdog:
image: ${DOMAIN_WATCHDOG_IMAGE:?set in versions.env}
container_name: domainwatchdog_app
restart: unless-stopped
env_file:
- .env.local
environment:
APP_ENV: prod
SERVER_NAME: ${SERVER_NAME:-:80}
DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages
MESSENGER_RDAP_LOW_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-low
MESSENGER_RDAP_HIGH_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-high
LOCK_DSN: redis://valkey:6379
HTTP_SECURE_COOKIE: true # Change to "false" if you are using HTTP
volumes:
- caddy_data:/data
- caddy_config:/config
- ./public/content:/app/public/content
ports:
- "127.0.0.1:8080:80"
depends_on:
- database
php-worker:
image: ${DOMAIN_WATCHDOG_IMAGE:?set in versions.env}
container_name: domainwatchdog_worker
restart: always
command: php /app/bin/console messenger:consume --all --time-limit=3600 -vvv
env_file:
- .env.local
environment:
APP_ENV: prod
DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
LOCK_DSN: redis://valkey:6379
MESSENGER_ASYNC_TRANSPORT_DSN: redis://valkey:6379/messages
MESSENGER_RDAP_LOW_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-low
MESSENGER_RDAP_HIGH_TRANSPORT_DSN: redis://valkey:6379/messages-rdap-high
MESSENGER_CONSUMER_NAME: worker
depends_on:
- database
healthcheck:
test: [ ]
disable: true
database:
image: ${DOMAIN_WATCHDOG_POSTGRES_IMAGE:?set in versions.env}
container_name: domainwatchdog_db
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB:-app}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!}
POSTGRES_USER: ${POSTGRES_USER:-app}
healthcheck:
test: [ "CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}" ]
timeout: 5s
retries: 5
start_period: 60s
volumes:
- database_data:/var/lib/postgresql/data:rw
valkey:
image: ${DOMAIN_WATCHDOG_VALKEY_IMAGE:?set in versions.env}
container_name: valkey
restart: always
# influxdb2:
# image: influxdb:2
# ports:
# - "127.0.0.1:8086:8086"
# environment:
# DOCKER_INFLUXDB_INIT_MODE: setup
# DOCKER_INFLUXDB_INIT_USERNAME: USERNAME # Please modify
# DOCKER_INFLUXDB_INIT_PASSWORD: PASSWORD # Please modify
# DOCKER_INFLUXDB_INIT_ADMIN_TOKEN: my-super-secret-auth-token # Please modify
# DOCKER_INFLUXDB_INIT_RETENTION: 0
# DOCKER_INFLUXDB_INIT_ORG: domainwatchdog
# DOCKER_INFLUXDB_INIT_BUCKET: domainwatchdog
volumes:
caddy_data:
caddy_config:
database_data:
+1 -1
View File
@@ -1,6 +1,6 @@
services:
grist:
image: gristlabs/grist:latest
image: ${GRIST_IMAGE:?set in versions.env}
restart: unless-stopped
ports:
- "8484:8484"
+133
View File
@@ -0,0 +1,133 @@
# Production Docker Compose Configuration
# Use this for production and self-hosted deployments with proper secrets management
services:
db:
image: ${NAMETAG_POSTGRES_IMAGE:?set in versions.env}
container_name: nametag-db
restart: always
environment:
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: ${DB_NAME}
ports:
- "${DB_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: [CMD-SHELL, "pg_isready -U ${DB_USER} -d ${DB_NAME}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- nametag-network
redis: # Optional. Comment out to disable Redis. See README.md for more details.
image: ${NAMETAG_REDIS_IMAGE:?set in versions.env}
container_name: nametag-redis
restart: always
command: redis-server --requirepass ${REDIS_PASSWORD:?Redis password required}
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
healthcheck:
test: [CMD, redis-cli, --raw, incr, ping]
interval: 10s
timeout: 5s
retries: 5
networks:
- nametag-network
app:
image: ${NAMETAG_IMAGE:?set in versions.env}
container_name: nametag-app
restart: unless-stopped
labels:
com.datadoghq.ad.logs: '[{"source": "nodejs", "service": "nametag"}]'
ports:
- 3000:3000
# TRUSTED_PROXY_HEADER / TRUSTED_PROXY_COUNT (see .env.example /
# docs/self-hosting/reverse-proxy.md) only protect rate limiting if
# this port cannot be reached except through your reverse proxy.
# Publishing it on all interfaces, as above, lets anyone who can reach
# the host bypass the proxy (and the header it sets) entirely. If you
# run a reverse proxy in front of Nametag (recommended for any
# instance reachable from outside your own network), bind this to
# localhost instead so only the proxy on the same host can reach it:
# - "127.0.0.1:3000:3000"
env_file:
- .env
volumes:
- photo_data:/app/data/photos
depends_on:
db:
condition: service_healthy
redis: # Optional. Comment out to disable Redis. See README.md for more details.
condition: service_healthy
healthcheck:
test: [CMD, wget, -q, --spider, http://localhost:3000/api/health]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- nametag-network
- proxy
# Database backup service
backup:
image: ${NAMETAG_BACKUP_IMAGE:?set in versions.env}
container_name: nametag-backup
restart: always
environment:
- POSTGRES_HOST=db
- POSTGRES_DB=${DB_NAME}
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
- SCHEDULE=@daily
- BACKUP_KEEP_DAYS=7
- BACKUP_KEEP_WEEKS=4
- BACKUP_KEEP_MONTHS=6
- HEALTHCHECK_PORT=8080
volumes:
- ./backups:/backups
depends_on:
- db
networks:
- nametag-network
# Cron service for scheduled jobs
cron:
image: ${NAMETAG_CRON_IMAGE:?set in versions.env}
container_name: nametag-cron
restart: always
environment:
- CRON_SECRET=${CRON_SECRET}
depends_on:
- app
command: >
sh -c "
echo '0 8 * * * wget -q -O - --header=\"Authorization: Bearer '\"$$CRON_SECRET\"'\" http://app:3000/api/cron/send-reminders > /proc/1/fd/1 2>&1' > /etc/crontabs/root &&
echo '0 3 * * * wget -q -O - --header=\"Authorization: Bearer '\"$$CRON_SECRET\"'\" http://app:3000/api/cron/purge-deleted > /proc/1/fd/1 2>&1' >> /etc/crontabs/root &&
echo '0 2,10,18 * * * wget -q -O - --header=\"Authorization: Bearer '\"$$CRON_SECRET\"'\" http://app:3000/api/cron/carddav-sync > /proc/1/fd/1 2>&1' >> /etc/crontabs/root &&
echo '*/5 * * * * wget -q -O - --header=\"Authorization: Bearer '\"$$CRON_SECRET\"'\" http://app:3000/api/cron/geocode > /proc/1/fd/1 2>&1' >> /etc/crontabs/root &&
crond -f -l 2
"
networks:
- nametag-network
volumes:
postgres_data:
driver: local
redis_data: # Optional. Comment out to disable Redis. See README.md for more details.
driver: local
photo_data:
driver: local
networks:
nametag-network:
external: true
name: nametag-network
proxy: # for reverse proxy (e.g., Nginx Proxy Manager) to access the app without exposing ports to the outside world
external: true
+34
View File
@@ -0,0 +1,34 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended"],
"customManagers": [
{
"customType": "regex",
"description": "Image tags in versions.env",
"managerFilePatterns": ["/^versions\\.env$/"],
"matchStrings": [
"(?:^|\\n)[A-Z0-9_]+_IMAGE=(?<depName>[^:\\s]+):(?<currentValue>[^\\s@]+)"
],
"datasourceTemplate": "docker"
}
],
"packageRules": [
{
"description": "Database majors need a dump/restore, so never propose them",
"matchDepNames": ["postgres", "prodrigestivill/postgres-backup-local"],
"matchUpdateTypes": ["major"],
"enabled": false
},
{
"description": "Stay on the 10.6 LTS line; 10.11 is effectively a major upgrade",
"matchDepNames": ["mariadb"],
"allowedVersions": "/^10\\.6\\./"
},
{
"matchDepNames": ["amir20/dozzle"],
"prBodyNotes": [
"Also bump the Dozzle agents on the TrueNAS hosts to the same tag. The hub and agents share the TLS pair baked into the image."
]
}
]
}
+30
View File
@@ -0,0 +1,30 @@
# Supernote Private Cloud
Copied from Supernote's official
[docker-compose.yml](https://supernote-private-cloud.supernote.com/cloud/docker-compose.yml),
with these changes:
- **Database init scripts are mounted.** The official file doesn't mount
anything into `docker-entrypoint-initdb.d`, so `supernotedb.sql` never
loads into a new database. This file mounts:
- `supernotedb.sql` → `00-supernotedb.sql` (the schema)
- `supernote-email-init.sql` → `01-supernote-email-init.sql`
- **SMTP settings are pre-loaded.** `supernote-email-init.sql` fills in
`u_email_config`. Registration and password-reset emails then work without
a manual trip to the web UI's "Email Settings" dialog.
- **Database and Redis settings are inline.** The official file loads
`supernote-service`'s `DB_HOSTNAME`, `MYSQL_*` and `REDIS_*` variables from
a separate `.dbenv` file. Here they're set directly in the compose file,
from the same `.env` that mariadb and redis use.
## Notes
- **Init scripts only run once.** They run only against an empty
`sndata/db_data`. The playbook re-applies the SMTP settings with
`docker compose exec` on every run, so changing them in Infisical still
takes effect.
- **Image versions are pinned** (`mariadb:10.6.24`, `redis:7.4.7`,
`notelib:6.9.3`, `supernote-service:26.06.04`). To upgrade, change the tags
here and push to `stable`.
- **Check Supernote's file when upgrading.** Compare against the official
file in case they've added services or variables.
+89
View File
@@ -0,0 +1,89 @@
services:
mariadb:
image: ${SUPERNOTE_MARIADB_IMAGE:?set in versions.env}
container_name: mariadb
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: supernotedb
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
TZ: ${TZ:-UTC}
command: --skip-name-resolve --bind-address=0.0.0.0
volumes:
- ./sndata/db_data:/var/lib/mysql
- ./sndata/config/mysql/conf.d:/etc/mysql/conf.d:ro
- ./supernotedb.sql:/docker-entrypoint-initdb.d/00-supernotedb.sql:ro
- ./supernote-email-init.sql:/docker-entrypoint-initdb.d/01-supernote-email-init.sql:ro
- /etc/localtime:/etc/localtime:ro
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h localhost -u root -p$$MYSQL_ROOT_PASSWORD || exit 1"]
interval: 10s
timeout: 5s
retries: 10
start_period: 30s
restart: unless-stopped
redis:
image: ${SUPERNOTE_REDIS_IMAGE:?set in versions.env}
container_name: redis
environment:
TZ: ${TZ:-UTC}
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"]
volumes:
- ./sndata/redis_data:/data
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 3
notelib:
image: ${SUPERNOTE_NOTELIB_IMAGE:?set in versions.env}
container_name: notelib
environment:
TZ: ${TZ:-UTC}
volumes:
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
supernote-service:
image: ${SUPERNOTE_SERVICE_IMAGE:?set in versions.env}
container_name: supernote-service
depends_on:
mariadb:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "19071:19071"
- "18072:18072"
- "${FRONTEND_PORT:-19072}:8080"
- "${DOMAIN_PORT:-8199}:8080"
environment:
EXTERNAL_PORT_BACKEND: "19071"
EXTERNAL_PORT_FRONTEND: ${FRONTEND_PORT:-19072}
EXTERNAL_PORT_DOMAIN: ${DOMAIN_PORT:-8199}
TZ: ${TZ:-UTC}
DB_HOSTNAME: mariadb
MYSQL_DATABASE: supernotedb
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
REDIS_HOST: redis
REDIS_PORT: 6379
REDIS_PASSWORD: ${REDIS_PASSWORD}
volumes:
- ./sndata/recycle:/home/supernote/recycle
- ./supernote_data:/home/supernote/data
- ./sndata/logs/cloud:/home/supernote/cloud/logs
- ./sndata/logs/app:/home/supernote/logs
- ./sndata/logs/web:/var/log/nginx
- ./sndata/convert:/home/supernote/convert
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
+53
View File
@@ -0,0 +1,53 @@
# Central image versions for AtlasHorizon/compose.
# Each compose file reads its images from here via ${VAR:?}; Ansible
# downloads this next to docker-compose.yml and passes it as a second
# --env-file. One variable per service+component, so e.g. each Postgres
# can be upgraded independently (major bumps need a dump/restore).
# --- grist ---
GRIST_IMAGE=gristlabs/grist:1.7.21
# --- domain-watchdog ---
# App and worker must stay on the same version.
DOMAIN_WATCHDOG_IMAGE=maelgangloff/domain-watchdog:v1.4.6
# Major must match POSTGRES_VERSION in domain-watchdog's .env (used in DATABASE_URL).
DOMAIN_WATCHDOG_POSTGRES_IMAGE=postgres:16.15-alpine
DOMAIN_WATCHDOG_VALKEY_IMAGE=valkey/valkey:9.1.2
# --- nametag ---
NAMETAG_IMAGE=ghcr.io/mattogodoy/nametag:0.66.0
NAMETAG_POSTGRES_IMAGE=postgres:16.15-alpine
NAMETAG_REDIS_IMAGE=redis:7.4.11-alpine
# Keep the major in line with NAMETAG_POSTGRES_IMAGE.
NAMETAG_BACKUP_IMAGE=prodrigestivill/postgres-backup-local:16-alpine
NAMETAG_CRON_IMAGE=alpine:3.24.3
# --- supernote ---
SUPERNOTE_MARIADB_IMAGE=mariadb:10.6.24
SUPERNOTE_REDIS_IMAGE=redis:7.4.7
SUPERNOTE_NOTELIB_IMAGE=docker.io/supernote/notelib:6.9.3
SUPERNOTE_SERVICE_IMAGE=docker.io/supernote/supernote-service:26.06.04
# --- monitor (Flatcar) ---
# The hub and agents share the TLS pair baked into the image, so this must
# match the agent tag on ai, oswald_runner, oswl_connector and the TrueNAS hosts.
DOZZLE_IMAGE=amir20/dozzle:v11.1.1
ALERTA_IMAGE=alerta/alerta-web:9.1.0
# --- ai (Flatcar) ---
GITEA_MCP_IMAGE=docker.gitea.com/gitea-mcp-server:1.11.0
LITELLM_IMAGE=docker.litellm.ai/berriai/litellm:v1.106.4
QDRANT_IMAGE=qdrant/qdrant:v1.19.1
OPEN_TERMINAL_IMAGE=ghcr.io/open-webui/open-terminal:0.14.0
OPEN_WEBUI_IMAGE=ghcr.io/open-webui/open-webui:v0.11.4
OPENCODE_IMAGE=ghcr.io/anomalyco/opencode:1.18.32
# --- oswald_runner (Flatcar) ---
GITEA_RUNNER_IMAGE=docker.io/gitea/runner:3.5.0
N8N_IMAGE=docker.n8n.io/n8nio/n8n:2.40.5
CISA_KEV_RSS_IMAGE=ghcr.io/xsaveopt/cisa-kev-rss:0.0.5
# Domain Watchdog here shares DOMAIN_WATCHDOG_IMAGE and
# DOMAIN_WATCHDOG_VALKEY_IMAGE with the compose deployment.
# --- oswl_connector (Flatcar) ---
TAILSCALE_IMAGE=docker.io/tailscale/tailscale:v1.104.2