diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a8bc5b0 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +dist +.git +.gitignore +.env.local +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.DS_Store +*.md +.vscode +.idea \ No newline at end of file diff --git a/.env b/.env index 5dea892..d1bc400 100644 --- a/.env +++ b/.env @@ -1 +1,11 @@ -VITE_API_URL=https://simple-travel.felixits.uz/api/v1/ \ No newline at end of file +# API Configuration +VITE_API_URL=https://simple-travel.felixits.uz/api/v1/ +VITE_API_TIMEOUT=30000 + +# App Configuration +VITE_APP_NAME=simple-travel-admin +VITE_APP_VERSION=1.0.0 + +# Environment +NODE_ENV=production + diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..d1bc400 --- /dev/null +++ b/.env.production @@ -0,0 +1,11 @@ +# API Configuration +VITE_API_URL=https://simple-travel.felixits.uz/api/v1/ +VITE_API_TIMEOUT=30000 + +# App Configuration +VITE_APP_NAME=simple-travel-admin +VITE_APP_VERSION=1.0.0 + +# Environment +NODE_ENV=production + diff --git a/Dockerfile b/Dockerfile index f08a1a5..26ad7d6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,20 @@ -FROM node:20-alpine AS builder -WORKDIR /app -COPY package*.json ./ -RUN npm install --legacy-peer-deps -COPY . . -RUN npm run build - +# Build stage FROM node:20-alpine + WORKDIR /app -COPY --from=builder /app/dist ./dist -RUN npm install -g serve -EXPOSE 3000 -CMD ["serve", "-s", "dist"] + +# Copy dependencies +COPY package.json package-lock.json* ./ + +RUN npm ci --legacy-peer-deps + +# Copy all source +COPY . . + +# Set production env (agar .env.production bo‘lsa ishlaydi) +ENV NODE_ENV=production + +# Build for production +RUN npm run build +ENTRYPOINT npm run preview + diff --git a/docker-compose.yml b/docker-compose.yml index cd2aad4..f9c4cb5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,20 @@ -version: "3.9" - services: - frontend: - image: muhammadvadud/simple-travel-front-admin:latest - build: . + simple-travel-admin: + build: + context: . + dockerfile: Dockerfile + args: + - VITE_API_URL=${VITE_API_URL} + - VITE_APP_NAME=${VITE_APP_NAME} + container_name: simple-travel-admin ports: - - "5263:3000" - deploy: - replicas: 2 - restart_policy: - condition: on-failure + - "5263:4173" + env_file: + - .env.production + restart: unless-stopped + networks: + - network + +networks: + network: + driver: bridge diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000..5fe68ed --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,33 @@ +server { + listen 80; + server_name localhost; + root /usr/share/nginx/html; + index index.html; + + # Gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json; + + # 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; + + # React Router support + 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"; + } + + # Don't cache index.html + location = /index.html { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + } +} \ No newline at end of file