diff --git a/Dockerfile b/Dockerfile index 95b3371..de2552b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,74 +1,13 @@ -# Build stage -FROM node:20-alpine as build +FROM node:20 as builder WORKDIR /app - -# Copy package files -COPY package.json package-lock.json ./ - -# Install dependencies +COPY package*.json ./ RUN npm install - -# Copy source code COPY . . - -# Build the application RUN npm run build -# Production stage FROM nginx:alpine - -# Install necessary tools -RUN apk add --no-cache curl - -# Create nginx configuration -RUN echo 'server { \ - listen 80; \ - server_name localhost; \ - root /usr/share/nginx/html; \ - index index.html; \ - \ - # Gzip compression \ - gzip on; \ - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; \ - \ - # Security headers \ - add_header X-Frame-Options "SAMEORIGIN"; \ - add_header X-XSS-Protection "1; mode=block"; \ - add_header X-Content-Type-Options "nosniff"; \ - \ - # Trust proxy headers \ - real_ip_header X-Forwarded-For; \ - set_real_ip_from 0.0.0.0/0; \ - \ - # Handle proxy headers \ - proxy_set_header Host $host; \ - proxy_set_header X-Real-IP $remote_addr; \ - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; \ - proxy_set_header X-Forwarded-Proto $scheme; \ - \ - location / { \ - try_files $uri $uri/ /index.html; \ - } \ - \ - # Cache static assets \ - location /assets/ { \ - expires 1y; \ - add_header Cache-Control "public, no-transform"; \ - } \ - \ - # Error pages \ - error_page 404 /index.html; \ - error_page 500 502 503 504 /50x.html; \ - location = /50x.html { \ - root /usr/share/nginx/html; \ - } \ -}' > /etc/nginx/conf.d/default.conf - -# Copy built assets from build stage -COPY --from=build /app/dist /usr/share/nginx/html - -# Expose port 80 +COPY --from=builder /app/dist /usr/share/nginx/html +COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 - -CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx.conf b/nginx.conf index 6b97987..fad7c7b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,29 +1,85 @@ server { listen 80; - server_name localhost; - root /usr/share/nginx/html; - index index.html; + server_name ebook.miduway.space; + + # Редирект всех HTTP-запросов на HTTPS + return 301 https://$host$request_uri; +} - # Gzip compression - gzip on; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; +server { + listen 443 ssl; + server_name ebook.miduway.space; - # Security headers - add_header X-Frame-Options "SAMEORIGIN"; - add_header X-XSS-Protection "1; mode=block"; - add_header X-Content-Type-Options "nosniff"; + # SSL-сертификаты + ssl_certificate /etc/letsencrypt/live/ebook.miduway.space/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/ebook.miduway.space/privkey.pem; + + # Настройки SSL + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + # Проксирование к Docker-контейнеру location / { + proxy_pass http://localhost:80; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + # Настройки для Vue.js try_files $uri $uri/ /index.html; + add_header Cache-Control "no-cache, no-store, must-revalidate"; } - # Cache static assets - location /assets/ { + # Кэширование статических файлов Vue + location /js/ { + proxy_pass http://localhost:80; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + + # Настройки кэширования для JS файлов expires 1y; - add_header Cache-Control "public, no-transform"; + add_header Cache-Control "public, immutable"; } - # Error pages + location /css/ { + proxy_pass http://localhost:80; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + + # Настройки кэширования для CSS файлов + expires 1y; + add_header Cache-Control "public, immutable"; + } + + location /img/ { + proxy_pass http://localhost:80; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + + # Настройки кэширования для изображений + expires 1y; + add_header Cache-Control "public, immutable"; + } + + # Блокировка доступа к скрытым файлам + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + # Обработка ошибок для Vue.js error_page 404 /index.html; error_page 500 502 503 504 /50x.html; location = /50x.html { diff --git a/vite.config.ts b/vite.config.ts index 7a320a4..e5c0d5e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,15 @@ -import { defineConfig } from "vite"; -import vue from "@vitejs/plugin-vue"; -import tailwindcss from "@tailwindcss/vite"; +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import tailwindcss from '@tailwindcss/vite' -// https://vite.dev/config/ export default defineConfig({ plugins: [vue(), tailwindcss()], -}); + build: { + outDir: '../www/ebook.miduway.space/dist', // Output to Nginx served directory + emptyOutDir: true, + }, + server: { + host: '0.0.0.0', // Allow Docker container access + port: 4002, + }, +})