diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..92e9362d8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,32 @@ +/node_modules/ +/tmp/ +/build/ +/coverage/ +/.coverage/ +/.eslintcache +/.env +/deploy.sh +/.vs/ +yarn-error.log* +/junit.xml + +/static/ +/static-test/ +/public/ +/dist/ + +.idea +.DS_Store + +# Custom build files +/custom/**/* +!/custom/* +/custom/*.* +!/custom/.gitkeep +!/custom/**/.gitkeep + +# surge.sh +/CNAME +/AUTH +/CORS +/ROUTER diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..f93c5fdbe --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:18 as build +WORKDIR /app +COPY package.json . +COPY yarn.lock . +RUN yarn +COPY . . +ARG NODE_ENV=production +RUN yarn build + +FROM nginx:stable-alpine +COPY installation/docker.conf /etc/nginx/conf.d/default.conf +COPY --from=build /app/static /usr/share/nginx/html diff --git a/installation/docker.conf b/installation/docker.conf new file mode 100644 index 000000000..cdd5699ae --- /dev/null +++ b/installation/docker.conf @@ -0,0 +1,43 @@ +# Soapbox Nginx for Docker. +server { + keepalive_timeout 70; + sendfile on; + client_max_body_size 80m; + + root /usr/share/nginx/html; + + gzip on; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml image/x-icon; + + add_header Strict-Transport-Security "max-age=31536000" always; + + # SPA. + # Try static files, then fall back to index.html. + location / { + try_files $uri /index.html; + } + + # Build files. + # New builds produce hashed filenames, so these should be cached heavily. + location /packs { + add_header Cache-Control "public, max-age=31536000, immutable"; + add_header Strict-Transport-Security "max-age=31536000" always; + } + + # Return 404 on API routes so Soapbox knows what to do. + location /api { + add_header Content-Type "application/json"; + return 404 '{"error": "Not implemented"}'; + } + + # ServiceWorker: don't cache. + location = /sw.js { + add_header Cache-Control "public, max-age=0"; + add_header Strict-Transport-Security "max-age=31536000" always; + } +}