From e3a31fca7810795135eb4cf7a05aeb46c2e4d428 Mon Sep 17 00:00:00 2001 From: Viswamedha Nalabotu Date: Tue, 20 Jan 2026 04:23:43 +0000 Subject: [PATCH] Added production compose and Dockerfiles --- compose/prod/celery/Dockerfile | 26 ++++++ compose/prod/django/Dockerfile | 50 +++++++++++ compose/prod/docker-compose.mcp.yml | 26 ++++++ compose/prod/docker-compose.server.yml | 120 +++++++++++++++++++++++++ 4 files changed, 222 insertions(+) create mode 100644 compose/prod/celery/Dockerfile create mode 100644 compose/prod/django/Dockerfile create mode 100644 compose/prod/docker-compose.mcp.yml create mode 100644 compose/prod/docker-compose.server.yml diff --git a/compose/prod/celery/Dockerfile b/compose/prod/celery/Dockerfile new file mode 100644 index 0000000..6abee5e --- /dev/null +++ b/compose/prod/celery/Dockerfile @@ -0,0 +1,26 @@ +FROM python:3.12.0-slim + +LABEL org.opencontainers.image.title="Dynavera Celery Worker" +LABEL org.opencontainers.image.source="https://git.cs.bham.ac.uk/projects-2025-26/vxn217" + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +RUN apt-get update && apt-get install --no-install-recommends -y \ + build-essential \ + libpq-dev \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements/django.txt . +RUN pip install --no-cache-dir -r django.txt + +COPY manage.py manage.py +COPY config config +COPY apps apps +COPY data data + +RUN mkdir -p /app/static + +CMD ["celery", "-A", "config.celery", "worker", "--loglevel=info"] diff --git a/compose/prod/django/Dockerfile b/compose/prod/django/Dockerfile new file mode 100644 index 0000000..bf13235 --- /dev/null +++ b/compose/prod/django/Dockerfile @@ -0,0 +1,50 @@ +FROM node:22-alpine AS node + +WORKDIR /app + +COPY package*.json ./ + +RUN npm ci + +COPY vite.config.ts . +COPY tsconfig.json . +COPY package*.json . +COPY src ./src +COPY index.html . + +RUN npm run build + +FROM python:3.12.0-slim AS python + +LABEL org.opencontainers.image.title="Dynavera - An Agentic Approach to Role-Specific Trainers" +LABEL org.opencontainers.image.source="https://git.cs.bham.ac.uk/projects-2025-26/vxn217" +LABEL org.opencontainers.image.description="Dynavera (Final Year Project)" + +ENV PYTHONDONTWRITEBYTECODE=1 +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app + +RUN apt-get update && apt-get install --no-install-recommends -y \ + build-essential \ + libpq-dev \ + wait-for-it \ + && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ + && rm -rf /var/lib/apt/lists/* + +COPY requirements/django.txt . +RUN pip install --no-cache-dir -r django.txt + +COPY manage.py manage.py +COPY config config +COPY apps apps +COPY data data + +COPY --from=node /app/build ./build + +RUN mkdir -p /app/static + +COPY ./compose/prod/django/start /start +RUN sed -i 's/\r$//g' /start && chmod +x /start + +ENTRYPOINT ["/start"] \ No newline at end of file diff --git a/compose/prod/docker-compose.mcp.yml b/compose/prod/docker-compose.mcp.yml new file mode 100644 index 0000000..5bed2bb --- /dev/null +++ b/compose/prod/docker-compose.mcp.yml @@ -0,0 +1,26 @@ +services: + fyp-mcp-prod: + container_name: fyp-mcp-prod + build: + context: ../../ + dockerfile: compose/dev/mcp/Dockerfile + restart: unless-stopped + deploy: + mode: replicated + replicas: 1 + resources: + reservations: + devices: + - driver: nvidia + count: all + capabilities: [gpu] + env_file: + - ../../.env + environment: + - MCP_HTTP_HOST=0.0.0.0 + - MCP_HTTP_PORT=8001 + - NVIDIA_VISIBLE_DEVICES=all + ports: + - '0.0.0.0:${MCP_SERVER_PORT}:8001' + volumes: + - ../../:/app diff --git a/compose/prod/docker-compose.server.yml b/compose/prod/docker-compose.server.yml new file mode 100644 index 0000000..725548b --- /dev/null +++ b/compose/prod/docker-compose.server.yml @@ -0,0 +1,120 @@ +services: + fyp-django-prod: + container_name: fyp-django-prod + image: {FYP_DJANGO_IMAGE} + deploy: + mode: replicated + replicas: {FYP_DJANGO_REPLICAS} + env_file: + - ../../.env + labels: + - "traefik.enable=true" + - "traefik.http.routers.fyp-web.rule=Host(`${DJANGO_DOMAIN}`)" + - "traefik.http.routers.fyp-web.entrypoints=${DJANGO_ENTRYPOINT}" + - "traefik.http.routers.fyp-web.tls.certresolver=${CERTRESOLVER}" + - "traefik.http.services.fyp-web.loadbalancer.server.port=${DJANGO_PORT}" + - "com.centurylinklabs.watchtower.enable=true" + - "com.centurylinklabs.watchtower.scope=fyp" + volumes: + - ../../static:/app/static + - ../../media:/app/media + depends_on: + fyp-postgres-prod: + condition: service_healthy + networks: + - fyp-network + - proxy + + fyp-postgres-prod: + container_name: fyp-postgres-prod + image: postgres:15-alpine + hostname: fyp-postgres-prod + restart: unless-stopped + env_file: + - ../../.env + environment: + POSTGRES_HOST_AUTH_METHOD: trust + volumes: + - fyp_postgres_data:/var/lib/postgresql/data + healthcheck: + test: ['CMD-SHELL', 'pg_isready -h 127.0.0.1 -p 5432 -U ${POSTGRES_USER} -d ${POSTGRES_DB}'] + interval: 5s + timeout: 3s + retries: 5 + networks: + - fyp-network + + fyp-redis-prod: + container_name: fyp-redis-prod + image: redis:7-alpine + restart: unless-stopped + volumes: + - fyp_redis_data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 3s + retries: 5 + + fyp-celery-dev: + container_name: fyp-celery-dev + image: {FYP_CELERY_IMAGE} + env_file: + - ../../.env + volumes: + - ../../:/app + - ../../static:/app/static + - ../../media:/app/media + depends_on: + fyp-redis-prod: + condition: service_healthy + fyp-postgres-prod: + condition: service_healthy + + fyp-watchtower-prod: + container_name: fyp-watchtower-prod + image: containrrr/watchtower + command: + - "--scope=fyp" + - "--label-enable" + - "--interval" + - "30" + - "--rolling-restart" + environment: + - WATCHTOWER_CLEANUP=true + - REPO_USER=${GITLAB_USER} + - REPO_PASS=${GITLAB_PASS} + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + + fyp-runner-prod: + container_name: fyp-runner-prod + image: gitlab/gitlab-runner:${GITLAB_RUNNER_IMAGE_TAG} + restart: unless-stopped + environment: + - CI_SERVER_URL=${GITLAB_SERVER_URL} + - REGISTRATION_TOKEN=${GITLAB_RUNNER_REGISTRATION_TOKEN} + - RUNNER_EXECUTOR=docker + - RUNNER_RUN_UNTAGGED=true + - RUNNER_TAG_LIST= + - DOCKER_TLS_CERTDIR= + - DOCKER_IMAGE=${GITLAB_RUNNER_DOCKER_IMAGE} + volumes: + - gitlab-runner-config:/etc/gitlab-runner + - gitlab-machine-config:/root/.docker/machine + - /var/run/docker.sock:/var/run/docker.sock + command: + - run + - "--working-directory=/home/gitlab-runner" + +volumes: + fyp_postgres_data: + fyp_redis_data: + gitlab-runner-config: + gitlab-machine-config: + +networks: + fyp-network: + driver: bridge + proxy: + external: true