From ec064db204af44920666ae62e28e9be778d2b8d7 Mon Sep 17 00:00:00 2001 From: ordinarthur <@arthurbarre.js@gmail.com> Date: Sat, 11 Apr 2026 11:52:08 +0200 Subject: [PATCH] feat: add Dockerfile, nginx config and K8s manifests --- .dockerignore | 6 ++++++ Dockerfile | 25 +++++++++++++++++++++++++ k8s/deployment.yml | 43 +++++++++++++++++++++++++++++++++++++++++++ k8s/ingress.yml | 35 +++++++++++++++++++++++++++++++++++ k8s/namespace.yml | 4 ++++ k8s/service.yml | 14 ++++++++++++++ nginx.conf | 22 ++++++++++++++++++++++ 7 files changed, 149 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 k8s/deployment.yml create mode 100644 k8s/ingress.yml create mode 100644 k8s/namespace.yml create mode 100644 k8s/service.yml create mode 100644 nginx.conf diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..a5e6005 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +dist +.git +.astro +.DS_Store +.claude diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..7377dd6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +# --- Stage 1: Build --- +FROM node:22-alpine AS build +WORKDIR /app + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +# Install dependencies first (cache layer) +COPY package.json pnpm-lock.yaml ./ +RUN pnpm install --frozen-lockfile + +# Copy source and build +COPY . . +RUN pnpm build + +# --- Stage 2: Serve --- +FROM nginx:alpine AS runtime + +# Custom nginx config +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Copy built static files +COPY --from=build /app/dist /usr/share/nginx/html + +EXPOSE 80 diff --git a/k8s/deployment.yml b/k8s/deployment.yml new file mode 100644 index 0000000..b3749a7 --- /dev/null +++ b/k8s/deployment.yml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: aurelie-portfolio + namespace: portfolio + labels: + app: aurelie-portfolio +spec: + replicas: 2 + selector: + matchLabels: + app: aurelie-portfolio + template: + metadata: + labels: + app: aurelie-portfolio + spec: + containers: + - name: aurelie-portfolio + image: git.arthurbarre.fr/ordinarthur/aurelie-portfolio:latest + ports: + - containerPort: 80 + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "128Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 5 + periodSeconds: 30 + readinessProbe: + httpGet: + path: / + port: 80 + initialDelaySeconds: 3 + periodSeconds: 10 + imagePullSecrets: + - name: gitea-registry-secret diff --git a/k8s/ingress.yml b/k8s/ingress.yml new file mode 100644 index 0000000..21c9b5a --- /dev/null +++ b/k8s/ingress.yml @@ -0,0 +1,35 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: aurelie-portfolio + namespace: portfolio + annotations: + traefik.ingress.kubernetes.io/router.entrypoints: websecure + traefik.ingress.kubernetes.io/router.tls: "true" + traefik.ingress.kubernetes.io/router.tls.certresolver: letsencrypt +spec: + rules: + - host: aureliebarre.fr + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: aurelie-portfolio + port: + number: 80 + - host: www.aureliebarre.fr + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: aurelie-portfolio + port: + number: 80 + tls: + - hosts: + - aureliebarre.fr + - www.aureliebarre.fr diff --git a/k8s/namespace.yml b/k8s/namespace.yml new file mode 100644 index 0000000..fbc590d --- /dev/null +++ b/k8s/namespace.yml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: portfolio diff --git a/k8s/service.yml b/k8s/service.yml new file mode 100644 index 0000000..2308286 --- /dev/null +++ b/k8s/service.yml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: aurelie-portfolio + namespace: portfolio +spec: + type: NodePort + selector: + app: aurelie-portfolio + ports: + - port: 80 + targetPort: 80 + nodePort: 30081 + protocol: TCP diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..cae151d --- /dev/null +++ b/nginx.conf @@ -0,0 +1,22 @@ +server { + listen 80; + server_name _; + root /usr/share/nginx/html; + index index.html; + + # Cache static assets + location ~* \.(jpg|jpeg|png|gif|ico|svg|css|js|woff2?)$ { + expires 30d; + add_header Cache-Control "public, immutable"; + } + + # Astro clean URLs fallback + location / { + try_files $uri $uri/ $uri.html /index.html; + } + + # Gzip + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml image/svg+xml; + gzip_min_length 256; +}