Docker 설정 파일 구조 개선 및 .vite 폴더 추적 제거
- .dockerignore 및 docker-compose.yml을 docker/ 디렉토리로 이동 - Makefile의 docker-compose 명령어 경로 업데이트 - .vite/ 폴더를 git 추적에서 제거 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
14
docker/.dockerignore
Normal file
14
docker/.dockerignore
Normal file
@@ -0,0 +1,14 @@
|
||||
node_modules
|
||||
npm-debug.log
|
||||
dist
|
||||
.git
|
||||
.gitignore
|
||||
README.md
|
||||
.env
|
||||
.env.local
|
||||
.env.development
|
||||
.env.production
|
||||
.DS_Store
|
||||
coverage
|
||||
.nyc_output
|
||||
*.log
|
||||
50
docker/.htaccess
Normal file
50
docker/.htaccess
Normal file
@@ -0,0 +1,50 @@
|
||||
# Enable rewrite engine
|
||||
RewriteEngine On
|
||||
|
||||
# Redirect all traffic to HTTPS in production (uncomment if needed)
|
||||
# RewriteCond %{HTTPS} off
|
||||
# RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
# React Router - Redirect all requests to index.html
|
||||
# Don't rewrite files or directories
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-l
|
||||
RewriteRule . /index.html [L]
|
||||
|
||||
# Prevent direct access to .env files
|
||||
<Files .env*>
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# Security headers (if mod_headers is enabled)
|
||||
<IfModule mod_headers.c>
|
||||
# Cache static assets for 1 year
|
||||
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|svg|woff|woff2|ttf|otf)$">
|
||||
Header set Cache-Control "max-age=31536000, public, immutable"
|
||||
</FilesMatch>
|
||||
|
||||
# Cache HTML files for 10 minutes
|
||||
<FilesMatch "\.(html|htm)$">
|
||||
Header set Cache-Control "max-age=600, must-revalidate"
|
||||
</FilesMatch>
|
||||
</IfModule>
|
||||
|
||||
# Compression (if mod_deflate is enabled)
|
||||
<IfModule mod_deflate.c>
|
||||
AddOutputFilterByType DEFLATE text/plain
|
||||
AddOutputFilterByType DEFLATE text/html
|
||||
AddOutputFilterByType DEFLATE text/xml
|
||||
AddOutputFilterByType DEFLATE text/css
|
||||
AddOutputFilterByType DEFLATE application/xml
|
||||
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE application/rss+xml
|
||||
AddOutputFilterByType DEFLATE application/javascript
|
||||
AddOutputFilterByType DEFLATE application/x-javascript
|
||||
AddOutputFilterByType DEFLATE application/json
|
||||
AddOutputFilterByType DEFLATE image/svg+xml
|
||||
</IfModule>
|
||||
|
||||
# Error pages (customize as needed)
|
||||
# ErrorDocument 404 /index.html
|
||||
# ErrorDocument 500 /index.html
|
||||
53
docker/Dockerfile
Normal file
53
docker/Dockerfile
Normal file
@@ -0,0 +1,53 @@
|
||||
# Multi-stage build for React Vite application
|
||||
# Multi-platform support for AMD64 and ARM64
|
||||
FROM --platform=$BUILDPLATFORM node:20-alpine3.18 AS builder
|
||||
|
||||
# Install git (required for pnpm)
|
||||
RUN apk add --no-cache git
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
# Install pnpm directly without corepack
|
||||
RUN npm install -g pnpm@latest
|
||||
|
||||
# Copy package files
|
||||
COPY package.json pnpm-lock.yaml ./
|
||||
|
||||
# Install dependencies using pnpm
|
||||
RUN pnpm install --frozen-lockfile
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Build the application
|
||||
RUN pnpm run build
|
||||
|
||||
# Production stage with Apache
|
||||
FROM httpd:2.4-alpine AS production
|
||||
|
||||
# Install necessary packages
|
||||
RUN apk add --no-cache bash
|
||||
|
||||
# Copy built application from builder stage
|
||||
COPY --from=builder /app/dist /usr/local/apache2/htdocs/
|
||||
|
||||
# Copy Apache configuration
|
||||
COPY docker/apache.conf /usr/local/apache2/conf/httpd.conf
|
||||
|
||||
# Copy .htaccess file for URL rewriting
|
||||
COPY docker/.htaccess /usr/local/apache2/htdocs/.htaccess
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/entrypoint.sh
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Health check
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
|
||||
|
||||
# Start Apache using entrypoint script
|
||||
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
|
||||
35
docker/Dockerfile.dev
Normal file
35
docker/Dockerfile.dev
Normal file
@@ -0,0 +1,35 @@
|
||||
# Development Dockerfile for hot reloading
|
||||
# Multi-platform support for AMD64 and ARM64
|
||||
FROM --platform=$TARGETPLATFORM node:18-alpine
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /app
|
||||
|
||||
RUN corepack enable
|
||||
|
||||
# Copy package files
|
||||
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
|
||||
|
||||
RUN \
|
||||
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
|
||||
elif [ -f package-lock.json ]; then npm ci; \
|
||||
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i --frozen-lockfile; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
# Install all dependencies (including dev dependencies)
|
||||
RUN \
|
||||
if [ -f yarn.lock ]; then yarn run build; \
|
||||
elif [ -f package-lock.json ]; then npm run build; \
|
||||
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm run build; \
|
||||
else echo "Lockfile not found." && exit 1; \
|
||||
fi
|
||||
|
||||
# Copy source code
|
||||
COPY . .
|
||||
|
||||
# Expose development port
|
||||
EXPOSE 5173
|
||||
|
||||
# Start development server
|
||||
CMD ["pnpm", "run", "dev"]
|
||||
145
docker/apache.conf
Normal file
145
docker/apache.conf
Normal file
@@ -0,0 +1,145 @@
|
||||
# Apache httpd v2.4 minimal configuration
|
||||
ServerRoot "/usr/local/apache2"
|
||||
|
||||
# Server-wide configuration
|
||||
ServerAdmin admin@localhost
|
||||
ServerName localhost
|
||||
|
||||
# Listen on port 80
|
||||
Listen 80
|
||||
|
||||
# Load necessary modules
|
||||
LoadModule mpm_event_module modules/mod_mpm_event.so
|
||||
LoadModule authn_core_module modules/mod_authn_core.so
|
||||
LoadModule authz_core_module modules/mod_authz_core.so
|
||||
LoadModule authz_host_module modules/mod_authz_host.so
|
||||
LoadModule mime_module modules/mod_mime.so
|
||||
LoadModule log_config_module modules/mod_log_config.so
|
||||
LoadModule env_module modules/mod_env.so
|
||||
LoadModule headers_module modules/mod_headers.so
|
||||
LoadModule setenvif_module modules/mod_setenvif.so
|
||||
LoadModule version_module modules/mod_version.so
|
||||
LoadModule unixd_module modules/mod_unixd.so
|
||||
LoadModule status_module modules/mod_status.so
|
||||
LoadModule autoindex_module modules/mod_autoindex.so
|
||||
LoadModule dir_module modules/mod_dir.so
|
||||
LoadModule alias_module modules/mod_alias.so
|
||||
LoadModule rewrite_module modules/mod_rewrite.so
|
||||
LoadModule deflate_module modules/mod_deflate.so
|
||||
LoadModule filter_module modules/mod_filter.so
|
||||
|
||||
# User and group
|
||||
<IfModule unixd_module>
|
||||
User daemon
|
||||
Group daemon
|
||||
</IfModule>
|
||||
|
||||
# Document root
|
||||
DocumentRoot "/usr/local/apache2/htdocs"
|
||||
<Directory "/usr/local/apache2/htdocs">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
|
||||
# Enable URL rewriting for React Router
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-l
|
||||
RewriteRule . /index.html [L]
|
||||
</Directory>
|
||||
|
||||
# Directory indexes
|
||||
<IfModule dir_module>
|
||||
DirectoryIndex index.html index.htm
|
||||
</IfModule>
|
||||
|
||||
# Prevent .htaccess and .htpasswd files from being viewed
|
||||
<Files ".ht*">
|
||||
Require all denied
|
||||
</Files>
|
||||
|
||||
# Error log
|
||||
ErrorLog /proc/self/fd/2
|
||||
LogLevel warn
|
||||
|
||||
# Access log
|
||||
<IfModule log_config_module>
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
|
||||
LogFormat "%h %l %u %t \"%r\" %>s %b" common
|
||||
CustomLog /proc/self/fd/1 common
|
||||
</IfModule>
|
||||
|
||||
# MIME types
|
||||
<IfModule mime_module>
|
||||
TypesConfig conf/mime.types
|
||||
AddType application/javascript .js .mjs
|
||||
AddType application/json .json
|
||||
AddType text/css .css
|
||||
AddType text/html .html .htm
|
||||
AddType image/svg+xml .svg
|
||||
AddType image/x-icon .ico
|
||||
AddType font/woff .woff
|
||||
AddType font/woff2 .woff2
|
||||
AddType font/ttf .ttf
|
||||
AddType font/otf .otf
|
||||
AddEncoding gzip svgz
|
||||
</IfModule>
|
||||
|
||||
# Enable compression for text-based files
|
||||
<IfModule deflate_module>
|
||||
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css
|
||||
AddOutputFilterByType DEFLATE application/javascript application/json
|
||||
AddOutputFilterByType DEFLATE application/xml application/xhtml+xml
|
||||
AddOutputFilterByType DEFLATE application/rss+xml
|
||||
AddOutputFilterByType DEFLATE image/svg+xml
|
||||
AddOutputFilterByType DEFLATE font/ttf font/otf font/woff font/woff2
|
||||
|
||||
# Don't compress already compressed formats
|
||||
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|zip|gz|tgz|bz2|rar|7z)$ no-gzip dont-vary
|
||||
|
||||
# Make sure proxies don't deliver the wrong content
|
||||
Header append Vary Accept-Encoding env=!dont-vary
|
||||
</IfModule>
|
||||
|
||||
# Security headers
|
||||
<IfModule headers_module>
|
||||
# Prevent clickjacking
|
||||
Header always set X-Frame-Options "SAMEORIGIN"
|
||||
|
||||
# Prevent XSS attacks
|
||||
Header always set X-XSS-Protection "1; mode=block"
|
||||
|
||||
# Prevent MIME sniffing
|
||||
Header always set X-Content-Type-Options "nosniff"
|
||||
|
||||
# Referrer policy
|
||||
Header always set Referrer-Policy "no-referrer-when-downgrade"
|
||||
|
||||
# Content Security Policy
|
||||
Header always set Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'"
|
||||
|
||||
# Remove server signature
|
||||
Header always unset Server
|
||||
Header always unset X-Powered-By
|
||||
</IfModule>
|
||||
|
||||
# Cache control for static assets
|
||||
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|otf)$">
|
||||
Header set Cache-Control "max-age=31536000, public, immutable"
|
||||
</FilesMatch>
|
||||
|
||||
# Disable server signature
|
||||
ServerTokens Prod
|
||||
ServerSignature Off
|
||||
|
||||
# Health check endpoint
|
||||
<Location "/health">
|
||||
SetHandler server-status
|
||||
Require all granted
|
||||
</Location>
|
||||
|
||||
# Include additional configuration files
|
||||
# Removed IncludeOptional to prevent recursive inclusion
|
||||
# IncludeOptional conf/*.conf
|
||||
56
docker/docker-compose.yml
Normal file
56
docker/docker-compose.yml
Normal file
@@ -0,0 +1,56 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile
|
||||
platforms:
|
||||
- "linux/amd64"
|
||||
- "linux/arm64"
|
||||
platform: linux/amd64
|
||||
image: nice-app-web:latest
|
||||
container_name: nice-app-web
|
||||
ports:
|
||||
- "3000:80"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.web.rule=Host(`localhost`)"
|
||||
- "traefik.http.services.web.loadbalancer.server.port=80"
|
||||
|
||||
# Development service (optional)
|
||||
web-dev:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: docker/Dockerfile.dev
|
||||
platforms:
|
||||
- "linux/amd64"
|
||||
- "linux/arm64"
|
||||
platform: linux/amd64
|
||||
container_name: nice-app-web-dev
|
||||
ports:
|
||||
- "5173:5173"
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/node_modules
|
||||
environment:
|
||||
- NODE_ENV=development
|
||||
command: npm run dev
|
||||
profiles:
|
||||
- dev
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
node_modules:
|
||||
14
docker/entrypoint.sh
Normal file
14
docker/entrypoint.sh
Normal file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Replace environment variables in JavaScript files if needed
|
||||
# This is useful for runtime configuration in Docker containers
|
||||
|
||||
# Example: Replace API_URL placeholder with actual environment variable
|
||||
# if [ ! -z "$API_URL" ]; then
|
||||
# find /usr/local/apache2/htdocs -name '*.js' -exec sed -i "s|VITE_API_URL_PLACEHOLDER|$API_URL|g" {} +
|
||||
# fi
|
||||
|
||||
# Start Apache in foreground
|
||||
echo "Starting Apache HTTP Server..."
|
||||
exec httpd-foreground
|
||||
Reference in New Issue
Block a user