| author | |
| committer | |
| log | f9eb79553ff10e71e7957c722bd47c7e82ccc543 |
| tree | 484d2bdcffeef3a0bb17d8b41dbe25ba83919e49 |
| parent | 7660b1882cbb0f3a9d41fae2ec3fe1c4182f568d |
| signature |
9 files changed, 352 insertions(+), 3 deletions(-)
compose.yaml+147| ... | @@ -215,6 +215,76 @@ services: | ... | @@ -215,6 +215,76 @@ services: |
| 215 | - "${APP_ROOT}/forgejo-runner:/data" | 215 | - "${APP_ROOT}/forgejo-runner:/data" |
| 216 | restart: unless-stopped | 216 | restart: unless-stopped |
| 217 | command: forgejo-runner daemon | 217 | command: forgejo-runner daemon |
| 218 | knot: # port 22 | ||
| 219 | container_name: knot | ||
| 220 | image: knot:latest | ||
| 221 | build: | ||
| 222 | context: https://tangled.org/tangled.org/3lqs6zdi4nt22.git | ||
| 223 | dockerfile: Dockerfile | ||
| 224 | args: | ||
| 225 | TAG: "${KNOT_IMAGE_TAG:-v1.14.0-alpha}" | ||
| 226 | UID: "${USER_ID:?}" | ||
| 227 | GID: "${GROUP_ID:?}" | ||
| 228 | pull_policy: build | ||
| 229 | depends_on: | ||
| 230 | knot-init: | ||
| 231 | condition: service_completed_successfully | ||
| 232 | environment: | ||
| 233 | KNOT_SERVER_HOSTNAME: "knot.${HOME_DOMAIN:?}" | ||
| 234 | KNOT_SERVER_OWNER: "${KNOT_SERVER_OWNER:?}" | ||
| 235 | KNOT_SERVER_DB_PATH: /app/knotserver.db | ||
| 236 | KNOT_REPO_SCAN_PATH: /home/git/repositories | ||
| 237 | KNOT_SERVER_INTERNAL_LISTEN_ADDR: localhost:5444 | ||
| 238 | APPVIEW_ENDPOINT: "${KNOT_APPVIEW_ENDPOINT:-https://tangled.org}" | ||
| 239 | ports: | ||
| 240 | - "${KNOT_SSH_PORT:-2222}:22" | ||
| 241 | restart: unless-stopped | ||
| 242 | volumes: | ||
| 243 | - "${APP_ROOT}/knot/keys:/etc/ssh/keys" | ||
| 244 | - "${APP_ROOT}/knot/repositories:/home/git/repositories" | ||
| 245 | - "${APP_ROOT}/knot/server:/app" | ||
| 246 | labels: | ||
| 247 | net.paperclover.list.name: Tangled Knot | ||
| 248 | net.paperclover.list.domain: knot | ||
| 249 | net.paperclover.list.priority: 106 | ||
| 250 | knot-init: | ||
| 251 | container_name: knot-init | ||
| 252 | image: alpine:3.22 | ||
| 253 | user: "0:0" | ||
| 254 | command: ["sh", "-c", "chown -R ${USER_ID:?}:${GROUP_ID:?} /knot"] | ||
| 255 | volumes: | ||
| 256 | - "${APP_ROOT}/knot:/knot" | ||
| 257 | spindle: # port 6555 | ||
| 258 | container_name: spindle | ||
| 259 | build: | ||
| 260 | context: ./config/spindle | ||
| 261 | dockerfile: Dockerfile | ||
| 262 | args: | ||
| 263 | TAG: "${SPINDLE_IMAGE_TAG:-v1.14.0-alpha}" | ||
| 264 | pull_policy: build | ||
| 265 | depends_on: | ||
| 266 | docker-in-docker: | ||
| 267 | condition: service_started | ||
| 268 | environment: | ||
| 269 | DOCKER_HOST: tcp://docker-in-docker:2375 | ||
| 270 | SPINDLE_SERVER_HOSTNAME: "spindle.${HOME_DOMAIN:?}" | ||
| 271 | SPINDLE_SERVER_OWNER: "${SPINDLE_SERVER_OWNER:?}" | ||
| 272 | SPINDLE_SERVER_DB_PATH: /data/spindle.db | ||
| 273 | SPINDLE_SERVER_LOG_DIR: /data/logs | ||
| 274 | SPINDLE_SERVER_TAP_EMBED: "true" | ||
| 275 | SPINDLE_SERVER_TAP_URL: http://127.0.0.1:2480 | ||
| 276 | SPINDLE_SERVER_TAP_BIND: 127.0.0.1:2480 | ||
| 277 | SPINDLE_SERVER_TAP_DB_PATH: /data/tap.db | ||
| 278 | SPINDLE_NIXERY_PIPELINES_NIXERY: "${SPINDLE_NIXERY_PIPELINES_NIXERY:-nixery.tangled.sh}" | ||
| 279 | SPINDLE_NIXERY_PIPELINES_WORKFLOW_TIMEOUT: "${SPINDLE_NIXERY_PIPELINES_WORKFLOW_TIMEOUT:-10m}" | ||
| 280 | user: "$USER_ID:$GROUP_ID" | ||
| 281 | restart: unless-stopped | ||
| 282 | volumes: | ||
| 283 | - "${APP_ROOT}/spindle:/data" | ||
| 284 | labels: | ||
| 285 | net.paperclover.list.name: Tangled Spindle | ||
| 286 | net.paperclover.list.domain: spindle | ||
| 287 | net.paperclover.list.priority: 107 | ||
| 218 | docker-in-docker: | 288 | docker-in-docker: |
| 219 | container_name: docker-in-docker | 289 | container_name: docker-in-docker |
| 220 | image: docker:dind | 290 | image: docker:dind |
| ... | @@ -380,6 +450,43 @@ services: | ... | @@ -380,6 +450,43 @@ services: |
| 380 | net.paperclover.list.domain: opencode | 450 | net.paperclover.list.domain: opencode |
| 381 | net.paperclover.list.priority: 70 | 451 | net.paperclover.list.priority: 70 |
| 382 | net.paperclover.list.access: personal | 452 | net.paperclover.list.access: personal |
| 453 | # AT Protocol account hosting | ||
| 454 | pds: # port 3000 | ||
| 455 | container_name: pds | ||
| 456 | image: ghcr.io/bluesky-social/pds:0.4 | ||
| 457 | entrypoint: ["/bin/sh", "/custom/pds-entry.sh"] | ||
| 458 | user: "0:0" | ||
| 459 | restart: unless-stopped | ||
| 460 | environment: | ||
| 461 | HOME_DOMAIN: "${HOME_DOMAIN:?}" | ||
| 462 | PDS_HOSTNAME: "at.${HOME_DOMAIN:?}" | ||
| 463 | PDS_JWT_SECRET: "${PDS_JWT_SECRET:?}" | ||
| 464 | PDS_ADMIN_PASSWORD: "${PDS_ADMIN_PASSWORD:?}" | ||
| 465 | PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX: "${PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX:?}" | ||
| 466 | PDS_DATA_DIRECTORY: /pds | ||
| 467 | PDS_BLOBSTORE_DISK_LOCATION: /pds/blocks | ||
| 468 | PDS_DID_PLC_URL: https://plc.directory | ||
| 469 | PDS_BSKY_APP_VIEW_URL: https://api.bsky.app | ||
| 470 | PDS_BSKY_APP_VIEW_DID: did:web:api.bsky.app | ||
| 471 | PDS_REPORT_SERVICE_URL: https://mod.bsky.app | ||
| 472 | PDS_REPORT_SERVICE_DID: did:plc:ar7c4by46qjdydhdevvrndac | ||
| 473 | PDS_CRAWLERS: https://bsky.network | ||
| 474 | LOG_ENABLED: "true" | ||
| 475 | PDS_RATE_LIMITS_ENABLED: "${PDS_RATE_LIMITS_ENABLED:-true}" | ||
| 476 | PDS_INVITE_REQUIRED: "${PDS_INVITE_REQUIRED:-false}" | ||
| 477 | MAILER_ADDRESS: "${MAILER_ADDRESS}" | ||
| 478 | MAILER_USERNAME: "${MAILER_USERNAME}" | ||
| 479 | MAILER_PASSWORD: "${MAILER_PASSWORD}" | ||
| 480 | PDS_CONTACT_EMAIL_ADDRESS: "${PDS_CONTACT_EMAIL_ADDRESS:?}" | ||
| 481 | volumes: | ||
| 482 | - "${APP_ROOT}/pds:/pds" | ||
| 483 | - "./config/pds-entry.sh:/custom/pds-entry.sh:ro" | ||
| 484 | healthcheck: | ||
| 485 | test: ["CMD", "wget", "--quiet", "--spider", "http://127.0.0.1:3000/xrpc/_health"] | ||
| 486 | interval: 10s | ||
| 487 | timeout: 5s | ||
| 488 | retries: 12 | ||
| 489 | start_period: 20s | ||
| 383 | # databases | 490 | # databases |
| 384 | postgres: | 491 | postgres: |
| 385 | container_name: postgres | 492 | container_name: postgres |
| ... | @@ -552,6 +659,46 @@ services: | ... | @@ -552,6 +659,46 @@ services: |
| 552 | net.paperclover.list.domain: sync | 659 | net.paperclover.list.domain: sync |
| 553 | net.paperclover.list.priority: 31 | 660 | net.paperclover.list.priority: 31 |
| 554 | net.paperclover.list.access: personal | 661 | net.paperclover.list.access: personal |
| 662 | # chat | ||
| 663 | xmpp: # ports 5222, 5269 | ||
| 664 | container_name: xmpp | ||
| 665 | build: | ||
| 666 | context: ./config/xmpp | ||
| 667 | dockerfile: Dockerfile | ||
| 668 | pull_policy: build | ||
| 669 | ports: | ||
| 670 | - 5222:5222 | ||
| 671 | - 5269:5269 | ||
| 672 | - 5000:5000 | ||
| 673 | environment: | ||
| 674 | USER_ID: "$USER_ID" | ||
| 675 | GROUP_ID: "$GROUP_ID" | ||
| 676 | XMPP_HOSTNAME: "xmpp.${HOME_DOMAIN:?}" | ||
| 677 | XMPP_ADMIN_USER: "${XMPP_ADMIN_USER:?}" | ||
| 678 | XMPP_ADMIN_PASSWORD: "${XMPP_ADMIN_PASSWORD:?}" | ||
| 679 | ACME_EMAIL: "${ADMIN_EMAIL:?}" | ||
| 680 | PROSODY_VIRTUAL_HOSTS: "xmpp.${HOME_DOMAIN:?}" | ||
| 681 | PROSODY_NETWORK_HOSTNAME: "xmpp.${HOME_DOMAIN:?}" | ||
| 682 | PROSODY_ADMINS: "${XMPP_ADMIN_USER:?}@xmpp.${HOME_DOMAIN:?}" | ||
| 683 | PROSODY_COMPONENTS: "conference.xmpp.${HOME_DOMAIN:?}:muc,upload.xmpp.${HOME_DOMAIN:?}:http_file_share,proxy.xmpp.${HOME_DOMAIN:?}:proxy65" | ||
| 684 | PROSODY_MUC_MODULES: "muc_mam,muc_unique" | ||
| 685 | PROSODY_UPLOAD_LIMIT_MB: "100" | ||
| 686 | PROSODY_UPLOAD_STORAGE_GB: "10" | ||
| 687 | PROSODY_RETENTION_DAYS: "7" | ||
| 688 | PROSODY_LOGLEVEL: "info" | ||
| 689 | restart: unless-stopped | ||
| 690 | volumes: | ||
| 691 | - "${APP_ROOT}/xmpp/data:/var/lib/prosody" | ||
| 692 | - "${APP_ROOT}/xmpp/certs:/etc/prosody/certs" | ||
| 693 | - "${APP_ROOT}/xmpp/letsencrypt:/etc/letsencrypt" | ||
| 694 | - "./config/xmpp/conf.d:/etc/prosody/conf.d:ro" | ||
| 695 | labels: | ||
| 696 | net.paperclover.list.name: Paper Clover XMPP | ||
| 697 | net.paperclover.list.domain: xmpp | ||
| 698 | net.paperclover.list.priority: 108 | ||
| 699 | depends_on: | ||
| 700 | caddy: | ||
| 701 | condition: service_started | ||
| 555 | # administration | 702 | # administration |
| 556 | openspeedtest: # port 3000 | 703 | openspeedtest: # port 3000 |
| 557 | restart: unless-stopped | 704 | restart: unless-stopped |
config/Caddyfile+44-2| ... | @@ -114,6 +114,15 @@ jkt.{$HOME_DOMAIN} { | ... | @@ -114,6 +114,15 @@ jkt.{$HOME_DOMAIN} { |
| 114 | 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" | 114 | 		header_up Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=" |
| 115 | 	} | 115 | 	} |
| 116 | } | 116 | } |
| 117 | at.{$HOME_DOMAIN} { | ||
| 118 | 	reverse_proxy "http://pds:3000" | ||
| 119 | } | ||
| 120 | knot.{$HOME_DOMAIN} { | ||
| 121 | 	reverse_proxy "http://knot:5555" | ||
| 122 | } | ||
| 123 | spindle.{$HOME_DOMAIN} { | ||
| 124 | 	reverse_proxy "http://spindle:6555" | ||
| 125 | } | ||
| 117 | music.{$HOME_DOMAIN} { | 126 | music.{$HOME_DOMAIN} { |
| 118 | 	handle_path /app/sw.js { | 127 | 	handle_path /app/sw.js { |
| 119 | header Content-Type "application/javascript" | 128 | header Content-Type "application/javascript" |
| ... | @@ -189,6 +198,41 @@ speedtest.{$HOME_DOMAIN} { | ... | @@ -189,6 +198,41 @@ speedtest.{$HOME_DOMAIN} { |
| 189 | sync.{$HOME_DOMAIN} { | 198 | sync.{$HOME_DOMAIN} { |
| 190 | 	import reverse_proxy_auth "http://syncthing:8384" admin | 199 | 	import reverse_proxy_auth "http://syncthing:8384" admin |
| 191 | } | 200 | } |
| 201 | xmpp.{$HOME_DOMAIN} { | ||
| 202 | 	tls { | ||
| 203 | 		on_demand | ||
| 204 | 	} | ||
| 205 | |||
| 206 | 	handle /share* { | ||
| 207 | 		reverse_proxy "https://xmpp:5281" { | ||
| 208 | 			transport http { | ||
| 209 | 				tls_server_name xmpp.{$HOME_DOMAIN} | ||
| 210 | 				tls_insecure_skip_verify | ||
| 211 | 			} | ||
| 212 | 		} | ||
| 213 | 	} | ||
| 214 | |||
| 215 | 	handle /xmpp-websocket* { | ||
| 216 | 		reverse_proxy "https://xmpp:5281" { | ||
| 217 | 			transport http { | ||
| 218 | 				tls_server_name xmpp.{$HOME_DOMAIN} | ||
| 219 | 				tls_insecure_skip_verify | ||
| 220 | 			} | ||
| 221 | 		} | ||
| 222 | 	} | ||
| 223 | |||
| 224 | 	header Content-Type "text/plain; charset=utf-8" | ||
| 225 | 	respond "XMPP service. Use port 5222 for clients and port 5269 for federation." 200 | ||
| 226 | } | ||
| 227 | |||
| 228 | http://xmpp.{$HOME_DOMAIN} { | ||
| 229 | 	handle /.well-known/acme-challenge/* { | ||
| 230 | 		reverse_proxy "http://xmpp:80" | ||
| 231 | 	} | ||
| 232 | |||
| 233 | 	header Content-Type "text/plain; charset=utf-8" | ||
| 234 | 	respond "XMPP service. Use port 5222 for clients and port 5269 for federation." 200 | ||
| 235 | } | ||
| 192 | 236 | ||
| 193 | # evil inc temporary infrastructure | 237 | # evil inc temporary infrastructure |
| 194 | git.evil.inc { | 238 | git.evil.inc { |
| ... | @@ -241,5 +285,3 @@ nas.paperclover.net { | ... | @@ -241,5 +285,3 @@ nas.paperclover.net { |
| 241 | local.test, *.local.test { | 285 | local.test, *.local.test { |
| 242 | 	tls internal | 286 | 	tls internal |
| 243 | } | 287 | } |
| 244 | |||
| 245 |
config/pds-entry.sh created+24| ... | @@ -0,0 +1,24 @@ | ||
| 1 | #!/bin/sh | ||
| 2 | set -eu | ||
| 3 | |||
| 4 | encode_uri_component() { | ||
| 5 | node -e 'process.stdout.write(encodeURIComponent(process.argv[1]))' "$1" | ||
| 6 | } | ||
| 7 | |||
| 8 | : "${MAILER_ADDRESS:?Missing MAILER_ADDRESS}" | ||
| 9 | : "${MAILER_USERNAME:?Missing MAILER_USERNAME}" | ||
| 10 | : "${MAILER_PASSWORD:?Missing MAILER_PASSWORD}" | ||
| 11 | : "${HOME_DOMAIN:?Missing HOME_DOMAIN}" | ||
| 12 | |||
| 13 | # PDS expects a single SMTP URL, so encode credentials before composing it. | ||
| 14 | mailer_username=$(encode_uri_component "$MAILER_USERNAME") | ||
| 15 | mailer_password=$(encode_uri_component "$MAILER_PASSWORD") | ||
| 16 | export PDS_EMAIL_SMTP_URL="smtps://${mailer_username}:${mailer_password}@${MAILER_ADDRESS}:465/" | ||
| 17 | export PDS_EMAIL_FROM_ADDRESS="noreply@${HOME_DOMAIN}" | ||
| 18 | |||
| 19 | |||
| 20 | if [ "$#" -eq 0 ]; then | ||
| 21 | set -- node --enable-source-maps index.js | ||
| 22 | fi | ||
| 23 | |||
| 24 | exec dumb-init -- "$@" | ||
config/spindle/Dockerfile created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | FROM golang:1.25-alpine AS builder | ||
| 2 | ENV CGO_ENABLED=1 | ||
| 3 | |||
| 4 | ARG TAG="v1.14.0-alpha" | ||
| 5 | |||
| 6 | WORKDIR /app | ||
| 7 | RUN apk add --no-cache git gcc musl-dev | ||
| 8 | RUN git clone -b "${TAG}" https://tangled.org/@tangled.org/core . | ||
| 9 | RUN go build -o /usr/local/bin/spindle -ldflags '-s -w -extldflags "-static"' ./cmd/spindle | ||
| 10 | |||
| 11 | FROM alpine:latest | ||
| 12 | RUN apk add --no-cache ca-certificates | ||
| 13 | COPY --from=builder /usr/local/bin/spindle /usr/local/bin/spindle | ||
| 14 | COPY entry.sh /entry.sh | ||
| 15 | EXPOSE 6555 | ||
| 16 | ENTRYPOINT ["/bin/sh", "/entry.sh"] | ||
config/spindle/entry.sh created+5| ... | @@ -0,0 +1,5 @@ | ||
| 1 | #!/bin/sh | ||
| 2 | set -e | ||
| 3 | |||
| 4 | mkdir -p "${SPINDLE_SERVER_LOG_DIR:-/data/logs}" | ||
| 5 | exec /usr/local/bin/spindle | ||
config/xmpp/Dockerfile created+11| ... | @@ -0,0 +1,11 @@ | ||
| 1 | FROM prosodyim/prosody:13.0 | ||
| 2 | |||
| 3 | RUN apt-get update \ | ||
| 4 | && apt-get install -y --no-install-recommends certbot \ | ||
| 5 | && rm -rf /var/lib/apt/lists/* | ||
| 6 | |||
| 7 | COPY entry.sh /entry.sh | ||
| 8 | RUN chmod 755 /entry.sh | ||
| 9 | |||
| 10 | ENTRYPOINT ["/usr/bin/tini", "--", "/entry.sh"] | ||
| 11 | CMD ["prosody", "-F"] | ||
config/xmpp/conf.d/paperclover.cfg.lua created+16| ... | @@ -0,0 +1,16 @@ | ||
| 1 | allow_registration = true | ||
| 2 | c2s_require_encryption = true | ||
| 3 | http_external_url = "https://" .. Lua.os.getenv("XMPP_HOSTNAME") .. "/" | ||
| 4 | contact_info = { | ||
| 5 | abuse = { "mailto:" .. Lua.os.getenv("ACME_EMAIL") }; | ||
| 6 | admin = { "mailto:" .. Lua.os.getenv("ACME_EMAIL") }; | ||
| 7 | } | ||
| 8 | |||
| 9 | modules_enabled:append({ | ||
| 10 | "cloud_notify"; | ||
| 11 | "smacks"; | ||
| 12 | "csi"; | ||
| 13 | "csi_simple"; | ||
| 14 | "server_contact_info"; | ||
| 15 | "websocket"; | ||
| 16 | }) | ||
config/xmpp/entry.sh created+60| ... | @@ -0,0 +1,60 @@ | ||
| 1 | #!/bin/bash | ||
| 2 | set -euo pipefail | ||
| 3 | |||
| 4 | if [[ "${1:-}" != "prosody" ]]; then | ||
| 5 | exec prosodyctl "$@" | ||
| 6 | fi | ||
| 7 | |||
| 8 | host_uid="${USER_ID:-}" | ||
| 9 | host_gid="${GROUP_ID:-}" | ||
| 10 | |||
| 11 | if [[ -n "$host_gid" ]]; then | ||
| 12 | groupmod -o -g "$host_gid" prosody | ||
| 13 | fi | ||
| 14 | |||
| 15 | if [[ -n "$host_uid" ]]; then | ||
| 16 | usermod -o -u "$host_uid" prosody | ||
| 17 | fi | ||
| 18 | |||
| 19 | mkdir -p /etc/prosody/certs /var/lib/prosody /var/run/prosody | ||
| 20 | chown -R prosody:prosody /etc/prosody/certs /var/lib/prosody /var/run/prosody | ||
| 21 | |||
| 22 | install_acme_cert() { | ||
| 23 | local host="$1" | ||
| 24 | local live_dir="/etc/letsencrypt/live/$host" | ||
| 25 | |||
| 26 | if [[ -f "$live_dir/fullchain.pem" ]]; then | ||
| 27 | certbot renew --non-interactive --quiet || true | ||
| 28 | else | ||
| 29 | certbot certonly \ | ||
| 30 | --standalone \ | ||
| 31 | --http-01-port 80 \ | ||
| 32 | --preferred-challenges http \ | ||
| 33 | --non-interactive \ | ||
| 34 | --agree-tos \ | ||
| 35 | --email "${ACME_EMAIL:?}" \ | ||
| 36 | -d "$host" | ||
| 37 | fi | ||
| 38 | |||
| 39 | cp "$live_dir/fullchain.pem" "/etc/prosody/certs/$host.crt" | ||
| 40 | cp "$live_dir/privkey.pem" "/etc/prosody/certs/$host.key" | ||
| 41 | chown prosody:prosody "/etc/prosody/certs/$host.crt" "/etc/prosody/certs/$host.key" | ||
| 42 | chmod 640 "/etc/prosody/certs/$host.key" | ||
| 43 | } | ||
| 44 | |||
| 45 | register_account() { | ||
| 46 | local username="$1" | ||
| 47 | local password="$2" | ||
| 48 | local host="$3" | ||
| 49 | |||
| 50 | if [[ -z "$username" || -z "$password" ]]; then | ||
| 51 | return 0 | ||
| 52 | fi | ||
| 53 | |||
| 54 | runuser -u prosody -- prosodyctl register "$username" "$host" "$password" >/dev/null 2>&1 || true | ||
| 55 | } | ||
| 56 | |||
| 57 | install_acme_cert "${XMPP_HOSTNAME:?}" | ||
| 58 | register_account "${XMPP_ADMIN_USER:-}" "${XMPP_ADMIN_PASSWORD:-}" "${XMPP_HOSTNAME:?}" | ||
| 59 | |||
| 60 | exec runuser -u prosody -- "$@" | ||
generate-env.sh+29-1| ... | @@ -3,7 +3,7 @@ set -e | ... | @@ -3,7 +3,7 @@ set -e |
| 3 | 3 | ||
| 4 | FILE=${1:-.env} | 4 | FILE=${1:-.env} |
| 5 | if [ -f "$FILE" ]; then | 5 | if [ -f "$FILE" ]; then |
| 6 | printf '\033[33mwarning: %d exists\033[0m\n' "$FILE" | 6 | printf '\033[33mwarning: %s exists\033[0m\n' "$FILE" |
| 7 | exit 1 | 7 | exit 1 |
| 8 | fi | 8 | fi |
| 9 | 9 | ||
| ... | @@ -28,6 +28,14 @@ template() { | ... | @@ -28,6 +28,14 @@ template() { |
| 28 | add "MAILER_USERNAME" "" | 28 | add "MAILER_USERNAME" "" |
| 29 | add "MAILER_PASSWORD" "" | 29 | add "MAILER_PASSWORD" "" |
| 30 | 30 | ||
| 31 | section "at protocol" | ||
| 32 | add "PDS_JWT_SECRET" "$(hex_secret 16)" | ||
| 33 | add "PDS_ADMIN_PASSWORD" "$(secret 32)" | ||
| 34 | add "PDS_PLC_ROTATION_KEY_K256_PRIVATE_KEY_HEX" "$(pds_rotation_key)" | ||
| 35 | add "PDS_RATE_LIMITS_ENABLED" "true" | ||
| 36 | add "PDS_INVITE_REQUIRED" "false" | ||
| 37 | add "PDS_CONTACT_EMAIL_ADDRESS" "" | ||
| 38 | |||
| 31 | section "authentication" | 39 | section "authentication" |
| 32 | add "KEYCLOAK_ADMIN_PASSWORD" "$(secret 12)" | 40 | add "KEYCLOAK_ADMIN_PASSWORD" "$(secret 12)" |
| 33 | 41 | ||
| ... | @@ -49,6 +57,19 @@ template() { | ... | @@ -49,6 +57,19 @@ template() { |
| 49 | add "FORGEJO_SECURITY_SECRET_KEY" "$(forgejo generate secret SECRET_KEY)" | 57 | add "FORGEJO_SECURITY_SECRET_KEY" "$(forgejo generate secret SECRET_KEY)" |
| 50 | add "FORGEJO_SECURITY_INTERNAL_TOKEN" "$(forgejo generate secret INTERNAL_TOKEN)" | 58 | add "FORGEJO_SECURITY_INTERNAL_TOKEN" "$(forgejo generate secret INTERNAL_TOKEN)" |
| 51 | 59 | ||
| 60 | section "tangled" | ||
| 61 | add "KNOT_SERVER_OWNER" "" | ||
| 62 | add "KNOT_APPVIEW_ENDPOINT" "https://tangled.org" | ||
| 63 | add "KNOT_SSH_PORT" "2222" | ||
| 64 | add "SPINDLE_SERVER_OWNER" "" | ||
| 65 | add "SPINDLE_IMAGE_TAG" "v1.14.0-alpha" | ||
| 66 | add "SPINDLE_NIXERY_PIPELINES_NIXERY" "nixery.tangled.sh" | ||
| 67 | add "SPINDLE_NIXERY_PIPELINES_WORKFLOW_TIMEOUT" "10m" | ||
| 68 | |||
| 69 | section "xmpp" | ||
| 70 | add "XMPP_ADMIN_USER" "admin" | ||
| 71 | add "XMPP_ADMIN_PASSWORD" "$(secret 20)" | ||
| 72 | |||
| 52 | section "evil infra" | 73 | section "evil infra" |
| 53 | add "EVIL_FORGEJO_SERVER_LFS_JWT_SECRET" "$(forgejo generate secret LFS_JWT_SECRET)" | 74 | add "EVIL_FORGEJO_SERVER_LFS_JWT_SECRET" "$(forgejo generate secret LFS_JWT_SECRET)" |
| 54 | add "EVIL_FORGEJO_OAUTH2_JWT_SECRET" "$(forgejo generate secret JWT_SECRET)" | 75 | add "EVIL_FORGEJO_OAUTH2_JWT_SECRET" "$(forgejo generate secret JWT_SECRET)" |
| ... | @@ -57,6 +78,13 @@ template() { | ... | @@ -57,6 +78,13 @@ template() { |
| 57 | } | 78 | } |
| 58 | 79 | ||
| 59 | secret() { openssl rand -base64 "$1" | tr -d '\n=/' | cut -c1-"$1"; } | 80 | secret() { openssl rand -base64 "$1" | tr -d '\n=/' | cut -c1-"$1"; } |
| 81 | hex_secret() { openssl rand -hex "$1"; } | ||
| 82 | pds_rotation_key() { | ||
| 83 | openssl ecparam -name secp256k1 -genkey -noout -outform DER | | ||
| 84 | tail -c +8 | | ||
| 85 | head -c 32 | | ||
| 86 | xxd -p -c 32 | ||
| 87 | } | ||
| 60 | section() { printf '\n# %s\n' "$1" >>"$FILE"; } | 88 | section() { printf '\n# %s\n' "$1" >>"$FILE"; } |
| 61 | add() { | 89 | add() { |
| 62 | printf '%s=%s\n' "$1" "${2:-}" >>"$FILE" | 90 | printf '%s=%s\n' "$1" "${2:-}" >>"$FILE" |