Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions client/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Dependencies
node_modules
npm-debug.log
yarn-error.log
yarn.lock

# Build output
dist
build
.vercel

# Environment variables
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# IDE
.vscode
.idea
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Git
.git
.gitignore
.gitattributes

# Testing
coverage
.nyc_output

# Misc
*.log
.vercelignore
README.md
53 changes: 53 additions & 0 deletions client/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Multi-stage Dockerfile for React + Vite Frontend

# Development Stage
FROM node:20-alpine AS development

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy source code
COPY . .

# Expose Vite dev server port
EXPOSE 5173

# Start development server
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]

# Build Stage
FROM node:20-alpine AS build

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy source code
COPY . .

# Build the application
RUN npm run build

# Production Stage
FROM nginx:alpine AS production

# Copy custom nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

# Copy built assets from build stage
COPY --from=build /app/dist /usr/share/nginx/html

# Expose port 80
EXPOSE 80

# Start nginx
CMD ["nginx", "-g", "daemon off;"]
22 changes: 22 additions & 0 deletions client/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
services:
client:
build:
context: .
dockerfile: Dockerfile
target: development
container_name: code-a2z-client
ports:
- '5173:5173'
env_file:
- .env
volumes:
- ./src:/app/src
- ./public:/app/public
- /app/node_modules
restart: unless-stopped
networks:
- code-a2z-network

networks:
code-a2z-network:
driver: bridge
40 changes: 40 additions & 0 deletions client/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 10240;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json;
gzip_disable "MSIE [1-6]\.";

# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Handle React Router
location / {
try_files $uri $uri/ /index.html;
}

# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

# Disable caching for index.html
location = /index.html {
add_header Cache-Control "no-cache, no-store, must-revalidate";
expires 0;
}

# Error pages
error_page 404 /index.html;
}
7 changes: 6 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"preview": "vite preview",
"docker:up": "docker-compose up -d",
"docker:down": "docker-compose down",
"docker:logs": "docker-compose logs -f",
"docker:build": "docker-compose build",
"docker:restart": "docker-compose restart"
},
"dependencies": {
"@editorjs/attaches": "^1.3.2",
Expand Down
98 changes: 98 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
services:
client:
build:
context: ./client
dockerfile: Dockerfile
target: development
container_name: code-a2z-client
ports:
- '5173:5173'
env_file:
- ./client/.env
volumes:
- ./client/src:/app/src
- ./client/public:/app/public
- client_node_modules:/app/node_modules
depends_on:
- server
restart: unless-stopped
networks:
- code-a2z-network

server:
build:
context: ./server
dockerfile: Dockerfile
target: development
container_name: code-a2z-server
ports:
- '8000:8000'
depends_on:
mongo:
condition: service_healthy
env_file:
- ./server/.env
environment:
- MONGODB_URL=mongodb://mongo:27017/code-a2z
- VITE_CLIENT_DOMAIN=http://localhost:5173
volumes:
- ./server/src:/app/src
- ./server/logs:/app/logs
restart: unless-stopped
healthcheck:
test:
[
'CMD',
'wget',
'--no-verbose',
'--tries=1',
'--spider',
'http://localhost:8000/monitor/health',
]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- code-a2z-network

mongo:
image: mongo:8-noble
container_name: code-a2z-mongo
ports:
- '27017:27017'
volumes:
- mongo-data:/data/db
restart: unless-stopped
healthcheck:
test: ['CMD', 'mongosh', '--eval', "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
networks:
- code-a2z-network

mongo-express:
image: mongo-express:latest
container_name: code-a2z-mongo-express
ports:
- '8081:8081'
environment:
- ME_CONFIG_MONGODB_URL=mongodb://mongo:27017
- ME_CONFIG_BASICAUTH_USERNAME=${MONGO_EXPRESS_USER:-admin}
- ME_CONFIG_BASICAUTH_PASSWORD=${MONGO_EXPRESS_PASSWORD:-changeme}
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
depends_on:
- mongo
restart: unless-stopped
networks:
- code-a2z-network

volumes:
mongo-data:
client_node_modules:

networks:
code-a2z-network:
driver: bridge
Loading
Loading