docker setup

This commit is contained in:
2025-11-29 20:56:06 +01:00
parent 43ef1bc376
commit 6144c28855
5 changed files with 251 additions and 1 deletions

View File

@@ -46,7 +46,7 @@ COPY --chown=appuser:appuser . .
USER appuser
# Expose Django port
EXPOSE 8000
EXPOSE 7080
# Run Django with uvicorn
CMD ["uvicorn", "MPM:application", "--host", "0.0.0.0", "--port", "7080"]

22
docker-compose.yml Normal file
View File

@@ -0,0 +1,22 @@
services:
backend:
container_name: mayo-production-manager-backend
build:
context: ./backend
dockerfile: Dockerfile
environment:
NODE_ENV: production
ports:
- 7090:7090
restart: unless-stopped
frontend:
container_name: mayo-production-manager-frontend
build:
context: ./frontend
dockerfile: Dockerfile
environment:
NODE_ENV: production
ports:
- 7080:7080
restart: unless-stopped

111
frontend/.dockerignore Normal file
View File

@@ -0,0 +1,111 @@
# -------------------------------
# Dependency directories
# -------------------------------
node_modules/
# -------------------------------
# Production and build outputs
# -------------------------------
dist/
out/
build/
public/build/
# -------------------------------
# Vite, VuePress, and cache dirs
# -------------------------------
.vite/
.vitepress/
.cache/
.tmp/
# -------------------------------
# Test output and coverage
# -------------------------------
coverage/
reports/
jest/
cypress/
cypress/screenshots/
cypress/videos/
# -------------------------------
# Environment and config files
# -------------------------------
_.env_
!.env.production # Keep production env if needed
_.local
_.log
# -------------------------------
# TypeScript artifacts
# -------------------------------
\*.tsbuildinfo
# -------------------------------
# Editor and IDE config
# -------------------------------
.vscode/
.idea/
\*.swp
# -------------------------------
# System files
# -------------------------------
.DS_Store
Thumbs.db
# -------------------------------
# Lockfiles (optional)
# -------------------------------
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# -------------------------------
# Git files
# -------------------------------
.git/
.gitignore
# -------------------------------
# Docker-related files
# -------------------------------
Dockerfile
.dockerignore
docker-compose.yml
docker-compose.override.yml

47
frontend/Dockerfile Normal file
View File

@@ -0,0 +1,47 @@
# =========================================
# Stage 1: Build the Vue.js Application
# =========================================
ARG NODE_VERSION=22.17.1-alpine
ARG NGINX_VERSION=alpine3.22
# Use a lightweight Node.js image for building (customizable via ARG)
FROM node:${NODE_VERSION} AS builder
# Set the working directory inside the container
WORKDIR /app
# Copy package-related files first to leverage Docker's caching mechanism
COPY package.json package-lock.json ./
# Install project dependencies using npm ci (ensures a clean, reproducible install)
RUN --mount=type=cache,target=/root/.npm npm ci
# Copy the rest of the application source code into the container
COPY . .
# Build the Vue.js application
RUN npm run build
# =========================================
# Stage 2: Prepare Nginx to Serve Static Files
# =========================================
FROM nginxinc/nginx-unprivileged:${NGINX_VERSION} AS runner
# Use a built-in non-root user for security best practices
USER nginx
# Copy custom Nginx config
COPY nginx.conf /etc/nginx/nginx.conf
# Copy the static build output from the build stage to Nginx's default HTML serving directory
COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html
# Expose port 8080 to allow HTTP traffic
# Note: The default NGINX container now listens on port 8080 instead of 80
EXPOSE 7080
# Start Nginx directly with custom config
ENTRYPOINT ["nginx", "-c", "/etc/nginx/nginx.conf"]
CMD ["-g", "daemon off;"]

70
frontend/nginx.conf Normal file
View File

@@ -0,0 +1,70 @@
worker_processes auto;
pid /tmp/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
charset utf-8;
access_log off;
error_log /dev/stderr warn;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
gzip on;
gzip_comp_level 6;
gzip_proxied any;
gzip_min_length 256;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
server {
listen 7080;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location /mayo-manager/ {
try_files $uri $uri/ /index.html;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png|woff2?|eot|ttf|svg|map)$ {
expires 1y;
access_log off;
add_header Cache-Control "public, immutable";
add_header X-Content-Type-Options nosniff;
}
# location /assets/ {
# expires 1y;
# add_header Cache-Control "public, immutable";
# add_header X-Content-Type-Options nosniff;
# }
# BACKEND API
location /mayo-manager/api/ {
proxy_pass http://mayo-production-manager-backend:7090/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# DJANGO ADMIN
location /mayo-manager/admin/ {
proxy_pass http://mayo-production-manager-backend:7090/admin/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 404 /index.html;
}
}