uvlava/services/artifacts-stack
Natalie 5748757345 infra(services): one-shot apply.sh for the producer-separated artifacts stack
Backs up, ships compose/Caddyfile/verdaccio configs, migrates the shared registry
into verdaccio-ct, docker compose up, caddy reload, verifies npm.{ct,mc,quinn}.
Idempotent. Run via ! (shared multi-org host, not auto-mode).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-01 08:07:04 -04:00
..
apply.sh infra(services): one-shot apply.sh for the producer-separated artifacts stack 2026-07-01 08:07:04 -04:00
Caddyfile infra(services): IaC the artifacts-host stack + producer-separate npm (verdaccio-ct/mc/quinn) 2026-07-01 08:02:22 -04:00
docker-compose.yml infra(services): IaC the artifacts-host stack + producer-separate npm (verdaccio-ct/mc/quinn) 2026-07-01 08:02:22 -04:00
README.md infra(services): IaC the artifacts-host stack + producer-separate npm (verdaccio-ct/mc/quinn) 2026-07-01 08:02:22 -04:00
verdaccio-ct.config.yaml infra(services): IaC the artifacts-host stack + producer-separate npm (verdaccio-ct/mc/quinn) 2026-07-01 08:02:22 -04:00
verdaccio-downstream.config.yaml infra(services): IaC the artifacts-host stack + producer-separate npm (verdaccio-ct/mc/quinn) 2026-07-01 08:02:22 -04:00

Artifacts-host service stack (forge + npm, producer-separated)

Source of truth for the /opt/services Docker stack on the artifacts host (com.uvlava.quinn.artifacts, reserved IP 134.199.243.61, reached via ssh -J quinn-vps root@134.199.243.61). This stack was host-only until 2026-07-01 — captured here and extended with per-producer npm.

Topology

Producer forge (git+web+pypi) npm (Verdaccio) data
ct forge.ct / pypi.ctforgejo-ct npm.ctverdaccio-ct /opt/services/ct, /opt/services/verdaccio-ct
mc forge.mc / pypi.mcforgejo-mc npm.mcverdaccio-mc /opt/services/mc, /opt/services/verdaccio-mc
quinn forge.quinn / pypi.quinnforgejo-quinn npm.quinnverdaccio-quinn /opt/services/quinn, /opt/services/verdaccio-quinn

Forges were already separate; the change here is splitting the single shared verdaccio into verdaccio-{ct,mc,quinn} and routing npm.<p> to each (was wrongly pointing at the Forgejo containers). ct owns @cocotte/* + @lilith/*; mc/quinn read-proxy those from ct (ctnpm uplink) but publish their own scopes locally — see verdaccio-*.config.yaml. For full isolation, drop the @cocotte/@lilith proxy blocks from verdaccio-downstream.config.yaml.

Apply (run on the host via ! — auto-mode can't touch this shared box)

# 1. ship the stack files
rsync -az artifacts-stack/docker-compose.yml   root@134.199.243.61:/opt/services/docker-compose.yml
rsync -az artifacts-stack/Caddyfile            root@134.199.243.61:/opt/services/Caddyfile
# 2. on the host: lay out per-producer verdaccio dirs + configs, migrate ct packages
ssh -J quinn-vps root@134.199.243.61 '
  cd /opt/services
  cp -a docker-compose.yml docker-compose.yml.bak; cp -a Caddyfile Caddyfile.bak
  for p in ct mc quinn; do mkdir -p verdaccio-$p/storage verdaccio-$p/conf; done
  # ct inherits every package + the htpasswd already published to the shared registry
  [ -d verdaccio/storage ] && cp -a verdaccio/storage/. verdaccio-ct/storage/ || cp -a verdaccio/. verdaccio-ct/storage/
'
# 3. drop the configs in place
rsync -az artifacts-stack/verdaccio-ct.config.yaml         root@134.199.243.61:/opt/services/verdaccio-ct/conf/config.yaml
rsync -az artifacts-stack/verdaccio-downstream.config.yaml root@134.199.243.61:/opt/services/verdaccio-mc/conf/config.yaml
rsync -az artifacts-stack/verdaccio-downstream.config.yaml root@134.199.243.61:/opt/services/verdaccio-quinn/conf/config.yaml
# 4. bring it up + reload edge
ssh -J quinn-vps root@134.199.243.61 'cd /opt/services && docker compose up -d && docker exec services-caddy-1 caddy reload --config /etc/caddy/Caddyfile'

Verify

curl -s https://npm.ct.uvlava.com/-/ping && echo ok
curl -s https://npm.ct.uvlava.com/@cocotte/ai-harness | head -c 80   # ct serves the pkg
curl -s https://npm.mc.uvlava.com/@cocotte/ai-harness | head -c 80    # mc read-proxies from ct

After it's up — point consumers at HTTPS (closes the plaintext finding)

Replace http://134.199.243.61:4873 with https://npm.ct.uvlava.com/ in: ~/.npmrc, prospector .npmrc + web/.npmrc, deploy/deploy-server.sh (the .npmrc it ships), and any bunfig.toml. Re-auth if the old JWT is rejected: npm login --registry https://npm.ct.uvlava.com/ --scope @cocotte.

DNS: npm.mc / npm.quinn records must exist in uvlava/terraform/do/dns.tf (add A records → the artifacts droplet, like npm.ct, if not already present).