From 6144c288557b5daa7022cb5da5cf9347bc15a427 Mon Sep 17 00:00:00 2001 From: bartool Date: Sat, 29 Nov 2025 20:56:06 +0100 Subject: [PATCH] docker setup --- backand/Dockerfile | 2 +- docker-compose.yml | 22 ++++++++ frontend/.dockerignore | 111 +++++++++++++++++++++++++++++++++++++++++ frontend/Dockerfile | 47 +++++++++++++++++ frontend/nginx.conf | 70 ++++++++++++++++++++++++++ 5 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 docker-compose.yml create mode 100644 frontend/.dockerignore create mode 100644 frontend/Dockerfile create mode 100644 frontend/nginx.conf diff --git a/backand/Dockerfile b/backand/Dockerfile index 39fc5b3..fb83523 100644 --- a/backand/Dockerfile +++ b/backand/Dockerfile @@ -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"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f1e4fb3 --- /dev/null +++ b/docker-compose.yml @@ -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 diff --git a/frontend/.dockerignore b/frontend/.dockerignore new file mode 100644 index 0000000..a4ac556 --- /dev/null +++ b/frontend/.dockerignore @@ -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 diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..9f36b64 --- /dev/null +++ b/frontend/Dockerfile @@ -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;"] \ No newline at end of file diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..290c104 --- /dev/null +++ b/frontend/nginx.conf @@ -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; + } +} \ No newline at end of file