Panama learns what a server is: from a root login to running containers
A machine's role is now the interview's first question and the one answer Panama records. Servers get the same shell minus the screen: core packages, nvm, Bun, Claude Code and Codex (desktops get Codex too), linger, rootless ports from 80, firewalld, the nginx-bridge network, and a nightly image updater that replaced watchtower for cause. server/containers/ carries junior's 23 compose services -- secrets moved to per-machine .env files that never enter this public repo, every transformed compose proven to render byte-identical to what is live. 'panama server' enables, disables and relinks them; nothing here restarts a running service. 'boot --server' walks a fresh VPS from its root login to a normal install. Five new contracts pin the secrets rule, the catalog's shape, panama-server's behavior, the role plumbing, and the dotfile classification. Claude-Session: https://claude.ai/code/session_01NU5JGiN3JfzqrLQB6wmJ1E
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# Since .env is gitignored, you can use .env.example to build a new `.env` file when you clone the repo.
|
||||
# Keep this file up-to-date when you add new variables to \`.env\`.
|
||||
# This file will be committed to version control, so make sure not to have any secrets in it.
|
||||
# If you are cloning this repo, create a copy of this file named `.env` and populate it with your secrets.
|
||||
|
||||
## Next App ##
|
||||
NODE_ENV=production
|
||||
SENTRY_AUTH_TOKEN=CHANGE_ME
|
||||
PAYLOAD_SECRET=CHANGE_ME
|
||||
PAYLOAD_DB_URL=CHANGE_ME
|
||||
NEXT_PUBLIC_SITE_URL=https://stpeteit.com
|
||||
NEXT_PUBLIC_CONVEX_URL=https://api.stpeteit.com # convex-backend:3210
|
||||
NEXT_PUBLIC_PLAUSIBLE_URL=https://plausible.gbrown.org
|
||||
NEXT_PUBLIC_SENTRY_DSN=https://[email protected]/5
|
||||
NEXT_PUBLIC_SENTRY_URL=https://sentry.gbrown.org
|
||||
NEXT_PUBLIC_SENTRY_ORG=sentry
|
||||
NEXT_PUBLIC_SENTRY_PROJECT_NAME=stpeteit-next
|
||||
|
||||
## Convex ##
|
||||
CONVEX_SELF_HOSTED_URL=https://api.stpeteit.com # convex-backend:3210
|
||||
CONVEX_SELF_HOSTED_ADMIN_KEY=CHANGE_ME
|
||||
# Convex Auth
|
||||
CONVEX_SITE_URL=https://stpeteit.com # convex-backend:3211
|
||||
USESEND_API_KEY=CHANGE_ME
|
||||
USESEND_URL=https://usesend.gbrown.org
|
||||
USESEND_FROM_EMAIL='St Pete IT Admin <[email protected]>'
|
||||
AUTH_AUTHENTIK_ID=CHANGE_ME
|
||||
AUTH_AUTHENTIK_SECRET=CHANGE_ME
|
||||
AUTH_AUTHENTIK_ISSUER=https://auth.gbrown.org/application/o/stpeteit/
|
||||
|
||||
## Docker Compose Variables for Next App ##
|
||||
NETWORK=nginx-bridge
|
||||
NEXT_CONTAINER_NAME=stpeteit-next
|
||||
NEXT_DOMAIN=stpeteit.com
|
||||
#NEXT_PORT=3000
|
||||
|
||||
## Docker Compose Variables for Self hosted Convex ##
|
||||
BACKEND_TAG=latest
|
||||
DASHBOARD_TAG=latest
|
||||
BACKEND_CONTAINER_NAME=stpeteit-backend
|
||||
DASHBOARD_CONTAINER_NAME=stpeteit-dashboard
|
||||
BACKEND_DOMAIN=convex.stpeteit.com
|
||||
DASHBOARD_DOMAIN=dashboard.stpeteit.com
|
||||
INSTANCE_NAME=stpeteit-convex
|
||||
#INSTANCE_SECRET=
|
||||
CONVEX_CLOUD_ORIGIN=https://api.stpeteit.com
|
||||
CONVEX_SITE_ORIGIN=https://convex.stpeteit.com
|
||||
NEXT_PUBLIC_DEPLOYMENT_URL=https://api.stpeteit.com
|
||||
DISABLE_BEACON=true
|
||||
REDACT_LOGS_TO_CLIENT=true
|
||||
DO_NOT_REQUIRE_SSL=true
|
||||
POSTGRES_URL=CHANGE_ME
|
||||
#BACKEND_PORT=
|
||||
#DASHBOARD_PORT
|
||||
#SITE_PROXY_PORT=
|
||||
#ACTIONS_USER_TIMEOUT_SECS=
|
||||
#RUST_LOG=
|
||||
#RUST_BACKTRACE=
|
||||
@@ -0,0 +1,101 @@
|
||||
networks:
|
||||
nginx-bridge: # Change to network you plan to use
|
||||
external: true
|
||||
|
||||
services:
|
||||
stpeteit-next:
|
||||
image: git.gbrown.org/gib/stpeteit-next:latest
|
||||
container_name: stpeteit-next
|
||||
hostname: stpeteit-next
|
||||
domainname: ${NEXT_DOMAIN}
|
||||
networks: ['${NETWORK:-nginx-bridge}']
|
||||
#ports: ['${NEXT_PORT}:${NEXT_PORT}']
|
||||
environment:
|
||||
- NODE_ENV=${NODE_ENV:-development}
|
||||
- SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}
|
||||
- PAYLOAD_SECRET=${PAYLOAD_SECRET}
|
||||
- PAYLOAD_DB_URL=${PAYLOAD_DB_URL}
|
||||
- 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:-stpeteit-backend}:${BACKEND_PORT:-3210}}
|
||||
- NEXT_PUBLIC_PLAUSIBLE_URL=${NEXT_PUBLIC_PLAUSIBLE_URL:-https://plausible.stpeteit.com}
|
||||
- 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}
|
||||
labels: ['com.centurylinklabs.watchtower.enable=true']
|
||||
depends_on: ['stpeteit-backend']
|
||||
tty: true
|
||||
stdin_open: true
|
||||
restart: unless-stopped
|
||||
|
||||
stpeteit-backend:
|
||||
image: ghcr.io/get-convex/convex-backend:${BACKEND_TAG:-latest}
|
||||
container_name: ${BACKEND_CONTAINER_NAME:-stpeteit-backend}
|
||||
hostname: ${BACKEND_CONTAINER_NAME:-stpeteit-backend}
|
||||
domainname: ${BACKEND_DOMAIN:-convex.stpeteit.com}
|
||||
networks: ['${NETWORK:-nginx-bridge}']
|
||||
#user: '1000:1000'
|
||||
#ports: ['${BACKEND_PORT:-3210}:3210','${SITE_PROXY_PORT:-3211}:3211']
|
||||
volumes: [./data:/convex/data:z]
|
||||
labels: ['com.centurylinklabs.watchtower.enable=true']
|
||||
environment:
|
||||
- INSTANCE_NAME
|
||||
#- INSTANCE_SECRET
|
||||
- CONVEX_CLOUD_ORIGIN=${CONVEX_CLOUD_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-stpeteit-backend}:${BACKEND_PORT:-3210}}
|
||||
- CONVEX_SITE_ORIGIN=${CONVEX_SITE_ORIGIN:-http://${BACKEND_CONTAINER_NAME:-stpeteit-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
|
||||
|
||||
stpeteit-dashboard:
|
||||
image: ghcr.io/get-convex/convex-dashboard:${DASHBOARD_TAG:-latest}
|
||||
container_name: ${DASHBOARD_CONTAINER_NAME:-stpeteit-dashboard}
|
||||
hostname: ${DASHBOARD_CONTAINER_NAME:-stpeteit-dashboard}
|
||||
domainname: ${DASHBOARD_DOMAIN:-dashboard.${BACKEND_DOMAIN:-convex.stpete.com}}
|
||||
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:-stpeteit-backend}:${PORT:-3210}}
|
||||
depends_on:
|
||||
stpeteit-backend:
|
||||
condition: service_healthy
|
||||
stdin_open: true
|
||||
tty: true
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 10s
|
||||
stop_signal: SIGINT
|
||||
|
||||
#convexmonorepo-postgresql:
|
||||
#image: postgres:17
|
||||
#container_name: ${POSTGRES_CONTAINER_NAME:-convexmonorepo-postgres}
|
||||
#hostname: ${POSTGRES_CONTAINER_NAME:-convexmonorepo-postgres}
|
||||
#domainname: postgres.${NEXT_DOMAIN:-convexmonorepo.gbrown.org}
|
||||
#networks: ['${NETWORK:-nginx-bridge}']
|
||||
#ports: ['5432:5432']
|
||||
#environment:
|
||||
#- POSTGRES_USER=${POSTGRES_USER:-convexmonorepo}
|
||||
#- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
#- POSTGRES_DB=${POSTGRES_DB:-convexmonorepo_payload}
|
||||
#labels: ['com.centurylinklabs.watchtower.enable=true']
|
||||
#volumes: ['./volumes/postgres:/var/lib/postgresql/data:Z']
|
||||
#tty: true
|
||||
#stdin_open: true
|
||||
#restart: unless-stopped
|
||||
#healthcheck:
|
||||
#test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"]
|
||||
#start_period: 20s
|
||||
#interval: 30s
|
||||
#retries: 5
|
||||
#timeout: 5s
|
||||
@@ -0,0 +1,21 @@
|
||||
[Unit]
|
||||
RequiresMountsFor=/home/gib/Media
|
||||
Description=Podman Compose: StPeteIT
|
||||
After=network-online.target podman.socket
|
||||
Wants=network-online.target
|
||||
StartLimitIntervalSec=300
|
||||
StartLimitBurst=3
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
WorkingDirectory=%h/Server/StPeteIT
|
||||
ExecStart=/usr/bin/podman compose up -d
|
||||
ExecStop=/usr/bin/podman compose down
|
||||
RemainAfterExit=yes
|
||||
TimeoutStartSec=900
|
||||
TimeoutStopSec=90
|
||||
Restart=on-failure
|
||||
RestartSec=30
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Reference in New Issue
Block a user