diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..aa277b6 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +node_modules +dist +.git +.github +ios +resources +.superpowers +*.log diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..3ffe269 --- /dev/null +++ b/Caddyfile @@ -0,0 +1,15 @@ +:80 { + root * /srv + encode gzip zstd + + # The service worker and entry HTML must never be cached, so PWA updates land. + @nocache path /sw.js / /index.html /manifest.webmanifest + header @nocache Cache-Control "no-cache" + + # Hashed build assets and icons are content-addressed → cache forever. + @immutable path /assets/* /icons/* + header @immutable Cache-Control "public, max-age=31536000, immutable" + + try_files {path} /index.html + file_server +} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6813f6b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# Build the PWA, then serve the static bundle with Caddy. +# TLS is terminated at your edge (Cloudflare tunnel / reverse proxy), so the +# container serves plain HTTP on :80. + +# ---- build ---- +FROM node:20-alpine AS build +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci +COPY . . +RUN npm run build + +# ---- serve ---- +FROM caddy:2-alpine +COPY Caddyfile /etc/caddy/Caddyfile +COPY --from=build /app/dist /srv +EXPOSE 80 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3263636 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +services: + director: + build: . + image: the-director:latest + container_name: the-director + restart: unless-stopped + ports: + # host:container — point your director.timevans.uk route at host port 8087 + - "8087:80"