From d283f3a3ed283555539ff2692d988a31117185fe Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Thu, 27 Feb 2025 13:23:14 +0100 Subject: [PATCH] Refactor Docker setup for environment flexibility and dev support Moved environment variables to .env.template for better management and updated docker-compose files to use them. Added separate docker-compose.dev.yml for development, a Makefile for streamlined commands, and split backend Dockerfile into development and production stages. Updated .gitignore to include new changes. --- .env.template | 25 ++++++++++++++ .gitignore | 5 +++ Makefile | 13 ++++++++ backend/Dockerfile | 57 +++++++++++++++----------------- docker-compose.dev.yml | 74 ++++++++++++++++++++++++++++++++++++++++++ docker-compose.yml | 44 ++++++++++--------------- 6 files changed, 162 insertions(+), 56 deletions(-) create mode 100644 .env.template create mode 100644 Makefile create mode 100644 docker-compose.dev.yml diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..91bc5d2 --- /dev/null +++ b/.env.template @@ -0,0 +1,25 @@ +# Common settings +PROJECT_NAME=EventSpace +VERSION=1.0.0 + +# Database settings +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres +POSTGRES_DB=eventspace +POSTGRES_HOST=db +POSTGRES_PORT=5432 +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} + +# Backend settings +BACKEND_PORT=8000 +SECRET_KEY=your_secret_key_here +ENVIRONMENT=development +DEBUG=true +BACKEND_CORS_ORIGINS=["http://localhost:3000"] +FIRST_SUPERUSER_EMAIL=admin@example.com +FIRST_SUPERUSER_PASSWORD=admin123 + +# Frontend settings +FRONTEND_PORT=3000 +NEXT_PUBLIC_API_URL=http://localhost:8000 +NODE_ENV=development \ No newline at end of file diff --git a/.gitignore b/.gitignore index d2b0246..64381b4 100644 --- a/.gitignore +++ b/.gitignore @@ -262,6 +262,8 @@ celerybeat.pid # Environments .env +.env.* +!.env.template .venv env/ venv/ @@ -300,3 +302,6 @@ cython_debug/ # option (not recommended) you can uncomment the following to ignore the entire idea folder. .idea/ *.iml + +# Docker volumes +postgres_data*/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..90b9d53 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +.PHONY: dev prod down clean + +dev: + docker compose -f docker-compose.dev.yml up --build -d + +prod: + docker compose up --build -d + +down: + docker compose down + +clean: + docker compose down -v \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index 5b57ad4..625a92b 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,37 +1,34 @@ -# Use Python 3.12 as the base image -FROM python:3.12-slim - -# Set working directory +# Development stage +FROM python:3.12-slim AS development WORKDIR /app - -# Set environment variables -ENV PYTHONDONTWRITEBYTECODE=1 -ENV PYTHONUNBUFFERED=1 -ENV PYTHONPATH=/app - -# Install system dependencies -RUN apt-get update \ - && apt-get install -y --no-install-recommends gcc postgresql-client \ - && apt-get clean \ - && rm -rf /var/lib/apt/lists/* - -# Install Python dependencies +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app +RUN apt-get update && \ + apt-get install -y --no-install-recommends gcc postgresql-client && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt - -# Copy application code COPY . . - -# Set up entrypoint script -# Note: entrypoint.sh is at the root of the backend directory, not in a scripts folder -COPY entrypoint.sh /usr/local/bin/entrypoint.sh +COPY entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/entrypoint.sh - -# Expose port -EXPOSE 8000 - -# Set the entrypoint ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -# Default command -CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] \ No newline at end of file +# Production stage +FROM python:3.12-slim AS production +WORKDIR /app +ENV PYTHONDONTWRITEBYTECODE=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONPATH=/app +RUN apt-get update && \ + apt-get install -y --no-install-recommends postgresql-client && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt +COPY . . +COPY entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/entrypoint.sh +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..5c848ba --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,74 @@ +services: + db: + image: postgres:17-alpine + volumes: + - postgres_data_dev:/var/lib/postgresql/data/ + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + ports: + - "5432:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] + interval: 5s + timeout: 5s + retries: 5 + networks: + - app-network + + backend: + build: + context: ./backend + dockerfile: Dockerfile + target: development + volumes: + - ./backend:/app + - ./uploads:/app/uploads + - backend_dev_modules:/app/.venv + ports: + - "8000:8000" + environment: + - DATABASE_URL=${DATABASE_URL} + - SECRET_KEY=${SECRET_KEY} + - ENVIRONMENT=development + - DEBUG=true + - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} + depends_on: + db: + condition: service_healthy + networks: + - app-network + command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + target: deps + args: + - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} + volumes: + - ./frontend:/app + - frontend_dev_modules:/app/node_modules + - frontend_dev_next:/app/.next + ports: + - "3000:3000" + environment: + - NODE_ENV=development + - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} + depends_on: + - backend + command: npm run dev + networks: + - app-network + +volumes: + postgres_data_dev: + backend_dev_modules: + frontend_dev_modules: + frontend_dev_next: + +networks: + app-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 95962b7..e8bad19 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,63 +4,55 @@ services: volumes: - postgres_data:/var/lib/postgresql/data/ environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres - - POSTGRES_DB=eventspace - ports: - - "5432:5432" + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"] interval: 5s timeout: 5s retries: 5 networks: - app-network + restart: unless-stopped backend: build: context: ./backend dockerfile: Dockerfile - volumes: - - ./backend:/app - - ./uploads:/app/uploads - ports: - - "8000:8000" + target: production environment: - - DATABASE_URL=postgresql://postgres:postgres@db:5432/eventspace - - SECRET_KEY=your_secret_key_here - - ENVIRONMENT=development - - DEBUG=true + - DATABASE_URL=${DATABASE_URL} + - SECRET_KEY=${SECRET_KEY} + - ENVIRONMENT=production + - DEBUG=false + - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} depends_on: db: condition: service_healthy networks: - app-network + restart: unless-stopped + frontend: build: context: ./frontend dockerfile: Dockerfile + target: runner args: - - NEXT_PUBLIC_API_URL=http://backend:8000 - ports: - - "3000:3000" + - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} environment: - NODE_ENV=production - - NEXT_PUBLIC_API_URL=http://backend:8000 + - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL} depends_on: - backend - healthcheck: - test: ["CMD", "wget", "--spider", "http://localhost:3000"] - interval: 10s - timeout: 5s - retries: 3 networks: - app-network - + restart: unless-stopped volumes: postgres_data: networks: app-network: - driver: bridge + driver: bridge \ No newline at end of file