Skip to content

Deploy

For operators running their own OdyssAI-X. Two ways to ship a change: a hot patch (seconds) or a full rebuild (a minute). Pick by what you touched.

The invariant: what’s on the server equals what’s in your main branch. Ship changes from version control, not by hand-editing files on the box.

For a change to api.py or dashboard.html, copy the file into the running container — no image rebuild:

Terminal window
scp scripts/api.py scripts/dashboard.html admin@<server>:/tmp/
ssh admin@<server> 'docker cp /tmp/api.py odyssai-odysseus:/app/api.py'
ssh admin@<server> 'docker cp /tmp/dashboard.html odyssai-odysseus:/app/dashboard.html'

Then:

  • dashboard.html is served fresh per request — no restart needed.
  • api.py is loaded once at process start — restart to apply:
    Terminal window
    ssh admin@<server> 'docker restart odyssai-odysseus'

A restart drops loaded pools (the orphan sweep frees JACCL state). A local pool reloads on its next request (a one-time cold prefill). Restart only when the api.py change requires it, and prefer a low-traffic moment.

When you change dependencies, the Dockerfile, or want a clean image:

Terminal window
ssh admin@<server> 'cd <repo> && docker compose up -d --build'

--force-recreate if you need to recreate the container without a code change (e.g. to apply a renamed container or an .env change):

Terminal window
docker compose up -d --no-deps --force-recreate odyssai-odysseus

Confirm the engine came back and the routes work:

Terminal window
curl -sf http://<server>:8000/health # back to idle?
curl -s http://<server>:8000/v1/models # catalog present?

If a model was loaded before the restart, give it the reload time before expecting fast TTFT. See Cluster health.

A hot-patch is trivially reversible — keep the previous api.py (docker cp odyssai-odysseus:/app/api.py /tmp/api.py.bak before you patch) and copy it back + restart if the new one misbehaves. For an image, redeploy the previous tag.