-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDockerfile
More file actions
160 lines (133 loc) · 4.18 KB
/
Copy pathDockerfile
File metadata and controls
160 lines (133 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Multi-stage Dockerfile for OpenLearnX Platform
FROM node:26-alpine AS frontend-builder
# Build Frontend
WORKDIR /app/frontend
COPY frontend/package.json frontend/pnpm-lock.yaml* ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile
COPY frontend/ ./
ENV NEXT_TELEMETRY_DISABLED=1
RUN pnpm run build
# Main Python image with everything
FROM python:3.14-slim
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
ENV TF_CPP_MIN_LOG_LEVEL=2
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
# Install system dependencies (Python + Node.js)
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
gcc \
g++ \
libpq-dev \
curl \
wget \
ca-certificates \
gnupg \
nginx \
supervisor \
&& curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g pnpm \
&& rm -rf /var/lib/apt/lists/*
# Set work directory
WORKDIR /app
# Copy and install Python dependencies
COPY backend/requirements.txt ./backend/
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir -r backend/requirements.txt
# Copy backend code
COPY backend/ ./backend/
# Copy built frontend from previous stage
COPY --from=frontend-builder /app/frontend/.next/standalone ./frontend/
COPY --from=frontend-builder /app/frontend/.next/static ./frontend/.next/static
COPY --from=frontend-builder /app/frontend/public ./frontend/public
# Create necessary directories
RUN mkdir -p /var/log/supervisor \
&& mkdir -p /app/logs \
&& mkdir -p /app/uploads
# Configure Nginx
COPY <<EOF /etc/nginx/sites-available/openlearnx
server {
listen 80;
server_name localhost;
# Frontend
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Backend API
location /api/ {
proxy_pass http://127.0.0.1:5000/;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Health check
location /health {
access_log off;
return 200 "healthy\\n";
add_header Content-Type text/plain;
}
}
EOF
RUN ln -s /etc/nginx/sites-available/openlearnx /etc/nginx/sites-enabled/ \
&& rm /etc/nginx/sites-enabled/default
# Configure Supervisor
COPY <<EOF /etc/supervisor/conf.d/openlearnx.conf
[supervisord]
nodaemon=true
user=root
logfile=/var/log/supervisor/supervisord.log
pidfile=/var/run/supervisord.pid
[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/nginx.err.log
stdout_logfile=/var/log/supervisor/nginx.out.log
[program:backend]
command=gunicorn --bind 127.0.0.1:5000 --workers 4 --timeout 120 main:app
directory=/app/backend
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/backend.err.log
stdout_logfile=/var/log/supervisor/backend.out.log
environment=PYTHONPATH="/app/backend"
[program:frontend]
command=node server.js
directory=/app/frontend
autostart=true
autorestart=true
stderr_logfile=/var/log/supervisor/frontend.err.log
stdout_logfile=/var/log/supervisor/frontend.out.log
environment=PORT="3000",HOSTNAME="127.0.0.1"
EOF
# Create non-root user
RUN adduser --disabled-password --gecos '' appuser \
&& chown -R appuser:appuser /app \
&& chown -R appuser:appuser /var/log/supervisor
# Health check script
COPY <<EOF /app/healthcheck.sh
#!/bin/bash
curl -f http://127.0.0.1/health && \
curl -f http://127.0.0.1:3000/ && \
curl -f http://127.0.0.1:5000/api/health
EOF
RUN chmod +x /app/healthcheck.sh
# Switch to non-root user for app files
USER appuser
# Expose port
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD /app/healthcheck.sh || exit 1
# Switch back to root for supervisor
USER root
# Start all services with supervisor
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/openlearnx.conf"]