diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..87d6665 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +node_modules +dist +.git +.gitignore +/.vscode +/.DS_Store +pnpm-lock.yaml +npm-debug.log +Dockerfile +docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a581c51 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +# Build stage +FROM node:20-alpine AS builder +WORKDIR /app + +# Install build dependencies and pnpm (via corepack) +RUN apk add --no-cache python3 make g++ && \ + corepack enable && corepack prepare pnpm@latest --activate + +# Copy package manifests first for better caching +COPY package.json pnpm-lock.yaml ./ + +# Copy the rest of the project +COPY . . + +# Install deps and build +RUN pnpm install --frozen-lockfile +RUN pnpm build + +# Production image +FROM nginx:stable-alpine +COPY --from=builder /app/dist /usr/share/nginx/html + +# Add custom nginx config for SPA routing +COPY docker/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 + +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4534558 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,22 @@ +version: '3.8' +services: + web: + build: . + image: campaign-web:latest + ports: + - "5173:80" + environment: + - NODE_ENV=production + restart: unless-stopped + + dev: + image: node:20 + working_dir: /app + volumes: + - ./:/app:cached + - /app/node_modules + command: sh -c "corepack enable && corepack prepare pnpm@latest --activate && pnpm install && pnpm dev --host 0.0.0.0" + ports: + - "5173:5173" + environment: + - CHOKIDAR_USEPOLLING=true diff --git a/docker/nginx.conf b/docker/nginx.conf new file mode 100644 index 0000000..0a07f34 --- /dev/null +++ b/docker/nginx.conf @@ -0,0 +1,18 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html; + + location / { + try_files $uri $uri/ /index.html; + } + + # Optional: cache static assets + location ~* \.(?:js|css|png|jpg|jpeg|gif|ico|svg)$ { + try_files $uri =404; + expires 30d; + add_header Cache-Control "public, max-age=2592000, immutable"; + } +}