- Change the build process to allow cache busting - Optimisations to the build process - Several improvements of UI geared towards mobile experience -
5.9 KiB
5.9 KiB
Migratieplan: Standaardisatie van Startup Processen en Docker Builds
Dit document beschrijft de migratie-afspraken rond het opstarten van onze applicaties, inclusief het gebruik van een generiek startscript, het inzetten van tini als entrypoint, en de overstap naar een shared base build structuur.
Doel: standaardisatie, betere betrouwbaarheid in Kubernetes, en snellere builds.
1. Generiek startscript (scripts/start.sh)
Doel
- Eén startscript voor alle rollen: web, worker, beat.
- Gedrag wordt bepaald via environment variables (
ROLE=web|worker|beat). - Geen “magische” verschillen meer tussen Podman en Kubernetes.
Voorbeeld
#!/usr/bin/env bash
set -euo pipefail
ROLE="${ROLE:-web}"
case "$ROLE" in
web)
exec gunicorn -w "${WORKERS:-1}" -k "${WORKER_CLASS:-gevent}" -b "0.0.0.0:${PORT:-8080}" --worker-connections "${WORKER_CONN:-100}" --access-logfile - --error-logfile - --log-level "${LOGLEVEL:-info}" scripts.run_eveai_app:app
;;
worker)
exec celery -A scripts.run_eveai_workers worker --loglevel="${CELERY_LOGLEVEL:-INFO}" --concurrency="${CELERY_CONCURRENCY:-2}" --max-tasks-per-child="${CELERY_MAX_TASKS_PER_CHILD:-1000}" --prefetch-multiplier="${CELERY_PREFETCH:-1}" -O fair
;;
beat)
exec celery -A scripts.run_eveai_workers beat --loglevel="${CELERY_LOGLEVEL:-INFO}"
;;
*)
echo "Unknown ROLE=$ROLE" >&2
exit 1
;;
esac
Belangrijk
- Geen init/migraties meer in het startscript (die draaien we via Jobs/CronJobs).
- Geen
cd,chown, of PYTHONPATH-hacks in startscript → alles naar Dockerfile. - Altijd
execgebruiken zodat processen signalen correct ontvangen.
2. Gebruik van tini als ENTRYPOINT
Waarom?
- In containers draait het eerste proces als PID 1.
- Zonder init-proces worden signalen niet correct doorgegeven en ontstaan zombieprocessen.
tiniis een lichtgewicht init die dit oplost.
Implementatie
RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["/usr/bin/tini","-g","--"]
CMD ["bash","-lc","scripts/start.sh"]
-g= stuur signalen naar de hele process group (belangrijk voor Gunicorn en Celery).- Hiermee is een apart
entrypoint.shniet meer nodig.
3. Verplaatsen van logica naar Dockerfile
Wat naar de Dockerfile moet
WORKDIR /appENV PYTHONPATH=/app:/app/patched_packages:$PYTHONPATHENV FLASK_APP=/app/scripts/run_eveai_app.py(alleen nodig voor CLI, niet voor gunicorn)- User-aanmaak en permissies:
ARG UID=10001 ARG GID=10001 RUN groupadd -g ${GID} appuser && useradd -u ${UID} -g ${GID} -M -d /nonexistent -s /usr/sbin/nologin appuser RUN chown -R appuser:appuser /app USER appuser
Wat niet meer in startscript hoort
cd /appexport PYTHONPATH=...chown -R ... /logs- DB-migraties of cache-invalidatie → deze verhuizen naar Kubernetes Jobs/CronJobs.
4. Kubernetes Jobs & CronJobs
Use cases
- Jobs → eenmalige taken zoals DB-migraties of cache-invalidatie.
- CronJobs → geplande taken (bv. nachtelijke opschoningen).
Waarom?
- Startup scripts blijven lean.
- Geen race conditions bij meerdere replicas.
- Flexibel los van deploys uit te voeren.
5. Docker builds: naar een shared base (Optie B)
Nieuwe structuur
repo/
├─ Dockerfile.base
├─ requirements.txt
├─ common/
├─ config/
├─ scripts/
├─ patched_packages/
├─ docker/
│ ├─ eveai_app/Dockerfile
│ ├─ eveai_api/Dockerfile
│ └─ eveai_workers/Dockerfile
└─ compose_dev.yaml
Dockerfile.base
FROM python:3.12-slim
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1
RUN apt-get update && apt-get install -y --no-install-recommends tini && rm -rf /var/lib/apt/lists/*
ARG UID=10001
ARG GID=10001
RUN groupadd -g ${GID} appuser && useradd -u ${UID} -g ${GID} -M -d /nonexistent -s /usr/sbin/nologin appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY common /app/common
COPY config /app/config
COPY scripts /app/scripts
COPY patched_packages /app/patched_packages
RUN chown -R appuser:appuser /app && chmod +x /app/scripts/start.sh
ENV PYTHONPATH=/app:/app/patched_packages:${PYTHONPATH} ROLE=web PORT=8080
USER appuser
EXPOSE 8080
ENTRYPOINT ["/usr/bin/tini","-g","--"]
CMD ["bash","-lc","scripts/start.sh"]
Service Dockerfiles
docker/eveai_app/Dockerfile
FROM yourorg/eveai-base:py312-v1
WORKDIR /app
COPY eveai_app /app/eveai_app
COPY migrations /app/migrations
COPY content /app/content
ENV ROLE=web PORT=8080
docker/eveai_api/Dockerfile
FROM yourorg/eveai-base:py312-v1
WORKDIR /app
COPY eveai_api /app/eveai_api
ENV ROLE=web PORT=8080
docker/eveai_workers/Dockerfile
FROM yourorg/eveai-base:py312-v1
WORKDIR /app
COPY eveai_workers /app/eveai_workers
ENV ROLE=worker
6. Workflow afspraken
- Startscript is generiek → gedrag via env (
ROLE=...). - Geen init-taken meer in startscript → Jobs/CronJobs in k8s.
tinials ENTRYPOINT → correcte signalen en zombie-cleanup.- Dockerfile regelt PYTHONPATH, FLASK_APP, permissies en user.
- Base image bevat Python, deps en common code.
- Service-images kopiëren enkel hun eigen directories.
- Build flow:
- Base builden/pushen bij gewijzigde deps/common.
- Services snel erbovenop rebuilden bij code-wijzigingen.
7. Samenvatting
Met deze migratie krijgen we:
- Eenvoudiger startscript (alleen proceskeuze).
- Betere betrouwbaarheid bij shutdowns (via tini).
- Strikte scheiding tussen lifecycle taken en runtime.
- Snellere builds via shared base image.
- Uniforme aanpak in zowel Podman/Compose als Kubernetes.