hp-studios-ai-content-agent/deploy
DJP b0516d8bba deploy.sh: patch sites-enabled too (it's diverged, not a symlink)
On this specific shared host, /etc/apache2/sites-enabled/*.conf is
a hand-maintained copy of sites-available, not the usual a2ensite
symlink. Apache loads sites-enabled, so patching sites-available
alone produced exactly the observed bug: configtest passed, our
Include sat in sites-available, and Apache kept 404-ing because the
active config had no Include line.

Script now:
- lists sites-enabled paths first, sites-available second
- readlink -f resolves each to its real path; a dedup set skips
  double-patching when the enabled entry IS a normal symlink
- picks up both the plain HTTP vhost and any *-le-ssl.conf variant

A symlink-based install keeps working (one file edited once); a
divergent-copy install like this one gets both files patched.
2026-04-22 17:09:05 -04:00
..
apache Add deploy script, prod compose override, and Apache subpath proxy 2026-04-22 15:23:51 -04:00
deploy.sh deploy.sh: patch sites-enabled too (it's diverged, not a symlink) 2026-04-22 17:09:05 -04:00
README.md Add deploy script, prod compose override, and Apache subpath proxy 2026-04-22 15:23:51 -04:00

Deploy — HP Studios AI Content Agent

Idempotent deployment to optical-dev.oliver.solutions (or any shared Apache + Docker Linux box).

Public URL: https://optical-dev.oliver.solutions/hp-content-agent/

First-time setup on the server

# SSH in, clone the repo somewhere you want it to live
ssh you@optical-dev.oliver.solutions
sudo git clone git@bitbucket.org:zlalani/hp-studios-ai-content-agent.git /opt/hp-studios-ai-content-agent
cd /opt/hp-studios-ai-content-agent

# Bootstrap .env (will error and tell you what secrets to fill)
sudo ./deploy/deploy.sh
# Edit /opt/hp-studios-ai-content-agent/.env and fill:
#   ANTHROPIC_API_KEY=...
#   OPENAI_API_KEY=... (or VOYAGE_API_KEY)
# Everything else is auto-populated.

# Re-run to actually deploy
sudo ./deploy/deploy.sh

The script handles everything else:

  • Picks free host ports in 2000029999, stable across reruns
  • Builds + starts containers with project name hp-studios-ai-content-agent
  • Runs Alembic migrations + seeds admin user (first run prints credentials)
  • Renders the Apache snippet with the chosen ports
  • Adds an Include line to the vhost and reloads Apache
  • Ensures UFW allows 22/80

Re-deploy (after a git pull)

cd /opt/hp-studios-ai-content-agent
sudo git pull
sudo ./deploy/deploy.sh

Safe to re-run any time. Existing ports, secrets, and the admin user are preserved.

Apache integration

The script writes a rendered proxy snippet to deploy/apache/hp-content-agent.conf and adds an Include line inside the vhost at /etc/apache2/sites-available/optical-dev.oliver.solutions.conf. If the file doesn't exist, the script prints the Include line for manual addition.

The snippet proxies:

  • /hp-content-agent/api/127.0.0.1:$API_HOST_PORT
  • /hp-content-agent/127.0.0.1:$FRONTEND_HOST_PORT

Order matters in the rendered file — API rule precedes the catch-all frontend rule.

Common operations

# Status
docker compose -p hp-studios-ai-content-agent -f docker-compose.yml -f docker-compose.prod.yml ps

# Logs
docker compose -p hp-studios-ai-content-agent -f docker-compose.yml -f docker-compose.prod.yml logs -f api worker

# Shell into API container
docker compose -p hp-studios-ai-content-agent -f docker-compose.yml -f docker-compose.prod.yml exec api bash

# Rebuild just the frontend (after a merge that only changed frontend)
docker compose -p hp-studios-ai-content-agent -f docker-compose.yml -f docker-compose.prod.yml up -d --build frontend

# Tear down (keeps data volume; use -v to also wipe the DB)
docker compose -p hp-studios-ai-content-agent -f docker-compose.yml -f docker-compose.prod.yml down

Troubleshooting

  • 404 at /hp-content-agent/ — check the Include line is in the vhost and apache2ctl configtest passes. Check deploy/apache/hp-content-agent.conf points to the ports in docker compose ps.
  • API calls from the SPA 404 — open the browser Network tab. If requests go to /api/... instead of /hp-content-agent/api/..., the frontend wasn't rebuilt with VITE_API_URL=/hp-content-agent/api. Force a rebuild: docker compose … up -d --build frontend.
  • Port collisions — the script picks in 2000029999 and writes to .env. Delete the four *_HOST_PORT lines and re-run to reassign.
  • Cookies / auth fail — the JWT cookie is set on the root domain optical-dev.oliver.solutions with path /, so the subpath is fine. If requests fail with 401, check that CORS_ORIGIN=https://optical-dev.oliver.solutions is in .env (the script sets it).

What the script does not do

  • TLS / Let's Encrypt — handled by whatever already serves the vhost.
  • DNS — uses the existing optical-dev.oliver.solutions hostname, no record changes.
  • Backup — docker compose down keeps the Postgres data volume by default. Dump with docker compose … exec postgres pg_dump -U hp hp_content_agent > backup.sql if you want a snapshot before a risky change.