diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..027a87a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +node_modules +npm-debug.log +.git +.gitignore +README.md +.env +.env.* +.nyc_output +coverage +.vscode +.DS_Store +dist \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a66b656 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +# Multi-stage build for production +FROM node:20-alpine AS build-stage + +# Set working directory +WORKDIR /app + +# Copy package files +COPY package*.json ./ + +# Install dependencies +#ENV NODE_ENV=production +RUN npm ci --no-audit --no-fund + +# Copy source code +COPY . . + +# Build the app +RUN npm run build + +# Production stage +FROM nginx:stable-alpine AS production-stage + +# Copy built assets from build stage +COPY --from=build-stage /app/dist /usr/share/nginx/html + +# Copy custom nginx config +COPY nginx.conf /etc/nginx/nginx.conf + +# Expose port 80 +EXPOSE 80 + +# Start nginx +HEALTHCHECK --interval=30s --timeout=3s --retries=3 CMD wget -qO- http://localhost/healthz >/dev/null 2>&1 || exit 1 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..e6e5c8a --- /dev/null +++ b/nginx.conf @@ -0,0 +1,49 @@ +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + etag on; + gzip on; + gzip_comp_level 5; + gzip_min_length 1024; + gzip_types + text/plain text/css application/json application/javascript + text/xml application/xml application/xml+rss image/svg+xml; + + server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "DENY" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always; + + # Handle client-side routing + location / { + try_files $uri $uri/ /index.html; + } + + location = /index.html { + add_header Cache-Contrl "no-store, no-cache, must-revalidate"; + expires -1; + } + + # Cache static assets + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { + expires 1y; + add_header Cache-Control "public, immutable"; + } + + location = healthz { + default_type text/plain; + return 200 'ok'; + } + } +} \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico index df36fcf..6ecd0e4 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/src/assets/logo.png b/src/assets/logo.png deleted file mode 100644 index f3d2503..0000000 Binary files a/src/assets/logo.png and /dev/null differ diff --git a/src/components/UserLogin.vue b/src/components/UserLogin.vue index 4fc12c8..e2b2573 100644 --- a/src/components/UserLogin.vue +++ b/src/components/UserLogin.vue @@ -113,7 +113,7 @@
Don't have an account? Sign up
+Don't have an account?