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.
This commit is contained in:
2025-02-27 13:23:14 +01:00
parent 03f4792232
commit d283f3a3ed
6 changed files with 162 additions and 56 deletions

25
.env.template Normal file
View File

@@ -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

5
.gitignore vendored
View File

@@ -262,6 +262,8 @@ celerybeat.pid
# Environments # Environments
.env .env
.env.*
!.env.template
.venv .venv
env/ env/
venv/ venv/
@@ -300,3 +302,6 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder. # option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/ .idea/
*.iml *.iml
# Docker volumes
postgres_data*/

13
Makefile Normal file
View File

@@ -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

View File

@@ -1,37 +1,34 @@
# Use Python 3.12 as the base image # Development stage
FROM python:3.12-slim FROM python:3.12-slim AS development
# Set working directory
WORKDIR /app WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE=1 \
# Set environment variables PYTHONUNBUFFERED=1 \
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1 RUN apt-get update && \
ENV PYTHONPATH=/app apt-get install -y --no-install-recommends gcc postgresql-client && \
apt-get clean && \
# Install system dependencies rm -rf /var/lib/apt/lists/*
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
COPY requirements.txt . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
# Copy application code
COPY . . COPY . .
COPY entrypoint.sh /usr/local/bin/
# 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
RUN chmod +x /usr/local/bin/entrypoint.sh RUN chmod +x /usr/local/bin/entrypoint.sh
# Expose port
EXPOSE 8000
# Set the entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Default command # Production stage
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] 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"]

74
docker-compose.dev.yml Normal file
View File

@@ -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

View File

@@ -4,59 +4,51 @@ services:
volumes: volumes:
- postgres_data:/var/lib/postgresql/data/ - postgres_data:/var/lib/postgresql/data/
environment: environment:
- POSTGRES_USER=postgres - POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=postgres - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=eventspace - POSTGRES_DB=${POSTGRES_DB}
ports:
- "5432:5432"
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"] test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 5 retries: 5
networks: networks:
- app-network - app-network
restart: unless-stopped
backend: backend:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
volumes: target: production
- ./backend:/app
- ./uploads:/app/uploads
ports:
- "8000:8000"
environment: environment:
- DATABASE_URL=postgresql://postgres:postgres@db:5432/eventspace - DATABASE_URL=${DATABASE_URL}
- SECRET_KEY=your_secret_key_here - SECRET_KEY=${SECRET_KEY}
- ENVIRONMENT=development - ENVIRONMENT=production
- DEBUG=true - DEBUG=false
- BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS}
depends_on: depends_on:
db: db:
condition: service_healthy condition: service_healthy
networks: networks:
- app-network - app-network
restart: unless-stopped
frontend: frontend:
build: build:
context: ./frontend context: ./frontend
dockerfile: Dockerfile dockerfile: Dockerfile
target: runner
args: args:
- NEXT_PUBLIC_API_URL=http://backend:8000 - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
ports:
- "3000:3000"
environment: environment:
- NODE_ENV=production - NODE_ENV=production
- NEXT_PUBLIC_API_URL=http://backend:8000 - NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
depends_on: depends_on:
- backend - backend
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3000"]
interval: 10s
timeout: 5s
retries: 3
networks: networks:
- app-network - app-network
restart: unless-stopped
volumes: volumes:
postgres_data: postgres_data: