Remove dedicated static-init service and run collectstatic in the init sidecar instead. Static files baked into the image are copied to /mnt/static for nginx serving on each deployment. Also update MCP and nginx ports and refresh external service hostnames in comments.
103 lines
3.5 KiB
Bash
103 lines
3.5 KiB
Bash
#!/bin/sh
|
|
# Mnemosyne container entrypoint.
|
|
#
|
|
# The same image runs all three processes — the compose service supplies
|
|
# `web`, `mcp`, `worker`, or `migrate` as CMD.
|
|
|
|
set -e
|
|
|
|
case "$1" in
|
|
web)
|
|
# Django REST API + admin (gunicorn → wsgi).
|
|
exec gunicorn \
|
|
--config /app/docker/gunicorn.conf.py \
|
|
--bind 0.0.0.0:8000 \
|
|
--workers "${GUNICORN_WORKERS:-3}" \
|
|
--access-logfile - \
|
|
--error-logfile - \
|
|
mnemosyne.wsgi:application
|
|
;;
|
|
|
|
mcp)
|
|
# FastMCP over Streamable HTTP at /mcp/, mounted by mnemosyne.asgi.
|
|
exec uvicorn \
|
|
--host 0.0.0.0 \
|
|
--port 8001 \
|
|
--workers "${UVICORN_WORKERS:-1}" \
|
|
mnemosyne.asgi:app
|
|
;;
|
|
|
|
worker)
|
|
# Celery worker covering embedding + ingest + batch + default queues.
|
|
# In production you may want to split these onto separate worker
|
|
# services for queue-level isolation; one process is fine to start.
|
|
exec celery -A mnemosyne worker \
|
|
--loglevel="${CELERY_LOG_LEVEL:-info}" \
|
|
--queues="${CELERY_QUEUES:-celery,embedding,batch}" \
|
|
--concurrency="${CELERY_CONCURRENCY:-2}"
|
|
;;
|
|
|
|
beat)
|
|
# Celery scheduled tasks (only needed if/when periodic jobs are wired).
|
|
exec celery -A mnemosyne beat \
|
|
--loglevel="${CELERY_LOG_LEVEL:-info}"
|
|
;;
|
|
|
|
migrate)
|
|
# One-shot DB migration runner — invoke before bringing services up
|
|
# for the first time or after a deploy.
|
|
exec python manage.py migrate --noinput
|
|
;;
|
|
|
|
setup)
|
|
# One-shot init — Neo4j indexes + library_type seed data. Run this
|
|
# manually after the system embedding model has been configured in the
|
|
# admin (setup_neo4j_indexes reads vector dimensions from that row).
|
|
python manage.py setup_neo4j_indexes
|
|
python manage.py load_library_types
|
|
;;
|
|
|
|
init)
|
|
# Bundled one-shot init run by the `init` sidecar on every
|
|
# `docker compose up`. Idempotent: re-runs are no-ops unless migrations
|
|
# or library_type defaults need to change. A non-zero exit here blocks
|
|
# `app`, `mcp`, and `worker` from starting.
|
|
#
|
|
# collectstatic copies the static files baked into the image at build
|
|
# time (/app/staticfiles) into STATIC_ROOT (/mnt/static), which nginx
|
|
# serves directly. --clear removes any stale files from the previous
|
|
# deploy before copying, so deleted assets don't linger.
|
|
#
|
|
# Neo4j vector-index creation is *deliberately not* bundled here. That
|
|
# command (``setup_neo4j_indexes``) requires a system embedding model
|
|
# with a configured ``vector_dimensions`` value, and that model is
|
|
# data an operator configures through the Django admin after first
|
|
# boot. On a fresh stack there is no such row yet, so blocking the
|
|
# whole stack on it would make the admin unreachable — a chicken-and-
|
|
# egg. Operator bootstrap flow:
|
|
#
|
|
# 1. docker compose up # init sidecar: migrate + collectstatic + load_library_types
|
|
# 2. browse to admin, configure system embedding model
|
|
# 3. docker compose exec app python manage.py setup_neo4j_indexes
|
|
#
|
|
# Until step 3 runs, vector search will return empty results — the
|
|
# readiness check in library/apps.py logs a warning when indexes are
|
|
# missing so this is visible, not silent.
|
|
set -e
|
|
python manage.py migrate --noinput
|
|
python manage.py collectstatic --noinput --clear
|
|
python manage.py load_library_types
|
|
;;
|
|
|
|
|
|
shell)
|
|
# Drop into the management shell for ad-hoc work.
|
|
exec python manage.py shell
|
|
;;
|
|
|
|
*)
|
|
# Fall through: run whatever was passed (e.g. `manage.py <cmd>`).
|
|
exec "$@"
|
|
;;
|
|
esac
|