From 120e25d50dde53f30f7bf739bca39a81e891fb1a Mon Sep 17 00:00:00 2001 From: chiko Date: Fri, 9 Oct 2026 00:38:17 +0200 Subject: [PATCH] Dockerized --- .dockerignore | 9 +++++++++ Dockerfile | 38 ++++++++++++++++++++++++++++++++++++++ README.md | 21 +++++++++++++++++++++ compose.yaml | 18 ++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 compose.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..497f243 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +node_modules +dist +data +.git +.env +.env.* +!.env.example +coverage +*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1b293f6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +FROM node:22-bookworm-slim AS build + +WORKDIR /app + +# better-sqlite3 has a native module; compile it for this Node/Debian image. +RUN apt-get update \ + && apt-get install -y --no-install-recommends python3 make g++ \ + && rm -rf /var/lib/apt/lists/* + +COPY package.json package-lock.json ./ +RUN npm ci + +COPY tsconfig.json ./ +COPY src ./src +RUN npm run build && npm prune --omit=dev + +FROM node:22-bookworm-slim AS runtime + +ENV NODE_ENV=production \ + PORT=3000 \ + DB_PATH=/app/data/events.sqlite + +WORKDIR /app + +COPY --from=build --chown=node:node /app/package.json ./package.json +COPY --from=build --chown=node:node /app/node_modules ./node_modules +COPY --from=build --chown=node:node /app/dist ./dist + +RUN mkdir -p /app/data && chown node:node /app/data +VOLUME ["/app/data"] + +USER node +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ + CMD node -e "fetch('http://127.0.0.1:' + (process.env.PORT || 3000) + '/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))" + +CMD ["node", "dist/index.js"] diff --git a/README.md b/README.md index ead594c..92a7208 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,27 @@ A `.env` file is optional at startup; without one, the server still runs, but no For production, run `npm run build` followed by `npm start`, and keep the process running with your preferred process manager or service host. +## Docker + +Build and start the service with Docker Compose: + +```sh +Copy-Item .env.example .env +# Edit .env and configure Apprise, ntfy, and Discord settings. +docker compose up -d --build +``` + +The service listens on port `3000`; set `HOST_PORT` in the shell or Compose `.env` file to change the host port. SQLite data is stored in the persistent `event-data` Docker volume. Follow logs with `docker compose logs -f`, stop with `docker compose down`, and remove the database volume only when you intend to delete the stored events and notification history (`docker compose down -v`). + +To build and run without Compose: + +```sh +docker build -t 77th-ev-cal-ntfy-srv . +docker run -d --name 77th-ev-cal-ntfy-srv --restart unless-stopped \ + --env-file .env -p 3000:3000 -v event-data:/app/data \ + 77th-ev-cal-ntfy-srv +``` + ## Endpoints - `GET /health` — service and polling status diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..ff2bbb8 --- /dev/null +++ b/compose.yaml @@ -0,0 +1,18 @@ +services: + calendar-service: + build: . + container_name: 77th-ev-cal-ntfy-srv + restart: unless-stopped + env_file: + - path: .env + required: false + environment: + PORT: 3000 + DB_PATH: /app/data/events.sqlite + ports: + - "${HOST_PORT:-3000}:3000" + volumes: + - event-data:/app/data + +volumes: + event-data: