Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
core docker-compose.yml
34 kB · 1038 lines
YAML
at sl/gitmirror
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039services: dns: image: coredns/coredns:1.14.7 restart: unless-stopped command: ["-conf", "/etc/coredns/Corefile"] volumes: - ./localinfra/Corefile:/etc/coredns/Corefile:ro networks: tngl: ipv4_address: 11.0.0.254 upstream-cache:
redis: image: redis:7-alpine restart: unless-stopped networks: [tngl]
postgres: image: postgres:14-alpine restart: unless-stopped environment: POSTGRES_USER: tnglr POSTGRES_PASSWORD: tnglr volumes: - postgres-data:/var/lib/postgresql/data - ./localinfra/postgres-init.sql:/docker-entrypoint-initdb.d/init.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U tnglr -d plc"] interval: 2s timeout: 2s retries: 30 start_period: 5s networks: [tngl]
pds: dns: [11.0.0.254] build: context: localinfra dockerfile: pds.Dockerfile restart: unless-stopped env_file: localinfra/pds.env environment: PDS_DID_PLC_URL: http://plc:8080 NODE_EXTRA_CA_CERTS: /caddy-ca/root.crt volumes: - pds-data:/pds - ./localinfra/certs/root.crt:/caddy-ca/root.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3000/xrpc/_health"] interval: 2s timeout: 2s retries: 30 start_period: 5s depends_on: dns: condition: service_started plc: condition: service_healthy networks: [tngl]
tranquil: dns: [11.0.0.254] build: context: localinfra dockerfile: tranquil.Dockerfile restart: unless-stopped environment: PDS_HOSTNAME: tranquil.tngl.boltless.dev SSL_CERT_FILE: /certs/root.crt DATABASE_URL: postgres://tnglr:tnglr@postgres:5432/tranquil PLC_DIRECTORY_URL: http://plc:8080 JWT_SECRET: ed7fb58467a19ac446743b9dafc89983face3a73f6ed2abe5fef29a12357c94d DPOP_SECRET: bae499d35b7410afa1babc52020687281210a1bf2b8ee70e24c212fe136ce5ea MASTER_KEY: f69f8047bb0418fff099092b380527a63885ca7ea16216b0f5894a040bc0fafa TRANQUIL_PDS_ALLOW_INSECURE_SECRETS: "true" INVITE_CODE_REQUIRED: "false" ALLOW_HTTP_PROXY: "true" ALLOW_PRIVATE_FETCH: "true" DISABLE_RATE_LIMITING: "true" # no comms service configured here, so accounts could never verify otherwise DISABLE_ACCOUNT_VERIFICATION_GATE: "true" MAX_DELEGATED_ACCOUNTS_PER_CONTROLLER: "2" volumes: - tranquil-data:/var/lib/tranquil-pds - ./localinfra/certs/root.crt:/certs/root.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3000/xrpc/_health"] interval: 2s timeout: 2s retries: 30 start_period: 5s depends_on: dns: condition: service_started plc: condition: service_started postgres: condition: service_healthy networks: [tngl]
tranquil-gate: dns: [11.0.0.254] build: context: . dockerfile: localinfra/tranquil-gate.Dockerfile restart: unless-stopped environment: GATE_DID: did:web:delegates.tngl.boltless.dev GATE_TRANQUIL_DID: did:web:tranquil.tngl.boltless.dev GATE_TRANQUIL_URL: http://tranquil:3000 GATE_DELIBERI_URL: http://deliberi:6565 GATE_DELIBERI_DID: did:web:deliberi.tngl.boltless.dev GATE_PLC_URL: http://plc:8080 # Local development key only. Provision a private key for deployment. GATE_SIGNING_KEY: AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE= GATE_EXTRA_CA_FILE: /certs/root.crt RUST_LOG: info volumes: - ./localinfra/certs/root.crt:/certs/root.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3100/xrpc/_health"] interval: 2s timeout: 2s retries: 30 depends_on: dns: condition: service_started tranquil: condition: service_healthy deliberi: condition: service_healthy init-accounts: condition: service_completed_successfully caddy: condition: service_started networks: [tngl]
init-accounts: dns: [11.0.0.254] build: context: localinfra dockerfile: seed.Dockerfile restart: "no" env_file: localinfra/pds.env environment: PDS_URL: http://pds:3000 OWNER_USER: alice KNOT_HOSTNAME: knot2.tngl.boltless.dev SPINDLE_HOSTNAME: spindle.tngl.boltless.dev TRANQUIL_URL: http://tranquil:3000 TRANQUIL_HOSTNAME: tranquil.tngl.boltless.dev volumes: - ./localinfra/scripts:/scripts:ro - init-state:/shared command: sh /scripts/init-accounts.sh depends_on: dns: condition: service_started pds: condition: service_healthy tranquil: condition: service_healthy networks: [tngl]
init-data: dns: [11.0.0.254] build: context: localinfra dockerfile: seed.Dockerfile restart: "no" env_file: localinfra/pds.env environment: PDS_URL: http://pds:3000 KNOT_URL: http://knot2:5555 KNOT_HOSTNAME: knot2.tngl.boltless.dev volumes: - ./localinfra/scripts:/scripts:ro - init-state:/shared:ro command: sh /scripts/init-data.sh depends_on: dns: condition: service_started init-accounts: condition: service_completed_successfully knot2: condition: service_healthy networks: [tngl]
plc: platform: linux/amd64 image: ghcr.io/bluesky-social/did-method-plc:plc-f2ab7516bac5bc0f3f86842fa94e996bd1b3815b restart: unless-stopped environment: DEBUG_MODE: "1" LOG_ENABLED: "true" LOG_LEVEL: debug LOG_DESTINATION: "1" PLC_VERSION: 0.0.1 PORT: "8080" DB_CREDS_JSON: &DB_CREDS_JSON '{"username":"tnglr","password":"tnglr","host":"postgres","port":5432}' DB_MIGRATE_CREDS_JSON: *DB_CREDS_JSON healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8080/_health"] interval: 2s timeout: 2s retries: 60 start_period: 10s depends_on: [postgres] networks: [tngl]
knot2: dns: [11.0.0.254] build: context: . dockerfile: localinfra/knot2.Dockerfile restart: unless-stopped environment: KNOT_HOSTNAME: knot2.tngl.boltless.dev KNOT_SCAN_PATH: /home/git/repositories KNOT_SSH_HOST_KEY_FILE: /home/git/keys/host_key KNOT_SEALED_KEY_FILE: /home/git/keys/sealed.bin KNOT_MASTER_KEY_ENV: KNOT_MASTER_KEY KNOT_MASTER_KEY: "9MfYcpOFaJYNzYJziRP3rrkM7DJdxQH/Hjey3LuwPF4=" # dev only KNOT_LEGACY_ADMIN_SECRET_ENV: KNOT_LEGACY_ADMIN_SECRET KNOT_LEGACY_ADMIN_SECRET: super-strong-devonly-key KNOT_PLC_DIRECTORY: https://plc.tngl.boltless.dev KNOT_APPVIEW_ENDPOINT: https://web.tngl.boltless.dev KNOT_EXTRA_CA_FILE: /etc/ssl/certs/tngl.crt # cluster root KNOT_XRPC_TRUSTED_PROXY_HEADER: x-forwarded-for KNOT_XRPC_TRUSTED_PROXIES: 11.0.0.0/24 KNOT_LISTEN_REQUEST_TIMEOUT_MS: "600000" KNOT_TLS_HTTP3: "false" KNOT_CONTRIBUTION_POLICY: anyone RUST_LOG: info ports: - "2223:2222" volumes: - knot2-data:/home/git - init-state:/shared:ro - ./localinfra/certs/root.crt:/etc/ssl/certs/tngl.crt:ro healthcheck: test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:5555/"] interval: 2s timeout: 2s retries: 60 start_period: 30s depends_on: dns: condition: service_started plc: condition: service_started pds: condition: service_healthy caddy: condition: service_started init-accounts: condition: service_completed_successfully networks: [tngl, upstream-cache]
ncps-migrate: image: &ncps-image ghcr.io/kalbasit/ncps:v0.9.4 profiles: ["linux"] restart: "no" command: - /bin/dbmate - --migrations-dir=/share/ncps/db/migrations/sqlite - --no-dump-schema - --url=sqlite:/storage/db.sqlite - up volumes: - ncps-data:/storage networks: [tngl]
ncps: image: *ncps-image profiles: ["linux"] restart: unless-stopped environment: ANALYTICS_REPORTING_ENABLED: "false" command: ["/bin/ncps", "serve", "--config", "/etc/ncps/ncps.yaml"] volumes: - ncps-data:/storage - ./localinfra/ncps.yaml:/etc/ncps/ncps.yaml:ro - ./localinfra/ncps-secret-key:/keys/ncps-secret-key:ro depends_on: ncps-migrate: condition: service_completed_successfully networks: [tngl, upstream-cache]
spindle: dns: [11.0.0.254] profiles: ["linux"] build: context: . dockerfile: localinfra/spindle.Dockerfile restart: unless-stopped environment: SPINDLE_SERVER_HOSTNAME: spindle.tngl.boltless.dev SPINDLE_SERVER_LISTEN_ADDR: 0.0.0.0:6555 SPINDLE_SERVER_METRICS_LISTEN_ADDR: 0.0.0.0:9091 SPINDLE_SERVER_DB_PATH: /var/lib/spindle/spindle.db SPINDLE_SERVER_PLC_URL: https://plc.tngl.boltless.dev SPINDLE_SERVER_JETSTREAM_ENDPOINT: wss://hydrant.tngl.boltless.dev/subscribe SPINDLE_SERVER_DEV: "true" SPINDLE_SERVER_DEV_EXTRA_HOSTS: knot2.tngl.boltless.dev,mirror.tngl.boltless.dev SPINDLE_SERVER_TAP_DB_PATH: /var/lib/spindle/tap.db SPINDLE_SERVER_TAP_RELAY_URL: https://pds.tngl.boltless.dev SPINDLE_MICROVM_PIPELINES_IMAGE_DIR: /var/lib/spindle/images SPINDLE_MICROVM_PIPELINES_OVERLAY_DIR: /var/lib/spindle/overlays SPINDLE_MICROVM_PIPELINES_AGENT_PORT: "11240" SPINDLE_MICROVM_PIPELINES_ENABLE_CGROUPS: "false" SPINDLE_CACHE_BACKEND: disk SPINDLE_NIX_CACHE_READ_URLS: http://ncps:8501 SPINDLE_NIX_CACHE_TRUSTED_PUBLIC_KEYS: cache.local:F7YqpMzuBdILYd/v+wMZN2YKxCzliXQyFmeezOxw7rU= SPINDLE_NIX_CACHE_UPLOAD_URL: http://ncps:8501/upload SPINDLE_QUOTA_USER_CACHE_STORAGE_MIB: 0 SPINDLE_QUOTA_USER_WORKFLOWS: 0 SPINDLE_QUOTA_USER_VCPUS: 0 SPINDLE_QUOTA_USER_MEMORY_MIB: 0 SPINDLE_QUOTA_USER_DISK_MIB: 0 SPINDLE_QUOTA_REPO_CACHE_STORAGE_MIB: 0 SPINDLE_QUOTA_REPO_WORKFLOWS: 0 SPINDLE_QUOTA_REPO_VCPUS: 0 SPINDLE_QUOTA_REPO_MEMORY_MIB: 0 SPINDLE_QUOTA_REPO_DISK_MIB: 0 SPINDLE_MICROVM_PIPELINES_DEBUG_SSH_ENABLED: true SPINDLE_MICROVM_PIPELINES_DEBUG_SSH_LISTEN_ADDR: 0.0.0.0:2223 SPINDLE_MICROVM_PIPELINES_DEBUG_SSH_GRACE_PERIOD: 10m SPINDLE_TRACING_ENDPOINT: "${SPINDLE_TRACING_ENDPOINT:-}" SPINDLE_TRACING_INSECURE: "${SPINDLE_TRACING_INSECURE:-false}" SPINDLE_LOG_FORMAT: json SPINDLE_LOGGING_ENDPOINT: "${SPINDLE_LOGGING_ENDPOINT:-}" SPINDLE_LOGGING_INSECURE: "${SPINDLE_LOGGING_INSECURE:-false}" SPINDLE_LOGGING_SERVICE_NAME: spindle # these two are required for cgroups, uncomment if testing # privileged: true # cgroup: host devices: - /dev/vsock:/dev/vsock - /dev/kvm:/dev/kvm - /dev/vhost-vsock:/dev/vhost-vsock - /dev/net/tun:/dev/net/tun cap_add: - NET_ADMIN - SYS_ADMIN security_opt: - label=disable - seccomp=unconfined ports: - "127.0.0.1:2223:2223" volumes: - spindle-data:/var/lib/spindle - spindle-logs:/var/log/spindle - ./out/localinfra-spindle-images:/var/lib/spindle/images:ro - init-state:/shared:ro - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:6555/"] interval: 2s timeout: 2s retries: 30 start_period: 5s depends_on: dns: condition: service_started plc: condition: service_started hydrant: condition: service_healthy init-accounts: condition: service_completed_successfully ncps: condition: service_started networks: [tngl, upstream-cache]
# knotmirror-tap: # dns: [11.0.0.254] # image: ghcr.io/bluesky-social/indigo/tap:sha-4f47add43060c27e8a37d9d76482ecddf001fcd8 # 0.1.10 # restart: unless-stopped # environment: # TAP_BIND: ":2480" # TAP_PLC_URL: https://plc.tngl.boltless.dev # TAP_RELAY_URL: https://pds.tngl.boltless.dev # PDS can be used as basic relay without collectiondir. # TAP_DATABASE_URL: postgres://tnglr:tnglr@postgres:5432/mirror_tap?sslmode=disable # TAP_COLLECTION_FILTERS: sh.tangled.repo # TAP_SIGNAL_COLLECTION: sh.tangled.repo # TAP_RESYNC_PARALLELISM: "10" # TAP_RETRY_TIMEOUT: 60s # volumes: # - ./localinfra/certs/root.crt:/etc/ssl/certs/tngl-dev-root.crt:ro # depends_on: # dns: # condition: service_started # postgres: # condition: service_started # pds: # condition: service_healthy # networks: [tngl]
# knotmirror: # dns: [11.0.0.254] # build: # context: . # dockerfile: localinfra/knotmirror.Dockerfile # restart: unless-stopped # environment: # MIRROR_LISTEN: 0.0.0.0:7000 # MIRROR_ADMIN_LISTEN: 0.0.0.0:7200 # MIRROR_HOSTNAME: mirror.tngl.boltless.dev # MIRROR_TAP_URL: http://knotmirror-tap:2480 # MIRROR_DB_URL: postgres://tnglr:tnglr@postgres:5432/mirror?sslmode=disable # MIRROR_REDIS_ADDR: redis:6379 # MIRROR_PLC_URL: https://plc.tngl.boltless.dev # MIRROR_GIT_BASEPATH: /data/repos # MIRROR_KNOT_USE_SSL: "true" # MIRROR_KNOT_SSRF: "false" # MIRROR_RESYNC_PARALLELISM: "4" # MIRROR_APPVIEW_URL: http://appview:3000 # MIRROR_SEARCH_ZOEKT_URL: https://zoekt.tngl.boltless.dev/indexserver # MIRROR_V2_HOST: http://gitmirror:9001 # MIRROR_DELIBERI_URL: http://deliberi:6565 # MIRROR_DELIBERI_DID: did:web:deliberi.tngl.boltless.dev # env_file: # - ./localinfra/certs/service-auth.env # volumes: # - knotmirror-data:/data # - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro # healthcheck: # test: ["CMD", "wget", "-qO-", "http://localhost:7000/"] # interval: 2s # timeout: 2s # retries: 30 # start_period: 5s # ports: # - "7201:7200" # depends_on: # dns: # condition: service_started # postgres: # condition: service_started # knotmirror-tap: # condition: service_started # networks: [tngl]
gitmirror: dns: [11.0.0.254] depends_on: dns: condition: service_started redis: condition: service_started postgres: condition: service_healthy build: context: . dockerfile: localinfra/gitmirror.Dockerfile restart: unless-stopped environment: RUST_LOG: gitmirror=debug GITMIRROR_LOG: gitmirror_ingest=debug,gitmirror_sync=debug,hydrant=info GITMIRROR_BIND: 0.0.0.0:9001 GITMIRROR_METRICS_BIND: 0.0.0.0:9091 GITMIRROR_SCAN_PATH: /data/repos GITMIRROR_SERVICE_DID: did:web:mirror.tngl.boltless.dev GITMIRROR_PLC_URL: https://plc.tngl.boltless.dev GITMIRROR_REDIS_URL: redis://redis:6379 GITMIRROR_KNOT_ALLOW_PRIVATE: "true" GITMIRROR_KNOT_REQUIRE_HTTPS: "false" GITMIRROR_DATABASE_URL: postgres://tnglr:tnglr@postgres:5432/gitmirror # Embedded hydrant config HYDRANT_DATABASE_PATH: /data/gitmirror-hydrant.db HYDRANT_RELAY_HOSTS: pds::wss://knot2.tngl.boltless.dev HYDRANT_CRAWLER_URLS: list_repos::https://knot2.tngl.boltless.dev HYDRANT_PLC_URL: https://plc.tngl.boltless.dev HYDRANT_BACKFILL_STRATEGY: sparse-filter HYDRANT_VERIFY_SIGNATURES: none volumes: - knotmirror-data:/data - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro networks: [tngl]
zoekt-webserver: build: context: https://tangled.org/boltless.me/zoekt.git#tngl volumes: - zoekt-index:/data/index - ./localinfra/certs/root.crt:/etc/ssl/certs/caddy.crt:ro command: ["zoekt-webserver", "-index", "/data/index", "-pprof", "-rpc"] networks: [tngl]
zoekt-tngl-indexserver: dns: [11.0.0.254] depends_on: [dns] build: context: . dockerfile: localinfra/zoekt-tngl-indexserver.Dockerfile environment: TANGLED_ZOEKT_INDEX_DIR: /data/index TANGLED_ZOEKT_PLC_URL: https://plc.tngl.boltless.dev TANGLED_ZOEKT_APPVIEW_URL: https://web.tngl.boltless.dev TANGLED_ZOEKT_ALLOW_HTTP: "true" volumes: - zoekt-index:/data/index - ./localinfra/certs/root.crt:/etc/ssl/certs/caddy.crt:ro command: ["zoekt-tngl-indexserver", "serve"] networks: [tngl]
# tailwind: # build: # context: . # dockerfile: localinfra/tailwind.Dockerfile # restart: unless-stopped # working_dir: /build # init: true # volumes: # - .:/build:ro # - ./appview/pages/static:/build/appview/pages/static # command: # ["-i", "input.css", "-o", "appview/pages/static/tw.css", "--watch=always"] # network_mode: none
# appview: # dns: [11.0.0.254] # build: # context: . # dockerfile: localinfra/appview.Dockerfile # restart: unless-stopped # environment: # TANGLED_DEV: "true" # TANGLED_APPVIEW_HOST: 127.0.0.1:3000 # TANGLED_XRPC_ENABLED: "true" # TANGLED_DB_PATH: /var/lib/appview/appview.db # TANGLED_PLC_URL: https://plc.tngl.boltless.dev # TANGLED_JETSTREAM_ENDPOINT: wss://hydrant.tngl.boltless.dev/subscribe # TANGLED_REDIS_ADDR: redis:6379 # TANGLED_KNOTMIRROR_URL: https://mirror.tngl.boltless.dev # TANGLED_CODESEARCH_ZOEKT_URL: https://zoekt.tngl.boltless.dev # TANGLED_SSH_ENABLED: "true" # TANGLED_SSH_LISTEN_ADDR: "0.0.0.0:3333" # ports: # - "3000:3000" # - "3333:3333" # healthcheck: # test: ["CMD", "wget", "-qO-", "http://localhost:3000/"] # interval: 5s # timeout: 2s # retries: 15 # start_period: 10s # volumes: # - .:/src:cached # - go-cache:/go/cache # - go-mod-cache:/go/mod # - appview-data:/var/lib/appview # - init-state:/shared:ro # - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro # depends_on: # dns: # condition: service_started # redis: # condition: service_started # pds: # condition: service_healthy # hydrant: # condition: service_healthy # init-accounts: # condition: service_completed_successfully # networks: [tngl]
deliberi: dns: [11.0.0.254] build: context: . dockerfile: localinfra/deliberi.Dockerfile restart: unless-stopped environment: DELIBERI_DEV: "true" DELIBERI_HOSTNAME: deliberi.tngl.boltless.dev DELIBERI_LISTEN_ADDR: 0.0.0.0:6565 DELIBERI_DB_PATH: /var/lib/deliberi/deliberi.db DELIBERI_PLC_URL: https://plc.tngl.boltless.dev DELIBERI_JETSTREAM_ENDPOINT: wss://hydrant.tngl.boltless.dev/subscribe DELIBERI_BOBBIN_API_URL: http://bobbin:8090 # verification links in deliberi mail point here; must be browser-reachable DELIBERI_BASE_URL: https://web.tngl.boltless.dev DELIBERI_PDS_HOST: https://pds.tngl.boltless.dev # PDS admin password for minting invite codes + creating accounts DELIBERI_PDS_ADMIN_SECRET: ${TANGLED_PDS_ADMIN_SECRET} DELIBERI_TRUSTED_SERVICE_DIDS: did:web:mirror.tngl.boltless.dev,did:web:delegates.tngl.boltless.dev volumes: - deliberi-data:/var/lib/deliberi - init-state:/shared:ro - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:6565/xrpc/_health"] interval: 2s timeout: 2s retries: 30 start_period: 5s ports: - "6565:6565" depends_on: dns: condition: service_started pds: condition: service_healthy hydrant: condition: service_healthy init-accounts: condition: service_completed_successfully networks: [tngl]
pdsls: build: context: . dockerfile: localinfra/pdsls.Dockerfile restart: unless-stopped ports: - "8081:80" depends_on: init-accounts: condition: service_completed_successfully networks: [tngl]
hydrant: dns: [11.0.0.254] build: context: . dockerfile: bobbin/containerfiles/hydrant.Containerfile args: HYDRANT_REF: main restart: unless-stopped environment: HYDRANT_API_BIND: 0.0.0.0:3000 HYDRANT_DATABASE_PATH: /data/hydrant.db HYDRANT_RELAY_HOSTS: pds::wss://pds.tngl.boltless.dev,pds::wss://knot2.tngl.boltless.dev,pds::wss://tranquil.tngl.boltless.dev HYDRANT_CRAWLER_URLS: list_repos::https://pds.tngl.boltless.dev HYDRANT_PLC_URL: https://plc.tngl.boltless.dev HYDRANT_FILTER_COLLECTIONS: sh.tangled.*,org.tangled.* HYDRANT_FILTER_SIGNALS: sh.tangled.actor.profile,sh.tangled.feed.comment,sh.tangled.feed.reaction,sh.tangled.feed.star,sh.tangled.git.refUpdate,sh.tangled.graph.follow,sh.tangled.graph.vouch,sh.tangled.knot,sh.tangled.knot.member,sh.tangled.knot.memberInvite,sh.tangled.label.definition,sh.tangled.label.op,sh.tangled.pipeline,sh.tangled.pipeline.status,sh.tangled.publicKey,sh.tangled.repo,sh.tangled.repo.artifact,sh.tangled.repo.collaborator,sh.tangled.repo.collaboratorAcceptance,sh.tangled.repo.collaboratorInvite,sh.tangled.repo.issue,sh.tangled.repo.issue.comment,sh.tangled.repo.issue.state,sh.tangled.repo.pull,sh.tangled.repo.pull.comment,sh.tangled.repo.pull.status,sh.tangled.spindle,sh.tangled.spindle.member,sh.tangled.string,org.tangled.feed.subscription HYDRANT_BACKFILL_STRATEGY: sparse-filter HYDRANT_VERIFY_SIGNATURES: none RUST_LOG: info volumes: - hydrant-data:/data - ./localinfra/certs/root.crt:/etc/ssl/certs/tngl-dev-root.crt:ro healthcheck: test: ["CMD", "bash", "-c", "echo > /dev/tcp/127.0.0.1/3000"] interval: 5s timeout: 2s retries: 15 start_period: 10s depends_on: dns: condition: service_started plc: condition: service_started pds: condition: service_healthy knot2: condition: service_healthy caddy: condition: service_started init-accounts: condition: service_completed_successfully networks: [tngl] bobbin: dns: [11.0.0.254] build: context: . dockerfile: localinfra/bobbin.Dockerfile restart: unless-stopped environment: BOBBIN_BIND: 0.0.0.0:8090 BOBBIN_HYDRANT_URL: http://hydrant:3000 BOBBIN_SLINGSHOT_URL: http://hydrant:3000 BOBBIN_SERVICE_DID: did:web:bobbin.tngl.boltless.dev BOBBIN_KNOT_ALLOW_PRIVATE: "true" BOBBIN_MIRROR_V2_URL: http://gitmirror:9001 BOBBIN_POCKET_URL: http://pocket:3000 BOBBIN_CODESEARCH_ZOEKT_URL: https://zoekt.tngl.boltless.dev BOBBIN_LOG: info BOBBIN_KNOT_REQUIRE_HTTPS: "true" BOBBIN_INGEST_IDLE_PROMOTE_MIN_EVENTS: "1" volumes: - .:/src:cached - bobbin-cargo:/cargo - bobbin-target:/target - ./localinfra/certs/root.crt:/etc/ssl/certs/tngl-dev-root.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8090/xrpc/sh.tangled.bobbin.getCoverage"] interval: 5s timeout: 2s retries: 15 start_period: 10s depends_on: dns: condition: service_started hydrant: condition: service_started caddy: condition: service_started pocket: condition: service_healthy networks: [tngl]
pocket: build: context: . dockerfile: localinfra/pocket.Dockerfile restart: unless-stopped environment: POCKET_DB: /var/lib/pocket/prefs.sqlite3 POCKET_DOMAIN: pocket.tngl.boltless.dev POCKET_SLINGSHOT_URL: http://bobbin:8090 RUST_LOG: info volumes: - pocket-data:/var/lib/pocket - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3000/.well-known/did.json"] interval: 5s timeout: 2s retries: 15 start_period: 10s ports: - "3100:3000" networks: [tngl]
web: dns: [11.0.0.254] build: context: . dockerfile: localinfra/web.Dockerfile restart: unless-stopped env_file: localinfra/certs/github.env environment: # cloudflare adapter → vite dev emulates the worker platform (env bindings) # from web/.wrangler/state, so local KV seeding works like the deployed worker SVELTE_ADAPTER: cloudflare BOBBIN_URL: https://bobbin.tngl.boltless.dev # browser-reachable appview for authed xrpc; host must match the # appview's TANGLED_APPVIEW_HOST so the service-auth aud lines up TANGLED_API_URL: http://127.0.0.1:3000 # suffix shown in the sites claim UI; must match the appview's TANGLED_SITES_DOMAIN SITES_DOMAIN: tngl.io DELIBERI_URL: https://deliberi.tngl.boltless.dev PRIMARY_KNOT: knot2.tngl.boltless.dev PRIMARY_SPINDLE: spindle.tngl.boltless.dev DELEGATION_URL: https://delegates.tngl.boltless.dev DELEGATION_DID: did:web:tranquil.tngl.boltless.dev CAMO_URL: https://camo.tngl.boltless.dev CAMO_SHARED_SECRET: localinfra-camo-secret AVATAR_URL: https://avatar.tngl.boltless.dev AVATAR_SHARED_SECRET: localinfra-avatar-secret VITE_HANDLE_RESOLVER_URL: https://pds.tngl.boltless.dev VITE_PLC_DIRECTORY_URL: https://plc.tngl.boltless.dev MIGRATOR_URL: https://migrator.tngl.boltless.dev GITHUB_PUBLIC_ORIGIN: https://github.tngl.boltless.dev GITHUB_API_ORIGIN: https://github.tngl.boltless.dev GITHUB_AVATARS_ORIGIN: https://github.tngl.boltless.dev # public turnstile site key rendered by the /signup page widget TURNSTILE_SITE_KEY: ${TANGLED_CLOUDFLARE_TURNSTILE_SITE_KEY} # host-side port; keeps the oauth loopback redirect consistent VITE_DEV_PORT: "5174" VITE_ALLOWED_HOSTS: .tngl.boltless.dev VITE_OAUTH_CLIENT_ID: https://web.tngl.boltless.dev/oauth-client-metadata.json VITE_OAUTH_REDIRECT_URI: https://web.tngl.boltless.dev/oauth/callback # the bind mount below does not deliver inotify, see vite.config.ts VITE_WATCH_POLL: "true" NODE_EXTRA_CA_CERTS: /caddy-ca/root.crt ports: - "5174:5174" volumes: - ./web:/src:cached # shadow generated dirs so the host tree stays untouched - web-node-modules:/src/node_modules - web-svelte-kit:/src/.svelte-kit - ./localinfra/certs/root.crt:/caddy-ca/root.crt:ro healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:5174/').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"] interval: 5s timeout: 2s retries: 30 start_period: 20s depends_on: dns: condition: service_started bobbin: condition: service_started caddy: condition: service_started networks: [tngl, upstream-cache]
github-stub: build: context: . dockerfile: localinfra/github-stub.Dockerfile restart: unless-stopped environment: PORT: "8000" REPOS_DIR: /data/repos GITHUB_PUBLIC_ORIGIN: https://github.tngl.boltless.dev GITHUB_API_ORIGIN: https://github.tngl.boltless.dev GITHUB_AVATARS_ORIGIN: https://github.tngl.boltless.dev GITHUB_APP_SETUP_URL: ${GITHUB_APP_SETUP_URL:-https://web.tngl.boltless.dev/_internal/github/install/callback} volumes: - github-stub-data:/data healthcheck: test: ["CMD", "python3", "-c", "import urllib.request,sys; sys.exit(0 if urllib.request.urlopen('http://localhost:8000/user', timeout=2).status == 200 else 1)"] interval: 5s timeout: 3s retries: 12 start_period: 5s networks: tngl: aliases: # deliberi validates committer email domains by DNS - octostub.dev
migrator: build: context: . dockerfile: localinfra/migrator.Dockerfile restart: unless-stopped env_file: ./localinfra/certs/migrator.env environment: MIGRATOR_HOSTNAME: migrator.tngl.boltless.dev MIGRATOR_APP_URL: https://web.tngl.boltless.dev MIGRATOR_PLC_URL: https://plc.tngl.boltless.dev MIGRATOR_GITHUB_HOST: github.tngl.boltless.dev MIGRATOR_DB_PATH: /var/lib/migrator/migrator.db MIGRATOR_WORK_DIR: /var/lib/migrator/scratch volumes: - migrator-data:/var/lib/migrator - ./localinfra/certs/root.crt:/usr/local/share/ca-certificates/caddy.crt:ro healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:6767/.well-known/did.json"] interval: 5s timeout: 2s retries: 12 start_period: 5s networks: [tngl]
camo: dns: [11.0.0.254] depends_on: [dns] build: context: . dockerfile: localinfra/camo.Dockerfile restart: unless-stopped environment: CAMO_SHARED_SECRET: localinfra-camo-secret WRANGLER_SEND_METRICS: "false" volumes: - ./camo:/src:cached # shadow generated dirs so the host tree stays untouched - camo-node-modules:/src/node_modules - camo-wrangler:/src/.wrangler - ./localinfra/certs/root.crt:/caddy-ca/root.crt:ro healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8787/').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"] interval: 5s timeout: 2s retries: 30 start_period: 30s networks: [tngl]
avatar: dns: [11.0.0.254] depends_on: [dns] build: context: . dockerfile: localinfra/avatar.Dockerfile restart: unless-stopped environment: AVATAR_SHARED_SECRET: localinfra-avatar-secret PLC_DIRECTORY_URL: https://plc.tngl.boltless.dev WRANGLER_SEND_METRICS: "false" volumes: - ./avatar:/src:cached - avatar-node-modules:/src/node_modules - avatar-wrangler:/src/.wrangler - ./localinfra/certs/root.crt:/caddy-ca/root.crt:ro healthcheck: test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:8787/').then(r=>process.exit(r.ok?0:1),()=>process.exit(1))"] interval: 5s timeout: 2s retries: 30 start_period: 30s networks: [tngl]
caddy: image: caddy:2-alpine restart: unless-stopped depends_on: dns: condition: service_started ports: - "80:80" - "443:443" - "8090:8090" volumes: - ./localinfra/Caddyfile:/etc/caddy/Caddyfile - ./localinfra/certs:/etc/caddy/certs:ro - caddy-data:/data networks: tngl: ipv4_address: 11.0.0.253 aliases: - plc.tngl.boltless.dev - pds.tngl.boltless.dev - alice.pds.tngl.boltless.dev - bob.pds.tngl.boltless.dev - charlie.pds.tngl.boltless.dev - david.pds.tngl.boltless.dev - hydrant.tngl.boltless.dev - knot2.tngl.boltless.dev # exercises the remote fetch path instead of same-authority - knot2-alt.tngl.boltless.dev - spindle.tngl.boltless.dev - tngl.boltless.dev - mirror.tngl.boltless.dev - zoekt.tngl.boltless.dev - pdsls.tngl.boltless.dev - bobbin.tngl.boltless.dev - camo.tngl.boltless.dev - avatar.tngl.boltless.dev - deliberi.tngl.boltless.dev - web.tngl.boltless.dev - delegates.tngl.boltless.dev - tranquil.tngl.boltless.dev - troy.tranquil.tngl.boltless.dev - github.tngl.boltless.dev - api.github.tngl.boltless.dev
prometheus: image: prom/prometheus:v2.54.1 profiles: ["observability"] restart: unless-stopped command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--enable-feature=exemplar-storage' volumes: - prometheus-data:/prometheus - ./localinfra/observability/prometheus:/etc/prometheus:ro ports: - "127.0.0.1:9090:9090" networks: [tngl]
tempo: image: grafana/tempo:2.5.0 profiles: ["observability"] restart: unless-stopped command: ["-config.file=/etc/tempo/tempo.yml"] volumes: - ./localinfra/observability/tempo/tempo.yml:/etc/tempo/tempo.yml:ro - tempo-data:/var/tempo ports: - "127.0.0.1:3200:3200" networks: [tngl]
loki: image: grafana/loki:3.0.0 profiles: ["observability"] restart: unless-stopped command: ["-config.file=/etc/loki/loki.yml"] volumes: - ./localinfra/observability/loki/loki.yml:/etc/loki/loki.yml:ro - loki-data:/loki ports: - "127.0.0.1:3100:3100" healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:3100/ready"] interval: 10s timeout: 5s retries: 3 networks: [tngl]
grafana: image: grafana/grafana:11.2.0 profiles: ["observability"] restart: unless-stopped volumes: - grafana-data:/var/lib/grafana - ./localinfra/observability/grafana/provisioning:/etc/grafana/provisioning:ro ports: - "127.0.0.1:3001:3000" networks: [tngl]
volumes: migrator-data: github-stub-data: caddy-data: postgres-data: pds-data: knot2-data: knotmirror-data: zoekt-index: spindle-data: spindle-logs: ncps-data: init-state: # go-cache: # go-mod-cache: # appview-data: deliberi-data: prometheus-data: grafana-data: tempo-data: loki-data: hydrant-data: pocket-data: bobbin-cargo: bobbin-target: tranquil-data: web-node-modules: web-svelte-kit: camo-node-modules: camo-wrangler: avatar-node-modules: avatar-wrangler:
networks: tngl: driver: bridge internal: true # Public-looking subnet so SSRF checks see container IPs as "public". # RFC1918 + doc/benchmark ranges are blocklisted; 11.x is unrouted on # the public internet, so it passes the check and won't collide. ipam: config: - subnet: 11.0.0.0/24
upstream-cache: driver: bridge