PostHog loads after the page is idle through a same-origin /ingest proxy and follows the signed-in Convex user. Plausible uses the per-site script through a /pa proxy. Sentry keeps errors and traces only. Pages load only the @spoon/ui modules they import, and client code reads public env from publicEnv.ts so zod stays out of the browser. Both analytics integrations stay off until their env is set in Infisical prod.
135 lines
6.3 KiB
YAML
135 lines
6.3 KiB
YAML
networks:
|
|
nginx-bridge: # Change to network you plan to use
|
|
external: true
|
|
|
|
services:
|
|
spoon-next:
|
|
build:
|
|
context: ../
|
|
dockerfile: ./docker/Dockerfile
|
|
args:
|
|
SENTRY_AUTH_TOKEN: ${SENTRY_AUTH_TOKEN}
|
|
SENTRY_DISABLE_AUTO_UPLOAD: ${SENTRY_DISABLE_AUTO_UPLOAD:-false}
|
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL}
|
|
NEXT_PUBLIC_CONVEX_URL: ${NEXT_PUBLIC_CONVEX_URL}
|
|
NEXT_PUBLIC_PLAUSIBLE_SRC: ${NEXT_PUBLIC_PLAUSIBLE_SRC:-}
|
|
NEXT_PUBLIC_POSTHOG_KEY: ${NEXT_PUBLIC_POSTHOG_KEY:-}
|
|
NEXT_PUBLIC_POSTHOG_HOST: ${NEXT_PUBLIC_POSTHOG_HOST:-}
|
|
NEXT_PUBLIC_SENTRY_DSN: ${NEXT_PUBLIC_SENTRY_DSN}
|
|
NEXT_PUBLIC_SENTRY_URL: ${NEXT_PUBLIC_SENTRY_URL}
|
|
NEXT_PUBLIC_SENTRY_ORG: ${NEXT_PUBLIC_SENTRY_ORG}
|
|
NEXT_PUBLIC_SENTRY_PROJECT_NAME: ${NEXT_PUBLIC_SENTRY_PROJECT_NAME}
|
|
NEXT_PUBLIC_SPOON_AGENT_WORKER_WS_URL: ${NEXT_PUBLIC_SPOON_AGENT_WORKER_WS_URL:-}
|
|
image: spoon-next:latest
|
|
#image: git.gbrown.org/gib/spoon-next:latest
|
|
container_name: ${NEXT_CONTAINER_NAME}
|
|
labels: ['com.centurylinklabs.watchtower.enable=true']
|
|
environment:
|
|
- NODE_ENV=${NODE_ENV}
|
|
- SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}
|
|
- NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL:-http://localhost:${NEXT_PORT:-3000}}
|
|
- NEXT_PUBLIC_CONVEX_URL=${NEXT_PUBLIC_CONVEX_URL:-http://${BACKEND_CONTAINER_NAME:-spoon-backend}:${BACKEND_PORT:-3210}}
|
|
- NEXT_PUBLIC_PLAUSIBLE_SRC=${NEXT_PUBLIC_PLAUSIBLE_SRC:-}
|
|
- NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY:-}
|
|
- NEXT_PUBLIC_POSTHOG_HOST=${NEXT_PUBLIC_POSTHOG_HOST:-}
|
|
- NEXT_PUBLIC_SENTRY_DSN=${NEXT_PUBLIC_SENTRY_DSN}
|
|
- NEXT_PUBLIC_SENTRY_URL=${NEXT_PUBLIC_SENTRY_URL}
|
|
- NEXT_PUBLIC_SENTRY_ORG=${NEXT_PUBLIC_SENTRY_ORG:-sentry}
|
|
- NEXT_PUBLIC_SENTRY_PROJECT_NAME=${NEXT_PUBLIC_SENTRY_PROJECT_NAME}
|
|
hostname: ${NEXT_CONTAINER_NAME}
|
|
domainname: ${NEXT_DOMAIN}
|
|
networks: ['${NETWORK:-nginx-bridge}']
|
|
#ports: ['${NEXT_PORT}:${NEXT_PORT}']
|
|
#depends_on: ['spoon-backend']
|
|
tty: true
|
|
stdin_open: true
|
|
restart: unless-stopped
|
|
|
|
spoon-backend:
|
|
image: ghcr.io/get-convex/convex-backend:${BACKEND_TAG:-latest}
|
|
container_name: ${BACKEND_CONTAINER_NAME:-spoon-backend}
|
|
hostname: ${BACKEND_CONTAINER_NAME:-spoon-backend}
|
|
domainname: ${BACKEND_DOMAIN:-convex.gbrown.org}
|
|
networks: ['${NETWORK:-nginx-bridge}']
|
|
#user: '1000:1000'
|
|
#ports: ['${BACKEND_PORT:-3210}:3210','${SITE_PROXY_PORT:-3211}:3211']
|
|
volumes: [./data:/convex/data]
|
|
labels: ['com.centurylinklabs.watchtower.enable=true']
|
|
environment:
|
|
- INSTANCE_NAME=${INSTANCE_NAME}
|
|
- INSTANCE_SECRET=${INSTANCE_SECRET}
|
|
- CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-spoon-backend}:${BACKEND_PORT:-3210}}
|
|
- CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-spoon-backend}:${SITE_PROXY_PORT:-3211}}
|
|
- DISABLE_BEACON=${DISABLE_BEACON:-true}
|
|
- REDACT_LOGS_TO_CLIENT=${REDACT_LOGS_TO_CLIENT:-true}
|
|
- DO_NOT_REQUIRE_SSL=${DO_NOT_REQUIRE_SSL:-false}
|
|
- POSTGRES_URL=${POSTGRES_URL}
|
|
stdin_open: true
|
|
tty: true
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: curl -f http://localhost:3210/version
|
|
interval: 5s
|
|
start_period: 10s
|
|
stop_grace_period: 10s
|
|
stop_signal: SIGINT
|
|
|
|
spoon-dashboard:
|
|
image: ghcr.io/get-convex/convex-dashboard:${DASHBOARD_TAG:-latest}
|
|
container_name: ${DASHBOARD_CONTAINER_NAME:-spoon-dashboard}
|
|
hostname: ${DASHBOARD_CONTAINER_NAME:-spoon-dashboard}
|
|
domainname: ${DASHBOARD_DOMAIN:-dashboard.${BACKEND_DOMAIN:-convex.gbrown.org}}
|
|
networks: ['${NETWORK:-nginx-bridge}']
|
|
#user: 1000:1000
|
|
#ports: ['${DASHBOARD_PORT:-6791}:6791']
|
|
labels: ['com.centurylinklabs.watchtower.enable=true']
|
|
environment:
|
|
- NEXT_PUBLIC_DEPLOYMENT_URL=${NEXT_PUBLIC_DEPLOYMENT_URL:-http://${BACKEND_CONTAINER_NAME:-spoon-backend}:${PORT:-3210}}
|
|
depends_on:
|
|
spoon-backend:
|
|
condition: service_healthy
|
|
stdin_open: true
|
|
tty: true
|
|
restart: unless-stopped
|
|
stop_grace_period: 10s
|
|
stop_signal: SIGINT
|
|
|
|
spoon-agent-worker:
|
|
build:
|
|
context: ../
|
|
dockerfile: ./docker/agent-worker.Dockerfile
|
|
image: spoon-agent-worker:latest
|
|
container_name: ${AGENT_WORKER_CONTAINER_NAME:-spoon-agent-worker}
|
|
hostname: ${AGENT_WORKER_CONTAINER_NAME:-spoon-agent-worker}
|
|
labels: ['com.centurylinklabs.watchtower.enable=true']
|
|
networks: ['${NETWORK:-nginx-bridge}']
|
|
environment:
|
|
- NEXT_PUBLIC_CONVEX_URL=${CONVEX_SELF_HOSTED_URL:-http://${BACKEND_CONTAINER_NAME:-spoon-backend}:${BACKEND_PORT:-3210}}
|
|
- SPOON_WORKER_TOKEN=${SPOON_WORKER_TOKEN}
|
|
- SPOON_AGENT_WORKER_ID=${SPOON_AGENT_WORKER_ID:-production-worker}
|
|
- SPOON_AGENT_JOB_IMAGE=${SPOON_AGENT_JOB_IMAGE:-spoon-agent-job:latest}
|
|
- SPOON_AGENT_RUNTIME=${SPOON_AGENT_RUNTIME:-docker}
|
|
- SPOON_AGENT_CONTAINER_RUNTIME=${SPOON_AGENT_CONTAINER_RUNTIME:-docker}
|
|
- SPOON_AGENT_CONTAINER_ACCESS=${SPOON_AGENT_CONTAINER_ACCESS:-network}
|
|
- SPOON_AGENT_NETWORK=${SPOON_AGENT_NETWORK:-nginx-bridge}
|
|
- SPOON_AGENT_MAX_CONCURRENT_JOBS=${SPOON_AGENT_MAX_CONCURRENT_JOBS:-1}
|
|
- SPOON_AGENT_JOB_TIMEOUT_MS=${SPOON_AGENT_JOB_TIMEOUT_MS:-1800000}
|
|
- SPOON_AGENT_WORKDIR=${SPOON_AGENT_WORKDIR:-/var/lib/spoon-agent/work}
|
|
# Required when the worker controls the host Docker socket: bind-mount
|
|
# source paths are resolved on the host, not inside this container, so the
|
|
# worker must know the host-side path backing SPOON_AGENT_WORKDIR. We bind
|
|
# the same host path at the same location below so they are identical.
|
|
- SPOON_AGENT_HOST_WORKDIR=${SPOON_AGENT_HOST_WORKDIR:-/var/lib/spoon-agent/work}
|
|
- GITHUB_APP_ID=${GITHUB_APP_ID}
|
|
- GITHUB_APP_PRIVATE_KEY=${GITHUB_APP_PRIVATE_KEY}
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
# Host bind mount (not a named volume) so the path is identical on the
|
|
# host and inside the worker, which is what the sibling job containers
|
|
# need for their `-v <path>:/workspace` mounts to resolve correctly.
|
|
- ${SPOON_AGENT_HOST_WORKDIR:-/var/lib/spoon-agent/work}:/var/lib/spoon-agent/work
|
|
depends_on:
|
|
spoon-backend:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|