Skip to content

Commit 65089de

Browse files
committed
Phase 3: Production hardening
- Add gunicorn>=21.2.0 production server - Optimize Dockerfile with gunicorn + uvicorn workers - Add non-root user for security - Create .dockerignore to exclude cache, .env, tests, databases
1 parent dddd42c commit 65089de

File tree

3 files changed

+31
-32
lines changed

3 files changed

+31
-32
lines changed

backend/.dockerignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
__pycache__
2+
*.pyc
3+
*.pyo
4+
*.pyd
5+
.Python
6+
env/
7+
venv/
8+
.env
9+
.env.local
10+
.git
11+
.gitignore
12+
*.db
13+
*.sqlite
14+
.pytest_cache
15+
tests/

backend/Dockerfile

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,29 @@
1-
# LinkedIn Post Bot - Backend Dockerfile
2-
# Build: docker build -t linkedin-bot-backend .
3-
# Run: docker run -p 8000:8000 --env-file ../.env linkedin-bot-backend
4-
51
FROM python:3.11-slim
62

7-
# Set working directory
83
WORKDIR /app
94

10-
# Install system dependencies
11-
RUN apt-get update && apt-get install -y --no-install-recommends \
12-
gcc \
5+
# Install system dependencies (needed for some python packages)
6+
RUN apt-get update && apt-get install -y \
7+
build-essential \
8+
libpq-dev \
139
&& rm -rf /var/lib/apt/lists/*
1410

15-
# Copy requirements first (better caching)
16-
COPY requirements.txt .
17-
1811
# Install Python dependencies
12+
COPY requirements.txt .
1913
RUN pip install --no-cache-dir -r requirements.txt
2014

2115
# Copy application code
2216
COPY . .
2317

24-
# Copy services directory from parent (mounted at runtime or copied in CI)
25-
# Note: In production, ensure services/ is available at /app/services
26-
COPY ../services /app/services 2>/dev/null || true
27-
28-
# Add parent directory to Python path for services imports
29-
ENV PYTHONPATH=/app:/app/..
30-
31-
# Create directory for SQLite databases
32-
RUN mkdir -p /data
33-
34-
# Environment variables (override with -e or --env-file)
35-
ENV PORT=8000
36-
ENV TOKEN_DB_PATH=/data/tokens.db
37-
ENV USER_SETTINGS_DB_PATH=/data/user_settings.db
38-
ENV POST_HISTORY_DB_PATH=/data/post_history.db
18+
# Create a non-root user for security
19+
RUN useradd -m appuser && chown -R appuser:appuser /app
20+
USER appuser
3921

4022
# Expose port
4123
EXPOSE 8000
4224

43-
# Health check
44-
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
45-
CMD curl -f http://localhost:8000/health || exit 1
46-
47-
# Run the application
48-
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
25+
# Production Command: Use Gunicorn with Uvicorn workers
26+
# -w 4: Use 4 worker processes (adjust based on CPU cores)
27+
# -k uvicorn.workers.UvicornWorker: Use async workers
28+
# --bind 0.0.0.0:8000: Listen on all interfaces
29+
CMD ["gunicorn", "-w", "4", "-k", "uvicorn.workers.UvicornWorker", "app:app", "--bind", "0.0.0.0:8000"]

backend/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ asyncpg>=0.29.0
1515
databases[postgresql]>=0.9.0
1616
aiosqlite>=0.20.0 # For local dev SQLite fallback
1717

18+
# Production server
19+
gunicorn>=21.2.0
20+
1821
# Testing dependencies
1922
pytest>=7.4.0
2023
pytest-asyncio>=0.21.0

0 commit comments

Comments
 (0)