Add Docker image, example compose file and Gitea build workflow
- Dockerfile: node:24-alpine, production deps only, runs as the node user, healthcheck on /healthz. No volume, because the server keeps no state. - docker-compose.yml: example for the VPS. It publishes no ports, since Docker's port publishing bypasses ufw and would skip NPM's IP access list. It joins NPM's network instead. - .gitea/workflows/docker.yml: on v*-prod* tags, builds on the self-hosted runner and pushes v0idf1sh/sdp-dashboard:<tag> and :latest using the DHUB_UNAME and DHUB_PASS secrets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b6ef6a195c
commit
c2cf725819
12
.dockerignore
Normal file
12
.dockerignore
Normal file
@ -0,0 +1,12 @@
|
||||
.git
|
||||
.gitea
|
||||
.vscode
|
||||
node_modules
|
||||
npm-debug.log*
|
||||
.env
|
||||
.env.*
|
||||
docs
|
||||
images
|
||||
*.md
|
||||
Dockerfile
|
||||
docker-compose*.yml
|
||||
43
.gitea/workflows/docker.yml
Normal file
43
.gitea/workflows/docker.yml
Normal file
@ -0,0 +1,43 @@
|
||||
# Builds the image and pushes it to Docker Hub when a production tag (e.g. v1.1.0-prod1) is pushed.
|
||||
# Restarting the container on the VPS is done by hand for now.
|
||||
name: Build and push image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*-prod*'
|
||||
|
||||
env:
|
||||
IMAGE: v0idf1sh/sdp-dashboard
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Check out
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
env:
|
||||
DHUB_UNAME: ${{ secrets.DHUB_UNAME }}
|
||||
DHUB_PASS: ${{ secrets.DHUB_PASS }}
|
||||
run: echo "$DHUB_PASS" | docker login --username "$DHUB_UNAME" --password-stdin
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
docker build \
|
||||
--pull \
|
||||
--label "org.opencontainers.image.version=${{ gitea.ref_name }}" \
|
||||
--label "org.opencontainers.image.revision=${{ gitea.sha }}" \
|
||||
-t "$IMAGE:${{ gitea.ref_name }}" \
|
||||
-t "$IMAGE:latest" \
|
||||
.
|
||||
|
||||
- name: Push
|
||||
run: |
|
||||
docker push "$IMAGE:${{ gitea.ref_name }}"
|
||||
docker push "$IMAGE:latest"
|
||||
|
||||
- name: Log out
|
||||
if: always()
|
||||
run: docker logout
|
||||
19
Dockerfile
Normal file
19
Dockerfile
Normal file
@ -0,0 +1,19 @@
|
||||
FROM node:24-alpine
|
||||
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
|
||||
# install dependencies first so code-only changes reuse this layer
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --omit=dev && npm cache clean --force
|
||||
|
||||
COPY src ./src
|
||||
|
||||
# no volume: sessions live in each user's browser, so the container keeps no state
|
||||
USER node
|
||||
EXPOSE 3000
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1:3000/healthz || exit 1
|
||||
|
||||
CMD ["node", "src/server.js"]
|
||||
25
docker-compose.yml
Normal file
25
docker-compose.yml
Normal file
@ -0,0 +1,25 @@
|
||||
# Example compose file for the VPS. Copy src/env.example to .env next to this file and fill it in.
|
||||
# Nginx Proxy Manager forwards the subdomain to sdp-dashboard:3000 and enforces the IP allow list.
|
||||
|
||||
services:
|
||||
sdp-dashboard:
|
||||
image: v0idf1sh/sdp-dashboard:latest
|
||||
container_name: sdp-dashboard
|
||||
restart: unless-stopped
|
||||
env_file: .env
|
||||
environment:
|
||||
# must match the redirect URI registered in the Zoho API console, minus /auth/callback
|
||||
PUBLIC_URL: https://dashboard.example.com
|
||||
# No published ports on purpose. Docker's port publishing bypasses ufw, so "3000:3000" would
|
||||
# let anyone reach the app directly and skip NPM's access list. NPM reaches it over the
|
||||
# shared network instead, using the container name as the forward hostname.
|
||||
expose:
|
||||
- "3000"
|
||||
networks:
|
||||
- proxy
|
||||
|
||||
networks:
|
||||
proxy:
|
||||
# the network Nginx Proxy Manager's container is on; check with `docker network ls`
|
||||
external: true
|
||||
name: ${NPM_NETWORK:-npm_default}
|
||||
Loading…
Reference in New Issue
Block a user