feat: fullstack dockerization
This commit is contained in:
parent
094a16a768
commit
b19520eb6e
@ -17,5 +17,4 @@ FRONTEND_URL=""
|
||||
|
||||
# Frontend
|
||||
VITE_VIEW_COOKIE_PATH="/"
|
||||
VITE_VIEW_COOKIE_DOMAIN=$DOMAIN
|
||||
VITE_COKOIE_SAME_SITE="strict"
|
||||
|
@ -40,7 +40,7 @@ services:
|
||||
LOG_LEVEL: debug
|
||||
APP_ENV: development
|
||||
DOMAIN: localhost
|
||||
FRONTEND_URL: http://localhost
|
||||
FRONTEND_URL: http://localhost:5173
|
||||
|
||||
networks:
|
||||
notatest:
|
||||
|
@ -38,18 +38,25 @@ services:
|
||||
LOG_LEVEL: ${LOG_LEVEL:-info}
|
||||
APP_ENV: ${APP_ENV:-production}
|
||||
DOMAIN: ${DOMAIN:-localhost}
|
||||
FRONTEND_URL: ${FRONTEND_URL:-http://localhost:5173}
|
||||
FRONTEND_URL: ${FRONTEND_URL:-http://localhost:3000}
|
||||
|
||||
notatest-web:
|
||||
build: ${PWD}/web
|
||||
image: notatest/web
|
||||
container_name: notatest-web
|
||||
build:
|
||||
context: ${PWD}/web
|
||||
dockerfile: ${PWD}/web/Dockerfile
|
||||
image: notatest-web:latest
|
||||
networks:
|
||||
- notatest
|
||||
# Add potential reverse proxy's local network here
|
||||
ports:
|
||||
- 3000:80 # Defined in nginx.conf
|
||||
- 3000:80 # Container port defined in nginx.conf (bound to 3000 for dev.)
|
||||
depends_on:
|
||||
- notatest-server
|
||||
environment:
|
||||
VITE_VIEW_COOKIE_PATH: ${VITE_VIEW_COOKIE_PATH:-/}
|
||||
VITE_VIEW_COOKIE_DOMAIN: ${DOMAIN:-localhost}
|
||||
VITE_COOKIE_SAME_SITE: ${VITE_COOKIE_SAME_SITE:-strict}
|
||||
|
||||
networks:
|
||||
notatest:
|
||||
|
10
scripts/run_full_dev.sh
Executable file
10
scripts/run_full_dev.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
DEV_COMPOSE_FILE="docker-compose.yml"
|
||||
|
||||
[ "$( docker container inspect -f '{{.State.Status}}' notatest-psql )" = "running" ] || docker compose up notatest-psql -d
|
||||
|
||||
# Shutdown, rebuild, & restart
|
||||
docker compose stop notatest-server notatest-web && docker compose rm -f notatest-server notatest-web
|
||||
docker compose -f $DEV_COMPOSE_FILE build
|
||||
docker compose -f $DEV_COMPOSE_FILE up notatest-server notatest-web
|
19
web/Dockerfile
Normal file
19
web/Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
# Build stage
|
||||
FROM node:23.11-alpine3.20 AS builder
|
||||
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Final stage (optimized image size + NGINX)
|
||||
FROM nginx:alpine
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/build /usr/share/nginx/html
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
@ -1,15 +1,48 @@
|
||||
server {
|
||||
listen 80; # TLS termination is handled by Traefik
|
||||
|
||||
location / {
|
||||
listen 80;
|
||||
root /usr/share/nginx/html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# TLS termination should be handled by a reverse proxy (e.g. Traefik)
|
||||
|
||||
# General security headers
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
|
||||
# Block access to dotfiles
|
||||
location ~ /\.(?!well-known) {
|
||||
deny all;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
# Enable gzip compression for all assets
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
|
||||
|
||||
location /api {
|
||||
proxy_pass http://notatest-server:8080; # Internal Docker DNS
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# Cache static assets
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, no-transform";
|
||||
}
|
||||
}
|
||||
|
||||
# Route 404 errors to front page
|
||||
error_page 404 /;
|
||||
}
|
11
web/package-lock.json
generated
11
web/package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^4.0.0",
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
@ -830,6 +831,16 @@
|
||||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/adapter-static": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.8.tgz",
|
||||
"integrity": "sha512-YaDrquRpZwfcXbnlDsSrBQNCChVOT9MGuSg+dMAyfsAa1SmiAhrA5jUYUiIMC59G92kIbY/AaQOWcBdq+lh+zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@sveltejs/kit": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@sveltejs/kit": {
|
||||
"version": "2.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.20.7.tgz",
|
||||
|
@ -15,6 +15,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^4.0.0",
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
"@sveltejs/kit": "^2.16.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
|
@ -1,6 +1,5 @@
|
||||
// TODO: this can be set to always be "/api" after Dockerization as the backend requests
|
||||
// will automatically be proxied to the correct destination
|
||||
export const API_BASE_ADDR = import.meta.env.PROD ? "/api" : "http://localhost:8080/api"
|
||||
// export const API_BASE_ADDR = import.meta.env.PROD ? "/api" : "http://localhost:8080/api"
|
||||
export const API_BASE_ADDR = "/api"
|
||||
|
||||
// Lifetimes of *in-memory* authentication tokens in milliseconds
|
||||
export const AT_EXP_MS = 15 * 60 * 1000 // 15 min.
|
||||
|
2
web/src/routes/+layout.server.ts
Normal file
2
web/src/routes/+layout.server.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export const ssr = false
|
||||
export const prerender = false
|
@ -1,18 +1,21 @@
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
import adapter from "@sveltejs/adapter-static"
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://svelte.dev/docs/kit/integrations
|
||||
// for more information about preprocessors
|
||||
preprocess: vitePreprocess(),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
||||
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
||||
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
||||
adapter: adapter()
|
||||
adapter: adapter({
|
||||
pages: "build",
|
||||
assets: "build",
|
||||
fallback: "index.html",
|
||||
precompress: false
|
||||
})
|
||||
},
|
||||
ssr: false,
|
||||
prerender: {
|
||||
entries: []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
@ -1,5 +1,5 @@
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { sveltekit } from "@sveltejs/kit/vite"
|
||||
import tailwindcss from "@tailwindcss/vite"
|
||||
import { defineConfig } from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
|
Loading…
x
Reference in New Issue
Block a user