Skip to content

Commit 1131445

Browse files
committed
feat(docker): We can now serve the frontend from docker image.
1 parent a8033a2 commit 1131445

File tree

4 files changed

+101
-113
lines changed

4 files changed

+101
-113
lines changed

Dockerfile.frontend

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,12 @@
1-
# Frontend Dockerfile (save as Dockerfile.frontend)
21
FROM node:20-alpine AS builder
3-
4-
# Set working directory
52
WORKDIR /app
6-
7-
# Copy package files for dependency installation
83
COPY frontend/package*.json ./
9-
10-
# Install dependencies with cache mount for faster rebuilds
11-
RUN --mount=type=cache,target=/root/.npm \
12-
npm ci --only=production
13-
14-
# Copy frontend source code
15-
COPY frontend/ ./
16-
17-
# Build the frontend application
4+
RUN npm install
5+
COPY frontend/ .
186
RUN npm run build
197

20-
# Production stage with nginx
21-
FROM nginx:alpine AS runtime
22-
23-
# Remove default nginx website
24-
RUN rm -rf /usr/share/nginx/html/*
25-
26-
# Copy built frontend from builder stage
8+
FROM nginx:stable-alpine as production-stage
279
COPY --from=builder /app/dist /usr/share/nginx/html
28-
29-
# Copy custom nginx configuration (optional)
30-
# COPY frontend/nginx.conf /etc/nginx/nginx.conf
31-
32-
# Create nginx user and set permissions
33-
RUN addgroup -g 1000 -S appgroup && \
34-
adduser -u 1000 -S appuser -G appgroup && \
35-
chown -R appuser:appgroup /usr/share/nginx/html && \
36-
chown -R appuser:appgroup /var/cache/nginx && \
37-
chown -R appuser:appgroup /var/log/nginx && \
38-
chown -R appuser:appgroup /etc/nginx/conf.d
39-
40-
# Make nginx run as non-root
41-
RUN touch /var/run/nginx.pid && \
42-
chown -R appuser:appgroup /var/run/nginx.pid
43-
44-
# Switch to non-root user
45-
USER appuser
46-
47-
# Expose port
48-
EXPOSE 8080
49-
50-
# Health check
51-
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s --retries=3 \
52-
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1
53-
54-
# Start nginx
10+
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf
11+
EXPOSE 80
5512
CMD ["nginx", "-g", "daemon off;"]

docker-compose.yml

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ services:
2727
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER} # Load from .env
2828
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS} # Load from .env
2929
restart: unless-stopped
30+
healthcheck:
31+
test: rabbitmq-diagnostics -q ping
32+
interval: 30s
33+
timeout: 30s
34+
retries: 3
3035
volumes:
3136
- rabbitmqdata:/var/lib/rabbitmq/
3237

@@ -38,69 +43,69 @@ services:
3843
env_file:
3944
- .env
4045
restart: unless-stopped
46+
healthcheck:
47+
test: ["CMD", "redis-cli", "ping"]
48+
interval: 10s
49+
timeout: 5s
50+
retries: 3
4151
command: ["redis-server", "--requirepass", "${CACHE_PASSWORD}"]
4252
volumes:
4353
- cachedata:/data
4454

45-
# prometheus:
46-
# image: "prom/prometheus"
47-
# container_name: "my_chess_style_prom"
48-
# env_file:
49-
# - .env
50-
# command:
51-
# - "--config.file=/etc/prometheus/prometheus.yml"
52-
# ports:
53-
# - 9090:9090
54-
# restart: unless-stopped
55-
# volumes:
56-
# - ./observability/prometheus:/etc/prometheus
57-
# - prom_data:/prometheus
58-
#
59-
# grafana:
60-
# image: "grafana/grafana"
61-
# container_name: "my_chess_style_graf"
62-
# env_file:
63-
# - .env
64-
# ports:
65-
# - 3000:3000
66-
# restart: unless-stopped
67-
# environment:
68-
# - GF_SECURITY_ADMIN_USER=${GRAFANA_DEFAULT_USER}
69-
# - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_DEFAULT_PASS}
70-
# volumes:
71-
# - ./observability/grafana:/etc/grafana/provisioning/datasources
72-
#
73-
# pg_explorer:
74-
# image: "prometheuscommunity/postgres-exporter"
75-
# container_name: "my_chess_style_pg_explorer"
76-
# env_file:
77-
# - .env
78-
# ports:
79-
# - 9187:9187
80-
# depends_on:
81-
# pg_server:
82-
# condition: service_healthy
83-
# prometheus:
84-
# condition: service_started
85-
# restart: unless-stopped
55+
prometheus:
56+
image: "prom/prometheus"
57+
container_name: "my_chess_style_prom"
58+
env_file:
59+
- .env
60+
command:
61+
- "--config.file=/etc/prometheus/prometheus.yml"
62+
ports:
63+
- 9090:9090
64+
restart: unless-stopped
65+
volumes:
66+
- ./observability/prometheus:/etc/prometheus
67+
- prom_data:/prometheus
68+
69+
grafana:
70+
image: "grafana/grafana"
71+
container_name: "my_chess_style_graf"
72+
env_file:
73+
- .env
74+
ports:
75+
- 3000:3000
76+
restart: unless-stopped
77+
environment:
78+
- GF_SECURITY_ADMIN_USER=${GRAFANA_DEFAULT_USER}
79+
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_DEFAULT_PASS}
80+
volumes:
81+
- ./observability/grafana:/etc/grafana/provisioning/datasources
82+
83+
pg_explorer:
84+
image: "prometheuscommunity/postgres-exporter"
85+
container_name: "my_chess_style_pg_explorer"
86+
env_file:
87+
- .env
88+
ports:
89+
- 9187:9187
90+
depends_on:
91+
pg_server:
92+
condition: service_healthy
93+
prometheus:
94+
condition: service_started
95+
restart: unless-stopped
8696

8797
django-web-frontend:
8898
build:
8999
context: .
90100
dockerfile: Dockerfile.frontend
91101
container_name: my_chess_style_django_web_frontend
92102
ports:
93-
- "3000:8080"
103+
- "3000:80"
104+
depends_on:
105+
django-web-backend:
106+
condition: service_healthy
94107
healthcheck:
95-
test:
96-
[
97-
"CMD",
98-
"wget",
99-
"--no-verbose",
100-
"--tries=1",
101-
"--spider",
102-
"http://localhost:8080/",
103-
]
108+
test: ["CMD", "curl", "-f", "http://localhost/"]
104109
interval: 30s
105110
timeout: 3s
106111
retries: 3
@@ -115,9 +120,12 @@ services:
115120
ports:
116121
- "8000:8000"
117122
depends_on:
118-
- pg_server
119-
- cache
120-
- rabbitmq_server
123+
pg_server:
124+
condition: service_healthy
125+
cache:
126+
condition: service_healthy
127+
rabbitmq_server:
128+
condition: service_healthy
121129
env_file:
122130
- .env
123131
develop:
@@ -133,10 +141,14 @@ services:
133141
image: my-chess-style-base
134142
container_name: my_chess_style_celery_worker
135143
depends_on:
136-
- django-web-backend
137-
- pg_server
138-
- cache
139-
- rabbitmq_server
144+
django-web-backend:
145+
condition: service_healthy
146+
pg_server:
147+
condition: service_healthy
148+
cache:
149+
condition: service_started
150+
rabbitmq_server:
151+
condition: service_healthy
140152
env_file:
141153
- .env
142154
command: sh celery_entry.sh
@@ -146,13 +158,12 @@ services:
146158
- "80:80"
147159
- "443:443"
148160
volumes:
149-
- ./nginx.conf:/etc/nginx/nginx.conf:ro
150-
- static_files:/var/www/static:ro
151-
- media_files:/var/www/media:ro
152-
- ./ssl:/etc/nginx/ssl:ro # If using SSL
161+
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
153162
depends_on:
154-
- django-web-backend
155-
- django-web-frontend
163+
django-web-backend:
164+
condition: service_healthy
165+
django-web-frontend:
166+
condition: service_healthy
156167

157168
networks:
158169
default:

nginx/default.conf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
upstream gunicorn {
2+
# docker will automatically resolve this to the correct address
3+
# because we use the same name as the service: "web"
4+
server django-web-backend:8000;
5+
}
6+
server {
7+
listen 80;
8+
server_name localhost;
9+
root /usr/share/nginx/html;
10+
index index.html index.htm;
11+
location ^~ /server/ {
12+
rewrite ^/server/(.*) /api/v1/$1 break;
13+
proxy_pass http://gunicorn;
14+
error_page 405 =200 $uri;
15+
}
16+
location / {
17+
try_files $uri $uri/ /index.html;
18+
}
19+
}

web_entry.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ python manage.py makemigrations --noinput
66
python manage.py migrate --noinput
77
python manage.py import_chess_openings
88

9-
exec python manage.py runserver 0.0.0.0:8000
9+
# exec python manage.py runserver 0.0.0.0:8000
10+
exec gunicorn my_chess_style.wsgi -b 0.0.0.0:8000

0 commit comments

Comments
 (0)