diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1b6419e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,19 @@ +FROM nginx:alpine + +# Remove default nginx static assets +RUN rm -rf /usr/share/nginx/html/* + +# Copy Custom NAS 3D CAD Viewer & Static Assets +COPY ./viewer /usr/share/nginx/html/viewer +COPY ./data /usr/share/nginx/html/data +COPY ./mechanical /usr/share/nginx/html/mechanical +COPY ./bom /usr/share/nginx/html/bom + +# Copy default landing redirect +RUN echo '
' > /usr/share/nginx/html/index.html + +# Copy optimized nginx configuration +COPY ./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..5158aa5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,57 @@ +services: + web: + image: ${REG:-acr.atyg.org}/library/custom-nas-web:latest + build: + context: . + dockerfile: Dockerfile + restart: unless-stopped + env_file: stack.env + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik-net" + - "traefik.http.routers.custom-nas.rule=Host(`${SYSTEM_DOMAIN:-nas.atyg.org}`)" + - "traefik.http.routers.custom-nas.entrypoints=websecure" + - "traefik.http.routers.custom-nas.tls=true" + - "traefik.http.services.custom-nas.loadbalancer.server.port=80" + expose: + - "80" + depends_on: + - db + networks: + - default + - traefik-net + volumes: + - ./viewer:/usr/share/nginx/html/viewer:ro + - ./data:/usr/share/nginx/html/data:ro + - ./mechanical:/usr/share/nginx/html/mechanical:ro + - ./bom:/usr/share/nginx/html/bom:ro + - spire-socket:/var/run/spire:ro + + db: + image: ${REG:-acr.atyg.org}/library/postgres:18-alpine + restart: unless-stopped + environment: + - POSTGRES_USER=${POSTGRES_USER:-nasadmin} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB:-custom_nas} + volumes: + - db-data:/var/lib/postgresql/data + networks: + - default + +volumes: + db-data: + driver: local + driver_opts: + type: none + device: ${DB_DATA_PATH:-/var/data/custom-nas/db} + o: bind + spire-socket: + name: spire-socket + external: true + +networks: + default: + name: custom-nas-net + traefik-net: + external: true diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..f69d358 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,27 @@ +server { + listen 80; + server_name _; + + root /usr/share/nginx/html; + index index.html /viewer/index.html; + + # Enable gzip compression for CAD models, netlists & JSON catalogs + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml; + + location / { + try_files $uri $uri/ /viewer/index.html; + } + + # Cache static CAD assets and JSON catalogs + location ~* \.(json|dxf|scad|csv|stl|obj)$ { + expires 1d; + add_header Cache-Control "public, no-transform"; + add_header Access-Control-Allow-Origin "*"; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/stack.env.example b/stack.env.example new file mode 100644 index 0000000..a83dab3 --- /dev/null +++ b/stack.env.example @@ -0,0 +1,9 @@ +# System & Domain Configuration +SYSTEM_DOMAIN=nas.atyg.org +REG=acr.atyg.org + +# Database Configuration +POSTGRES_USER=nasadmin +POSTGRES_PASSWORD=generate_secure_random_password_here +POSTGRES_DB=custom_nas +DB_DATA_PATH=/var/data/custom-nas/db