Compare commits

...
Author SHA1 Message Date
gorkem-bwl 0b09895098 docs: align dev setup docs with current server config
## Changes
- Replace stale QUEUE_TYPE env var (superSimpleQueue/lessSimpleQueue) with QUEUE_MODE (primary/worker) to match server/src/config/envValidation.ts
- Mark ORIGIN, TOKEN_TTL and LOG_LEVEL as optional with their defaults; note that only CLIENT_HOST, JWT_SECRET and DB_CONNECTION_STRING are strictly required
- Note that CLIENT_HOST must be a full URL (enforced by env validation)
- Remove Redis port 6379 from the port-conflict troubleshooting list; the server has no Redis dependency
- Point CLAUDE.md at CONTRIBUTING.md as the setup source of truth

## Why
A contributor followed the setup docs and hit references to files and env vars that no longer exist after the repo reorg. This brings the contributor docs in line with the actual dev workflow.
2026-07-21 19:44:22 +03:00
Alexander Holliday bf255a0178 Merge pull request #3793 from bluewave-labs/chore/refactor-routes
chore: convert router classes to exported functions
2026-07-20 11:30:41 -07:00
Alex Holliday 36434c1160 convert router classes to exported functions 2026-07-20 11:25:39 -07:00
Alexander Holliday 63cecf3447 Merge pull request #3792 from bluewave-labs/chore/purge-team/groups
purge unused groups route, update tests
2026-07-20 10:26:45 -07:00
Alex Holliday 4d9e5821a8 purge unused groups route, update tests 2026-07-20 10:21:43 -07:00
Alexander Holliday 5433a0cf5f Merge pull request #3791 from bluewave-labs/chore/fix-access-modifier
chore: protected -> private as no class inherits
2026-07-20 10:06:08 -07:00
Alex Holliday d485adbb54 narrow mapDocument types 2026-07-20 10:04:55 -07:00
Alex Holliday 3eadb99c5e protected -> private as no class inherits 2026-07-20 10:01:48 -07:00
Alexander Holliday 9c04061a04 Merge pull request #3787 from jpomykala/develop
Add Polish language
2026-07-20 09:34:54 -07:00
Alexander Holliday 897ffd5736 Merge pull request #3788 from Osamaali313/fix/response-time-poor-label
Fix missing "Poor" label on the average response-time gauge
2026-07-20 09:34:16 -07:00
Osamaali313 368595178d Fix missing "Poor" label on the average response-time gauge
`RadialAvgResponse` maps the response-time palette to a qualitative word:

    const palette = getResponseTimeColor(avg);
    const msg: Record<string, string> = {
        success: "Excellent",
        warning: "Average",
        danger: "Poor",
    };
    ...
    {msg[palette]}

But `getResponseTimeColor` only ever returns `"success" | "warning" | "error"`
(MonitorUtils.ts) — never `"danger"`. So for the slow case `palette` is
`"error"`, `msg["error"]` is `undefined`, and no label renders. The same
component uses `theme.palette[palette].main`, which works precisely because
`palette` is the real MUI key `"error"`; every other palette helper in
MonitorUtils.ts also uses `"error"`, and `"danger"` appears nowhere else in
the client. Any monitor whose average response time is >= 300 ms shows an
empty label exactly where the "Poor" signal matters most. Use the `error`
key.
2026-07-18 23:36:43 +03:00
Jakub Pomykała 924c862244 Format pl.json 2026-07-18 22:13:05 +02:00
Jakub Pomykała cf451416b1 Update polish translations after review 2026-07-18 21:33:10 +02:00
Jakub Pomykała 6e2a64fc9f Add Polish to language selector 2026-07-18 20:57:50 +02:00
Jakub Pomykała 0e52cb6231 Add polish 2026-07-18 20:22:00 +02:00
Alexander Holliday 507b96164f Merge pull request #3784 from bluewave-labs/chore/refactor-utils
chore: refactor utils
2026-07-15 10:24:51 -07:00
Alex Holliday 887521c376 Merge branch 'develop' into chore/refactor-utils 2026-07-15 10:24:23 -07:00
Alexander Holliday caee9510eb Merge pull request #3783 from bluewave-labs/chore/controller-refactor
chore: add catchAsync to handle errors, remove all try/catch blocks from con…
2026-07-15 10:23:48 -07:00
Alex Holliday 825a81d326 extract shared mongo mapper utils 2026-07-15 10:20:16 -07:00
Alex Holliday bd13e9d9c8 add catchAsync to handle errors, remove all try/catch blocks from contorllers 2026-07-15 10:02:36 -07:00
Alexander Holliday 92696d3685 Merge pull request #3782 from bluewave-labs/chore/hardware-aggregation-refactor
chore: hardware aggregation refactor
2026-07-15 09:59:03 -07:00
Alex Holliday 5120390923 aggregation->aggregations 2026-07-15 09:23:16 -07:00
Alex Holliday 0810fcbb88 refactor hardware aggregation pipeline 2026-07-15 09:18:35 -07:00
Alexander Holliday 15453c2d8d Merge pull request #3781 from bluewave-labs/chore/monitor-service-refactor
chore: remove duplicated code
2026-07-14 10:48:53 -07:00
Alex Holliday 70f10a73d8 remove duplicated code 2026-07-14 10:46:25 -07:00
Alexander Holliday 930c06f5ff Merge pull request #3780 from bluewave-labs/chore/dedupe
chore: remove toEntityWithChecks
2026-07-14 10:37:14 -07:00
Alex Holliday b088a8c878 remove toEntityWithChecks 2026-07-14 10:17:38 -07:00
Alexander Holliday 067a186765 Merge pull request #3779 from bluewave-labs/fix/cascade-incidents
fix: delete incidents on all monitors deleted
2026-07-14 09:26:13 -07:00
Alex Holliday 107b5cbd96 delete incidents on all monitors deleted 2026-07-14 09:24:14 -07:00
Alexander Holliday 7fdd51c072 Merge pull request #3778 from edobusy/fix/readme-k8s-install-link
fix(docs): correct K8s install link path in translated READMEs
2026-07-14 09:10:10 -07:00
Alexander Holliday 2331035da0 Merge pull request #3773 from bluewave-labs/fix/status-page-brand-color-not-applied
fix(status page): apply brand color via a dedicated brand token
2026-07-14 09:04:06 -07:00
edobusy fd4edb7227 fix(docs): correct K8s install link path in translated READMEs
The translated READMEs in docs/translations/ link to the Kubernetes
installation guide with a path copied from the root README
(./charts/helm/checkmate/INSTALLATION.md). Because these files live two
levels below the repo root, that path resolves to
docs/translations/charts/..., which does not exist, so the link is
broken in all 17 translations.

Fix the path to ../../charts/helm/checkmate/INSTALLATION.md so it
resolves to the repo-root charts/ directory. The root README.md is
correct as-is and is left unchanged.
2026-07-14 13:43:37 +10:00
Alexander Holliday 538b0df7e9 Merge pull request #3777 from bluewave-labs/fix/shield-csp
add img.shields.io to csp directive
2026-07-13 10:11:24 -07:00
Alex Holliday 9f79feec8e add img.shields.io to csp directive 2026-07-13 10:10:28 -07:00
Alexander Holliday fe703199f5 Merge pull request #3776 from bluewave-labs/chore/simplify-deployment
chore: simplify deployment
2026-07-13 09:57:13 -07:00
Alex Holliday 800080fd06 add log warnings about legacy env vars 2026-07-13 09:48:02 -07:00
Alex Holliday c1bcd9b206 add note to helm chart about migration 2026-07-13 09:47:45 -07:00
Alex Holliday 5d55750b7b update docs 2026-07-13 09:38:55 -07:00
Alexander Holliday 4f398e98d3 Merge pull request #3774 from bluewave-labs/feat/italian-translation-and-contrib-docs
feat(i18n): add Italian translation, document translation workflow
2026-07-13 09:05:01 -07:00
gorkem-bwl 242e853bf0 i18n(it): review pass — fix grammar, awkward phrasing, inconsistencies
91 leaves refined after a native-Italian style pass.

## Categories of fixes

- Grammar / gender agreement — e.g. `logs.table.headers.lastSeenAt`
  "Ultima visto il" → "Visto l'ultima volta"; heap gauge subject
  agreement in `logs.diagnostics.gauges.allocatedPercentage`.
- Awkward phrasing / calques — `notFound.subtitle` drops stilted
  "ad esso"; `incidents.fallback.title` "in salute" → "funzionano
  correttamente" (was reading as if for a person, not systems);
  `settings.form.removeMonitors.title` "Reset del sistema" →
  "Reimposta il sistema"; "con successo" → "correttamente" on
  status-page delete confirmations.
- Consistency — paused monitor status unified on "In pausa" across
  `common.labels.paused`, monitor status labels, status-bar keys, and
  the `bulkPause.*_one/other` copies. Button verbs
  "Sospendi"/"Riprendi" kept for brevity; status noun stays "In pausa".
- Mistranslations — `buttons.testNotifications` "Testa" → "Prova";
  `buttons.toggleTheme` "Cambia" → "Alterna"; Twilio "Auth token" now
  translated; Mongoose `readyState` clarified to "Stato di connessione".
- Register — trimmed "Ancora" from several empty-state titles so they
  read like natural Italian empty states.

## Verification

874 leaves in EN and IT, 0 missing / 0 extra, all placeholders and
inline tags preserved, no empty values.
2026-07-13 16:18:24 +03:00
gorkem-bwl 523bf2253c feat(i18n): add Italian translation, document translation workflow
## Changes

- Add `client/src/locales/it.json` — Italian translation of all 874 UI
  keys, structure mirrors `en.json` exactly. Placeholders (`{{value}}`,
  etc.) and inline tag tokens (`<settingsLink>`, `<highlight>`, ...)
  are preserved. Product/brand names, technical abbreviations, and
  placeholder-style examples (e.g. `you@example.com`) are kept in
  English. 116 leaves are intentionally kept verbatim in English
  (brand names, protocol names, sample values, port numbers, regex).
- Register `it: "Italiano"` in `LanguageSelector`'s `languageNames`
  map so the dropdown shows the localised name; the selector already
  picks up any locale present in the i18n resources.
- Fill in the two "How do I..." sections that CONTRIBUTING.md's table
  of contents already links to but did not have bodies:
  - "Improve the documentation?" — short guidance on doc PRs and
    keeping README translations in sync.
  - "Help with translations?" — describes the current per-language
    JSON workflow (source of truth: `en.json`; improve an existing
    language by editing its JSON; add a new one by adding a JSON file
    and registering the display name in `LanguageSelector`). Notes
    that the older PoEditor sync workflow is no longer authoritative.

## Benefits

- Italian speakers can now use Checkmate in Italian.
- Contributors who follow the "Help with translations?" link from
  the CONTRIBUTING TOC land on real, current guidance instead of a
  broken anchor.
- Translation quality can be improved incrementally by anyone
  editing `it.json` directly; no external tooling required.
2026-07-13 16:10:04 +03:00
Alex Holliday ceacaa5499 scope workflows 2026-07-09 11:24:35 -07:00
Alex Holliday 91343f996b hosting docs 2026-07-09 10:55:04 -07:00
Alex Holliday 312961e8c9 use repo owner 2026-07-09 10:27:56 -07:00
Alex Holliday 0475f194e9 temporary branch 2026-07-09 10:24:06 -07:00
Alex Holliday bbb051406f udpate docs 2026-07-09 10:21:09 -07:00
Alex Holliday 40a7599388 update workflows 2026-07-09 10:20:24 -07:00
Alex Holliday dffce2709e clean up docker files 2026-07-09 10:19:38 -07:00
Alex Holliday 62031a0ab1 add a CLIENT_CONFIG to the client, serve from BE with env vars 2026-07-09 09:49:45 -07:00
Alex Holliday ef175950b2 add dockerfile and build-image workflow 2026-07-09 09:29:31 -07:00
Alex Holliday 6d91efecad default client to same-origin /api/v1 and window.location.origin, drop UPTIME_APP_* placeholders 2026-07-08 11:04:47 -07:00
Alex Holliday f7d3bcb696 add root docker-compose 2026-07-08 10:47:03 -07:00
Alex Holliday 4a093e2b97 start health server on primary process true 2026-07-08 10:46:34 -07:00
182 changed files with 5695 additions and 5005 deletions

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
**/node_modules
**/dist
**/.env
**/*.env
.git
docker/dev/mongo/data
+103
View File
@@ -0,0 +1,103 @@
name: Build image
on:
push:
branches: ["develop", "master"]
tags: ["v*"]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# checkmate-backend-mono is a transitional alias so existing deployments
# keep receiving updates; drop it after one release cycle.
- name: Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/${{ github.repository_owner }}/checkmate
ghcr.io/${{ github.repository_owner }}/checkmate-backend-mono
flavor: |
latest=false
tags: |
type=ref,event=branch
type=ref,event=tag
type=semver,pattern={{version}}
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Build and push multi-arch image
uses: docker/build-push-action@v6
with:
context: .
file: ./docker/Dockerfile
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# The hosted staging/prod instances share one host and one compose file; each
# deploy pulls and recreates only its own service.
deploy-staging:
needs: build-and-push
if: github.ref == 'refs/heads/develop'
runs-on: ubuntu-latest
steps:
- name: Deploy staging.checkmate.so
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ secrets.DEMO_SERVER_HOST }}
username: ${{ secrets.DEMO_SERVER_USER }}
key: ${{ secrets.DEMO_SERVER_SSH_KEY }}
script: |
cd checkmate
git pull
cd docs/hosting/checkmate-so
docker compose pull checkmate-staging
docker compose up -d checkmate-staging
docker system prune -af
deploy-prod:
needs: build-and-push
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
steps:
- name: Deploy demo.checkmate.so
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ secrets.DEMO_SERVER_HOST }}
username: ${{ secrets.DEMO_SERVER_USER }}
key: ${{ secrets.DEMO_SERVER_SSH_KEY }}
script: |
cd checkmate
git pull
cd docs/hosting/checkmate-so
docker compose pull checkmate-demo
docker compose up -d checkmate-demo
docker system prune -af
@@ -1,148 +0,0 @@
name: Deploy images on release
on:
push:
tags:
- "v*"
workflow_dispatch:
jobs:
docker-build-and-push-client:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version from tag
id: extract_tag
run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Client Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-client:${{ steps.extract_tag.outputs.version }} \
-f ./docker/dist/client.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push Client Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-client:${{ steps.extract_tag.outputs.version }}
docker-build-and-push-server:
needs: docker-build-and-push-client
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Extract version
id: extract_tag
run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-backend:${{ steps.extract_tag.outputs.version }} \
-f ./docker/dist/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push Server Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-backend:${{ steps.extract_tag.outputs.version }}
- name: Build Mongo Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-mongo:${{ steps.extract_tag.outputs.version }} \
-f ./docker/dist/mongoDB.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push MongoDB Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-mongo:${{ steps.extract_tag.outputs.version }}
docker-build-and-push-server-mono-multiarch:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract version
id: extract_tag
run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push multi-arch Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/dist-arm/server.Dockerfile
push: true
no-cache: true
tags: |
ghcr.io/bluewave-labs/checkmate-backend-mono-multiarch:${{ steps.extract_tag.outputs.version }}
platforms: linux/amd64,linux/arm64
labels: |
org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate
build-args: |
VITE_APP_VERSION=${{ steps.extract_tag.outputs.version }}
docker-build-and-push-server-mono:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract version
id: extract_tag
run: echo "version=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-backend-mono:${{ steps.extract_tag.outputs.version }} \
-f ./docker/dist-mono/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
--build-arg VITE_APP_VERSION=${{ steps.extract_tag.outputs.version }} \
.
- name: Push Server Docker image
run: docker push ghcr.io/bluewave-labs/checkmate-backend-mono:${{ steps.extract_tag.outputs.version }}
-143
View File
@@ -1,143 +0,0 @@
name: Deploy images
on:
push:
branches: ["master"]
workflow_dispatch:
jobs:
docker-build-and-push-client:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: vars
run: echo "VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build Client Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-client:latest \
-f ./docker/dist/client.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
--build-arg VITE_APP_VERSION=${{ env.VERSION }} \
.
- name: Push Client Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-client:latest
docker-build-and-push-server:
needs: docker-build-and-push-client
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-backend:latest \
-f ./docker/dist/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push Server Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-backend:latest
- name: Build Mongo Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-mongo:latest \
-f ./docker/dist/mongoDB.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push MongoDB Docker image
run: |
docker push ghcr.io/bluewave-labs/checkmate-mongo:latest
docker-build-and-push-server-mono-multiarch:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: vars
run: echo "VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build and push multi-arch Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./docker/dist-arm/server.Dockerfile
push: true
no-cache: true
tags: |
ghcr.io/bluewave-labs/checkmate-backend-mono-multiarch:latest
platforms: linux/amd64,linux/arm64
labels: |
org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate
build-args: |
VITE_APP_VERSION=${{ env.VERSION }}
docker-build-and-push-server-mono:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: vars
run: echo "VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate-backend-mono:latest \
-f ./docker/dist-mono/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
--build-arg VITE_APP_VERSION=${{ env.VERSION }} \
.
- name: Push Server Docker image
run: docker push ghcr.io/bluewave-labs/checkmate-backend-mono:latest
-91
View File
@@ -1,91 +0,0 @@
name: Demo deploy
on:
push:
branches: [ "demo" ]
workflow_dispatch:
jobs:
docker-build-and-push-client:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: vars
run: echo "VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build Client Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:frontend-demo \
-f ./docker/prod/client.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
--build-arg VITE_APP_VERSION=${{ env.VERSION }} \
.
- name: Push Client Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:frontend-demo
docker-build-and-push-server:
needs: docker-build-and-push-client
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:backend-demo \
-f ./docker/prod/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push Server Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:backend-demo
- name: Build Mongo Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:mongo-demo \
-f ./docker/prod/mongoDB.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push MongoDB Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:mongo-demo
deploy-to-demo:
needs: docker-build-and-push-server
runs-on: ubuntu-latest
steps:
- name: SSH into server and restart container using Docker Compose
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ secrets.DEMO_SERVER_HOST }}
username: ${{ secrets.DEMO_SERVER_USER }}
key: ${{ secrets.DEMO_SERVER_SSH_KEY }}
script: |
cd checkmate
git pull
cd docker/unified
docker compose down
docker compose pull
docker compose up -d
docker system prune -af
-91
View File
@@ -1,91 +0,0 @@
name: Staging deploy
on:
push:
branches: [ "develop" ]
jobs:
docker-build-and-push-client:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: vars
run: echo "VERSION=$(git describe --tags --abbrev=0)" >> $GITHUB_ENV
- name: Build Client Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:frontend-staging \
-f ./docker/staging/client.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
--build-arg VITE_APP_VERSION=${{ env.VERSION }} \
.
- name: Push Client Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:frontend-staging
docker-build-and-push-server:
needs: docker-build-and-push-client
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build Server Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:backend-staging \
-f ./docker/staging/server.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push Server Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:backend-staging
- name: Build Mongo Docker image
run: |
docker build \
-t ghcr.io/bluewave-labs/checkmate:mongo-staging \
-f ./docker/staging/mongoDB.Dockerfile \
--label org.opencontainers.image.source=https://github.com/bluewave-labs/checkmate \
.
- name: Push MongoDB Docker image
run: docker push ghcr.io/bluewave-labs/checkmate:mongo-staging
deploy-to-staging:
needs: docker-build-and-push-server
runs-on: ubuntu-latest
steps:
- name: SSH into server and restart container using Docker Compose
uses: appleboy/ssh-action@v1.2.2
with:
host: ${{ secrets.DEMO_SERVER_HOST }}
username: ${{ secrets.DEMO_SERVER_USER }}
key: ${{ secrets.DEMO_SERVER_SSH_KEY }}
script: |
cd checkmate
git pull
cd docker/unified
docker compose down
docker compose pull
docker compose up -d
docker system prune -af
+4 -3
View File
@@ -35,9 +35,9 @@ npm run format # Prettier formatting
### Docker Development
```bash
cd docker/dev
./build_images.sh
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:6.0
docker build -f docker/Dockerfile -t checkmate . # build the mono image (server + built client)
docker compose -f docker/dev/docker-compose.yaml up # local full stack (builds image, runs mongo + worker)
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:8.0 # just a dev database
```
## Environment Setup
@@ -51,6 +51,7 @@ TOKEN_TTL="99d"
ORIGIN="localhost"
LOG_LEVEL="debug"
```
Only `CLIENT_HOST` (must be a full URL), `JWT_SECRET`, and `DB_CONNECTION_STRING` are strictly required; the rest have defaults (see `server/src/config/envValidation.ts`). Setup source of truth: CONTRIBUTING.md.
### Client `.env`
```env
+37 -30
View File
@@ -88,34 +88,10 @@ cd Checkmate
#### Step 2: Set Up Docker Containers (MongoDB)
Navigate to the Docker dev directory:
```bash
cd docker/dev
```
Build the Docker images:
Linux:
```bash
./build_images.sh
```
Windows:
```bash
./build_images.bat
```
Run MongoDB container:
```bash
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:6.0
```
Navigate back to the root directory:
```bash
cd ../..
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:8.0
```
#### Step 3: Set Up the Backend (Server)
@@ -148,10 +124,12 @@ LOG_LEVEL="debug"
- `CLIENT_HOST`: Frontend URL (default: http://localhost:5173)
- `JWT_SECRET`: Secret key for JWT tokens (change to something secure)
- `DB_CONNECTION_STRING`: MongoDB connection URL
- `ORIGIN`: Origin for CORS purposes
- `TOKEN_TTL`: Token time to live (in vercel/ms format)
- `LOG_LEVEL`: Debug level (debug, info, warn, error)
- `QUEUE_TYPE`: Job queue implementation (`superSimpleQueue` or `lessSimpleQueue`, optional, default: `superSimpleQueue`)
- `ORIGIN`: Origin for CORS purposes (optional)
- `TOKEN_TTL`: Token time to live in vercel/ms format (optional, default: `99d`)
- `LOG_LEVEL`: Debug level: debug, info, warn, error (optional, default: `debug`)
- `QUEUE_MODE`: Queue mode, `primary` or `worker` (optional, default: `primary`)
Only `CLIENT_HOST`, `JWT_SECRET`, and `DB_CONNECTION_STRING` are strictly required. Note that `CLIENT_HOST` must be a full URL.
Start the backend server:
@@ -227,7 +205,7 @@ docker rm uptime_database_mongo
**Port already in use:**
- Check if another service is using ports 5173, 52345, 27017, or 6379
- Check if another service is using ports 5173, 52345, or 27017
- Stop the conflicting service or change the port in `.env` files
**MongoDB connection issues:**
@@ -256,6 +234,35 @@ docker rm uptime_database_mongo
Start with [good first issues](https://github.com/bluewave-labs/checkmate/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
### Improve the documentation?
Documentation contributions are very welcome — fixing a typo, clarifying a step, or adding a missing example is a valuable PR.
- Small edits (typos, wording, formatting): open a PR directly against `develop`.
- Larger changes (restructuring a section, adding a new guide): open an issue first so we can align on scope, then a PR.
- Screenshots are helpful when documenting UI behaviour.
- README translations live in `docs/translations/`. If you're adding a new language, please also add a flag + link to the language bar in the root `README.md` and every existing translated README so they stay in sync.
### Help with translations?
The application uses `i18next` with one JSON file per language under `client/src/locales/` (`en.json` is the source of truth). English source strings are the definitive copy; other languages are generated as one-time machine translations that anyone is welcome to refine.
**To improve an existing language:**
1. Edit the relevant `client/src/locales/<code>.json` file directly.
2. Keep the JSON key structure identical to `en.json` — only translate the string values.
3. Open a PR against `develop`. No language-selector code changes are needed.
**To add a new language:**
1. Add `client/src/locales/<code>.json` with the same key structure as `en.json`, translated. If you can't translate every key, leave unfamiliar strings in English rather than removing keys — i18next falls back to the key path when a value is missing.
2. Add the display name to `languageNames` in `client/src/Components/inputs/LanguageSelector.tsx` (e.g. `it: "Italiano"`). The selector picks up any language present in `resources` automatically.
3. Open a PR against `develop`.
If translating a whole file is more than you want to take on, open an issue asking us to add the language and we'll generate an initial machine-translated file that you (or others) can refine over time.
**Note:** an older workflow that synced translations with PoEditor is still in the repo but no longer authoritative. Please treat the `.json` files in `client/src/locales/` as the source of truth.
### Submit a pull request?
Follow the [pull request checklist](#pull-request-checklist). Your PR should:
+31 -1
View File
@@ -80,7 +80,37 @@ Usage instructions can be found [here](https://checkmate.so/docs).
<a id="installation"></a>
## Installation
See installation instructions in [Checkmate documentation portal](https://checkmate.so/docs).
The quickest way to run Checkmate is the reference Docker Compose file, which runs the all-in-one image (`ghcr.io/bluewave-labs/checkmate`) plus MongoDB:
```bash
curl -O https://raw.githubusercontent.com/bluewave-labs/checkmate/master/docker/docker-compose.yaml
JWT_SECRET="$(openssl rand -hex 32)" docker compose up -d
```
Then open http://localhost:52345. If the app is reached at another origin (domain or LAN IP), set `CLIENT_HOST` accordingly. To build the image yourself, run `docker build -f docker/Dockerfile -t checkmate .` from a checkout. For TLS, put any reverse proxy (Caddy, Traefik, nginx) in front of port 52345.
### Configuration
The image is configured entirely through environment variables on the server container:
| Variable | Required | Description |
|---|---|---|
| `DB_CONNECTION_STRING` | Yes | MongoDB connection string, e.g. `mongodb://mongodb:27017/uptime_db` |
| `JWT_SECRET` | Yes | Secret used to sign auth tokens; generate one with `openssl rand -hex 32` |
| `CLIENT_HOST` | Yes | The URL users reach the app at, e.g. `https://checkmate.example.com`; used for CORS and for links in notifications and emails |
| `LOG_LEVEL` | No | Server log level: `error`, `warn`, `info`, or `debug` (default `debug`) |
The web client needs no configuration by default: it calls the API on the same origin it was served from (`/api/v1`). For setups where the defaults don't apply — for example, the API is reached through a different origin than the page — the server renders overrides into the client at runtime via these optional variables:
| Variable | Description |
|---|---|
| `CLIENT_CONFIG_API_BASE_URL` | Full base URL the client calls the API at, e.g. `https://api.example.com/api/v1`; defaults to same-origin `/api/v1` |
| `CLIENT_CONFIG_CLIENT_HOST` | Origin used when the client builds absolute links (invites, status pages); defaults to the browser's current origin |
| `CLIENT_CONFIG_LOG_LEVEL` | Browser console log level: `error`, `warn`, `info`, or `debug` (default `error`) |
> **Upgrading from an older image?** The `UPTIME_APP_*` variables (`UPTIME_APP_API_BASE_URL`, `UPTIME_APP_CLIENT_HOST`, `UPTIME_APP_LOG_LEVEL`) are no longer read. In most setups no replacement is needed — the same-origin defaults cover them; if you pointed the client at a different origin, use the `CLIENT_CONFIG_*` equivalents above. The `checkmate-client`, `checkmate-backend`, `checkmate-mongo`, and `checkmate-backend-mono-multiarch` images are no longer updated — switch to `ghcr.io/bluewave-labs/checkmate`, keeping your existing MongoDB service and data volume.
See full installation instructions in the [Checkmate documentation portal](https://checkmate.so/docs).
Alternatively, you can also use [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (South Africa), [Cloudzy](https://cloudzy.com/marketplace/checkmate) or [Pikapods](https://www.pikapods.com/) to quickly spin off a Checkmate instance. If you would like to monitor your server infrastructure, you'll need [Capture agent](https://github.com/bluewave-labs/capture). Capture repository also contains the installation instructions.
+4
View File
@@ -3,4 +3,8 @@ name: checkmate-chart
description: A Helm chart for Checkmate App
type: application
version: 0.2.0
# DO NOT bump appVersion past v3.8.1 until this chart is migrated to the all-in-one
# image (ghcr.io/bluewave-labs/checkmate). The checkmate-client / checkmate-backend /
# checkmate-mongo images this chart references are frozen at v3.8.1 — later versions
# are never published, so a bumped chart will fail to pull.
appVersion: "v3.8.1" # "v" prefix: published image tags are v-prefixed (ghcr.io/.../checkmate-*:v3.8.1)
+6 -4
View File
@@ -1,4 +1,6 @@
VITE_APP_API_BASE_URL=UPTIME_APP_API_BASE_URL
VITE_APP_API_V2_BASE_URL=UPTIME_APP_API_V2_BASE_URL
VITE_APP_CLIENT_HOST=UPTIME_APP_CLIENT_HOST
VITE_APP_LOG_LEVEL=UPTIME_APP_LOG_LEVEL
# Production builds use same-origin defaults: API at /api/v1, client host from
# window.location.origin. The empty values below override any local .env so a
# production build never bakes in a developer's localhost URLs.
VITE_APP_API_BASE_URL=
VITE_APP_CLIENT_HOST=
VITE_APP_LOG_LEVEL=
-1
View File
@@ -28,5 +28,4 @@ dist-ssr
# Scripts
*.sh
!env.sh
.env.development
-8
View File
@@ -1,8 +0,0 @@
#!/bin/sh
for i in $(env | grep UPTIME_APP_)
do
key=$(echo $i | cut -d '=' -f 1)
value=$(echo $i | cut -d '=' -f 2-)
echo $key=$value
find /usr/share/nginx/html -type f \( -name '*.js' -o -name '*.css' \) -exec sed -i "s|${key}|${value}|g" '{}' +
done
+1
View File
@@ -12,6 +12,7 @@
/>
<title>Checkmate</title>
<script src="/config.js"></script>
</head>
<body>
+2 -22
View File
@@ -92,7 +92,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.7",
"@babel/generator": "^7.29.7",
@@ -408,7 +407,6 @@
"node_modules/@emotion/react": {
"version": "11.14.0",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -446,7 +444,6 @@
"node_modules/@emotion/styled": {
"version": "11.14.1",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -1226,7 +1223,6 @@
"node_modules/@mui/material": {
"version": "7.3.7",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4",
"@mui/core-downloads-tracker": "^7.3.7",
@@ -1331,7 +1327,6 @@
"node_modules/@mui/system": {
"version": "7.3.7",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4",
"@mui/private-theming": "^7.3.7",
@@ -2376,7 +2371,6 @@
"version": "24.5.2",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.12.0"
}
@@ -2392,7 +2386,6 @@
"node_modules/@types/react": {
"version": "18.3.27",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/prop-types": "*",
"csstype": "^3.2.2"
@@ -2483,7 +2476,6 @@
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
"dev": true,
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "7.18.0",
"@typescript-eslint/types": "7.18.0",
@@ -2764,7 +2756,6 @@
"version": "8.15.0",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -3121,7 +3112,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.42",
"caniuse-lite": "^1.0.30001800",
@@ -3565,8 +3555,7 @@
},
"node_modules/dayjs": {
"version": "1.11.13",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.3",
@@ -3965,7 +3954,6 @@
"version": "8.57.1",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
@@ -4778,7 +4766,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.27.6"
},
@@ -5590,7 +5577,6 @@
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.19.0.tgz",
"integrity": "sha512-REhYUN8gNP3HlcIZS6QU2uy8iovl31cXsrNDkCcqWSQbCkcpdYLczqDz5PVIwNH42UQNyvukjes/RoHPDrOUmQ==",
"license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"@mapbox/geojson-rewind": "^0.5.2",
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
@@ -6372,7 +6358,6 @@
"node_modules/react-dom": {
"version": "18.3.1",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -6384,7 +6369,6 @@
"node_modules/react-hook-form": {
"version": "7.71.1",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -6588,8 +6572,7 @@
},
"node_modules/redux": {
"version": "5.0.1",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/redux-persist": {
"version": "6.0.0",
@@ -6739,7 +6722,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
"integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "1.0.9"
},
@@ -7581,7 +7563,6 @@
"version": "5.9.3",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -7719,7 +7700,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
"integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
+4
View File
@@ -0,0 +1,4 @@
// Fallback so /config.js always resolves (e.g. under the Vite dev server). In
// the Docker image the server shadows this path and renders the real config
// from its CLIENT_CONFIG_* environment variables.
window.__CHECKMATE_CONFIG__ = {};
@@ -13,7 +13,9 @@ export const languageNames: Record<string, string> = {
ca: "Català",
es: "Español",
fr: "Français",
it: "Italiano",
"pt-BR": "Português (BR)",
pl: "Polski",
cs: "Čeština",
fi: "Suomi",
tr: "Türkçe",
@@ -20,7 +20,7 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) =>
const msg: Record<string, string> = {
success: "Excellent",
warning: "Average",
danger: "Poor",
error: "Poor",
};
return (
@@ -10,8 +10,9 @@ import { useInviteForm } from "@/Hooks/useInviteForm";
import type { InviteFormData } from "@/Validation/invite";
import { usePost } from "@/Hooks/UseApi";
import { LAYOUT } from "@/Utils/Theme/constants";
import { runtimeConfig } from "@/Utils/runtimeConfig";
const CLIENT_HOST = import.meta.env.VITE_APP_CLIENT_HOST;
const CLIENT_HOST = runtimeConfig.clientHost || import.meta.env.VITE_APP_CLIENT_HOST;
interface InviteResponse {
token: string;
@@ -56,7 +57,7 @@ export const InviteTeamMemberDialog = ({
const result = await generateToken("/invite", data);
if (result?.data?.token) {
const token = result.data.token;
const link = CLIENT_HOST ? `${CLIENT_HOST}/register/${token}` : token;
const link = `${CLIENT_HOST || window.location.origin}/register/${token}`;
setInviteLink(link);
}
};
+2 -1
View File
@@ -3,7 +3,8 @@
declare const __APP_VERSION__: string;
interface ImportMetaEnv {
readonly VITE_APP_API_V2_BASE_URL?: string;
readonly VITE_APP_API_BASE_URL?: string;
readonly VITE_APP_CLIENT_HOST?: string;
readonly VITE_APP_LOG_LEVEL?: "debug" | "info" | "warn" | "error";
}
+3 -1
View File
@@ -1,8 +1,10 @@
import axios from "axios";
import type { AxiosError } from "axios";
import type { AxiosRequestConfig, AxiosResponse } from "axios";
import { runtimeConfig } from "@/Utils/runtimeConfig";
const BASE_URL = import.meta.env.VITE_APP_API_BASE_URL;
const BASE_URL =
runtimeConfig.apiBaseUrl || import.meta.env.VITE_APP_API_BASE_URL || "/api/v1";
const api = axios.create({
baseURL: BASE_URL,
+3 -1
View File
@@ -1,4 +1,5 @@
import type { LogLevel } from "@/Types/Log";
import { runtimeConfig } from "@/Utils/runtimeConfig";
interface LogContext {
[key: string]: any;
@@ -25,7 +26,8 @@ interface ErrorLogData {
userAgent: string;
}
const configuredLevel: LogLevel = import.meta.env.VITE_APP_LOG_LEVEL || "error";
const configuredLevel: LogLevel =
runtimeConfig.logLevel || import.meta.env.VITE_APP_LOG_LEVEL || "error";
const configuredPriority = LOG_LEVEL_PRIORITY[configuredLevel];
const shouldLog = (level: LogLevel): boolean => {
+18
View File
@@ -0,0 +1,18 @@
import type { LogLevel } from "@/Types/Log";
// Served by GET /config.js (rendered from server env) or a static config.js
// next to index.html; loaded before the bundle in index.html.
export interface RuntimeConfig {
apiBaseUrl?: string;
clientHost?: string;
logLevel?: LogLevel;
}
declare global {
interface Window {
__CHECKMATE_CONFIG__?: RuntimeConfig;
}
}
export const runtimeConfig: RuntimeConfig =
(typeof window !== "undefined" && window.__CHECKMATE_CONFIG__) || {};
+4 -1
View File
@@ -1,6 +1,9 @@
import { PUBLIC_STATUS_PAGE_PREFIX, type StatusPage } from "@/Types/StatusPage";
import { runtimeConfig } from "@/Utils/runtimeConfig";
const CLIENT_HOST = import.meta.env.VITE_APP_CLIENT_HOST as string | undefined;
const CLIENT_HOST =
runtimeConfig.clientHost ||
(import.meta.env.VITE_APP_CLIENT_HOST as string | undefined);
const getClientOriginProtocol = (): string => {
const source =
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -4,7 +4,7 @@
# Build on the host arch (BUILDPLATFORM) rather than under QEMU — the output is
# pure JS so it's arch-independent, and this avoids the esbuild host/native
# binary version mismatch under emulation.
FROM --platform=$BUILDPLATFORM node:20-slim AS frontend-build
FROM --platform=$BUILDPLATFORM node:22-slim AS frontend-build
WORKDIR /app/client
@@ -19,7 +19,7 @@ RUN npm run build
# ---------------------
# Backend stage
# ---------------------
FROM node:22-slim AS backend
FROM node:22-slim AS app
# Install ping
RUN apt-get update \
@@ -28,23 +28,18 @@ RUN apt-get update \
WORKDIR /app/server
COPY server/package.json ./
COPY server/package*.json ./
RUN npm install
RUN npm ci
COPY server ./
RUN chmod +x ./scripts/inject-vars.sh
RUN npm run build
COPY --from=frontend-build /app/client/dist ./public
RUN chown -R node:node ./public \
&& chown -R node:node ./dist \
&& chown -R node:node ./scripts
USER node
EXPOSE 52345 52346
EXPOSE 52345
CMD ["sh", "-c", "./scripts/inject-vars.sh && node ./dist/index.js"]
CMD ["node", "dist/index.js"]
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=bluewaveuptime/uptime_client
set dockerfiles[0]=.\docker\coolify\client.Dockerfile
set services[1]=bluewaveuptime/uptime_database_mongo
set dockerfiles[1]=.\docker\coolify\mongoDB.Dockerfile
set services[2]=bluewaveuptime/uptime_server
set dockerfiles[2]=.\docker\coolify\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-24
View File
@@ -1,24 +0,0 @@
#!/bin/bash
# Change directory to root Server directory for correct Docker Context
cd "$(dirname "$0")"
cd ../../
# Define an array of services and their Dockerfiles
declare -A services=(
["bluewaveuptime/uptime_client"]="./docker/coolify/client.Dockerfile"
["bluewaveuptime/uptime_database_mongo"]="./docker/coolify/mongoDB.Dockerfile"
["bluewaveuptime/uptime_server"]="./docker/coolify/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for service in "${!services[@]}"; do
docker build -f "${services[$service]}" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-22
View File
@@ -1,22 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client .
RUN npm run build
FROM nginx:1.27.1-alpine
COPY ./server/docker/dist/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-35
View File
@@ -1,35 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-demo.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:5000/api/;
proxy_http_version 1.1;
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 /api-docs/ {
proxy_pass http://server:5000/api-docs/;
proxy_http_version 1.1;
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;
}
}
-20
View File
@@ -1,20 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY ../../package*.json ./
RUN npm install
COPY ../../ ./
RUN npm run build
EXPOSE 5000
CMD ["node", "dist/index.js"]
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=uptime_client
set dockerfiles[0]=.\docker\dev\client.Dockerfile
set services[1]=uptime_mongo
set dockerfiles[1]=.\docker\dev\mongoDB.Dockerfile
set services[2]=uptime_server
set dockerfiles[2]=.\docker\dev\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-29
View File
@@ -1,29 +0,0 @@
#!/bin/bash
# Change directory to root Server directory for correct Docker Context
cd "$(dirname "$0")"
cd ../..
# Define service names and their corresponding Dockerfiles in parallel arrays
services=("uptime_client" "uptime_mongo" "uptime_server")
dockerfiles=(
"./docker/dev/client.Dockerfile"
"./docker/dev/mongoDB.Dockerfile"
"./docker/dev/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for i in "${!services[@]}"; do
service="${services[$i]}"
dockerfile="${dockerfiles[$i]}"
docker build -f "$dockerfile" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-20
View File
@@ -1,20 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client ./
RUN npm run build
FROM nginx:1.27.1-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
@@ -1,29 +1,14 @@
# Dev/Test only: Not required in production
# Example Docker Compose configuration for custom CA trust
# This file demonstrates how to configure Checkmate to trust custom CAs
#
# Usage: docker-compose -f docker-compose.yaml -f docker-compose.custom-ca-example.yaml up
#
# Usage: docker compose -f docker-compose.yaml -f docker-compose.custom-ca-example.yaml up
services:
server:
image: uptime_server:latest
restart: always
ports:
- "52345:52345"
env_file:
- server.env
checkmate:
environment:
# Mount your custom CA certificate
NODE_EXTRA_CA_CERTS: /certs/custom-ca.pem
volumes:
# Mount the certs directory (read-only for security)
- ./certs:/certs:ro
depends_on:
- mongodb
# Optional: Add healthcheck to ensure the server starts properly
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:52345/api/v1/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
+12 -18
View File
@@ -1,27 +1,20 @@
services:
client:
image: uptime_client:latest
restart: always
ports:
- "80:80"
environment:
UPTIME_APP_API_BASE_URL: "http://localhost:52345/api/v1"
UPTIME_APP_CLIENT_HOST: "http://localhost"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d/
depends_on:
- server
server:
image: uptime_server:latest
checkmate:
build:
context: ../..
dockerfile: docker/Dockerfile
restart: always
ports:
- "52345:52345"
env_file:
- server.env
depends_on:
- mongodb
mongodb:
condition: service_healthy
worker:
image: uptime_server:latest
build:
context: ../..
dockerfile: docker/Dockerfile
restart: always
ports:
- "52346:52346"
@@ -43,9 +36,10 @@ services:
timeout: 3s
retries: 3
depends_on:
- mongodb
mongodb:
condition: service_healthy
mongodb:
image: uptime_mongo:latest
image: mongo:8.0
restart: always
ports:
- "27017:27017"
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-35
View File
@@ -1,35 +0,0 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name localhost; # Set server name to localhost
server_tokens off;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# location /api/ {
# proxy_pass http://server:52345/api/;
# proxy_http_version 1.1;
# 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;
# proxy_set_header Connection '';
# chunked_transfer_encoding off;
# proxy_buffering off;
# proxy_cache off;
# }
# location /api-docs/ {
# proxy_pass http://server:52345/api-docs/;
# proxy_http_version 1.1;
# 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;
# }
}
-20
View File
@@ -1,20 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY ./server/package*.json ./
RUN npm install
COPY ./server/ ./
RUN npm run build
EXPOSE 52345
CMD ["node", "dist/index.js"]
-44
View File
@@ -1,44 +0,0 @@
#!/bin/bash
set -e # Exit on error
# Change directory to root Server directory for correct Docker Context
cd "$(dirname "$0")"
cd ../..
# Ensure buildx builder exists and is used
if ! docker buildx inspect mybuilder &>/dev/null; then
docker buildx create --name mybuilder --use
else
docker buildx use mybuilder
fi
# Define service names and Dockerfiles
services=("mono_server_arm")
dockerfiles=(
"./docker/dist-arm/server.Dockerfile"
)
# Static image name for GitHub Container Registry (GHCR)
image="ghcr.io/bluewave-labs/checkmate:backend-dist-multi-arch"
platforms="linux/amd64,linux/arm64"
repo_url="https://github.com/bluewave-labs/checkmate"
# Loop through each service and build
for i in "${!services[@]}"; do
service="${services[$i]}"
dockerfile="${dockerfiles[$i]}"
echo "🚀 Building multi-arch image for $service..."
docker buildx build \
--platform "$platforms" \
-f "$dockerfile" \
-t "$image" \
--label "org.opencontainers.image.source=$repo_url" \
--push \
.
echo "✅ $image pushed for platforms: $platforms"
done
echo "🎉 All multi-arch images built and pushed successfully"
-28
View File
@@ -1,28 +0,0 @@
services:
server:
image: ghcr.io/bluewave-labs/checkmate-backend-mono-multiarch:latest
restart: always
pull_policy: always
ports:
- "52345:52345"
environment:
- UPTIME_APP_API_BASE_URL=http://localhost:52345/api/v1
- UPTIME_APP_CLIENT_HOST=http://localhost
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
- CLIENT_HOST=http://localhost
- JWT_SECRET=my_secret
depends_on:
- mongodb
mongodb:
image: mongo:6.0
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.runCommand({ ping: 1 })", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
-30
View File
@@ -1,30 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=uptime_database_mongo
set dockerfiles[0]=.\docker\dist-mono\mongoDB.Dockerfile
set services[1]=uptime_server
set dockerfiles[1]=.\docker\dist-mono\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-28
View File
@@ -1,28 +0,0 @@
#!/bin/bash
# Change directory to root Server directory for correct Docker Context
cd "$(dirname "$0")"
cd ../..
# Define service names and their corresponding Dockerfiles in parallel arrays
services=("mono_mongo" "mono_server")
dockerfiles=(
"./docker/dist-mono/mongoDB.Dockerfile"
"./docker/dist-mono/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for i in "${!services[@]}"; do
service="${services[$i]}"
dockerfile="${dockerfiles[$i]}"
docker build -f "$dockerfile" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
@@ -1,27 +0,0 @@
services:
server:
image: mono_server
restart: always
ports:
- "52345:52345"
environment:
- UPTIME_APP_API_BASE_URL=http://localhost:52345/api/v1
- UPTIME_APP_CLIENT_HOST=http://localhost
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
- CLIENT_HOST=http://localhost
- JWT_SECRET=my_secret
depends_on:
- mongodb
mongodb:
image: mono_mongo
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
-28
View File
@@ -1,28 +0,0 @@
services:
server:
image: ghcr.io/bluewave-labs/checkmate-backend-mono:latest
pull_policy: always
restart: always
ports:
- "52345:52345"
environment:
- UPTIME_APP_API_BASE_URL=http://localhost:52345/api/v1
- UPTIME_APP_CLIENT_HOST=http://localhost
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
- CLIENT_HOST=http://localhost
- JWT_SECRET=my_secret
depends_on:
- mongodb
mongodb:
image: ghcr.io/bluewave-labs/checkmate-mongo:latest
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-37
View File
@@ -1,37 +0,0 @@
FROM node:22-slim AS frontend-build
WORKDIR /app/client
COPY client/package*.json ./
RUN npm install
COPY client ./
RUN npm run build
FROM node:22-slim AS app
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app/server
COPY server ./
RUN npm install
RUN npm run build
RUN cp -r src/templates dist/templates
COPY --from=frontend-build /app/client/dist ./public
RUN chmod +x ./scripts/inject-vars.sh \
&& chown -R node:node ./public \
&& chown -R node:node ./dist \
&& chown -R node:node ./scripts
EXPOSE 52345
CMD ["sh", "-c", "./scripts/inject-vars.sh && node ./dist/index.js"]
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=bluewaveuptime/uptime_client
set dockerfiles[0]=.\docker\dist\client.Dockerfile
set services[1]=bluewaveuptime/uptime_database_mongo
set dockerfiles[1]=.\docker\dist\mongoDB.Dockerfile
set services[2]=bluewaveuptime/uptime_server
set dockerfiles[2]=.\docker\dist\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-25
View File
@@ -1,25 +0,0 @@
#!/bin/bash
# Change directory to root Server directory for correct Docker Context
cd "$(dirname "$0")"
cd ../../
# Define an array of services and their Dockerfiles
declare -A services=(
["bluewaveuptime/uptime_client"]="./docker/dist/client.Dockerfile"
["bluewaveuptime/uptime_database_mongo"]="./docker/dist/mongoDB.Dockerfile"
["bluewaveuptime/uptime_server"]="./docker/dist/server.Dockerfile"
)
for service in "${!services[@]}"; do
docker build \
-f "${services[$service]}" \
-t "$service" \
.
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-22
View File
@@ -1,22 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client .
RUN npm run build
FROM nginx:1.27.1-alpine
COPY ./docker/dist/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
-38
View File
@@ -1,38 +0,0 @@
services:
client:
image: ghcr.io/bluewave-labs/checkmate-client:latest
restart: always
environment:
UPTIME_APP_API_BASE_URL: "http://localhost:52345/api/v1"
UPTIME_APP_CLIENT_HOST: "http://localhost"
ports:
- "80:80"
- "443:443"
depends_on:
- server
server:
image: ghcr.io/bluewave-labs/checkmate-backend:latest
restart: always
ports:
- "52345:52345"
depends_on:
- mongodb
environment:
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
- CLIENT_HOST=http://localhost
- JWT_SECRET=my_secret
# volumes:
# - /var/run/docker.sock:/var/run/docker.sock:ro
mongodb:
image: ghcr.io/bluewave-labs/checkmate-mongo:latest
restart: always
volumes:
- ./mongo/data:/data/db
command: ["mongod", "--quiet", "--bind_ip_all"]
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-35
View File
@@ -1,35 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-demo.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
# location /api/ {
# proxy_pass http://server:5000/api/;
# proxy_http_version 1.1;
# 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 /api-docs/ {
proxy_pass http://server:5000/api-docs/;
proxy_http_version 1.1;
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;
}
}
-20
View File
@@ -1,20 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY ./server/package*.json ./
RUN npm install
COPY ./server/ ./
RUN npm run build
EXPOSE 52345
CMD ["node", "dist/index.js"]
+45
View File
@@ -0,0 +1,45 @@
services:
checkmate:
image: ghcr.io/bluewave-labs/checkmate:latest
pull_policy: always
restart: always
ports:
- "52345:52345"
environment:
- DB_CONNECTION_STRING=mongodb://mongodb:27017/uptime_db
- CLIENT_HOST=${CLIENT_HOST:-http://localhost:52345}
- JWT_SECRET=${JWT_SECRET:?set JWT_SECRET in your environment}
stop_grace_period: 60s
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:52346/livez',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))",
]
interval: 15s
timeout: 3s
start_period: 60s
start_interval: 2s
retries: 3
depends_on:
mongodb:
condition: service_healthy
mongodb:
image: mongo:8.0
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- mongo-data:/data/db
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
volumes:
mongo-data:
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=uptime_client
set dockerfiles[0]=.\docker\prod\client.Dockerfile
set services[1]=uptime_database_mongo
set dockerfiles[1]=.\docker\prod\mongoDB.Dockerfile
set services[2]=uptime_server
set dockerfiles[2]=.\docker\prod\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-25
View File
@@ -1,25 +0,0 @@
#!/bin/bash
# Change directory to root directory for correct Docker Context
cd "$(dirname "$0")"
cd ../../
# Define an array of services and their Dockerfiles
declare -A services=(
["uptime_client"]="./docker/prod/client.Dockerfile"
["uptime_database_mongo"]="./docker/prod/mongoDB.Dockerfile"
["uptime_server"]="./docker/prod/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for service in "${!services[@]}"; do
docker build -f "${services[$service]}" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-20
View File
@@ -1,20 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client .
RUN npm run build
FROM nginx:1.27.1-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
-53
View File
@@ -1,53 +0,0 @@
services:
client:
image: ghcr.io/bluewave-labs/checkmate:frontend-demo
restart: always
environment:
UPTIME_APP_API_BASE_URL: "https://demo.checkmate.so/api/v1"
UPTIME_APP_CLIENT_HOST: "https://demo.checkmate.so"
ports:
- "80:80"
- "443:443"
depends_on:
- server
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d/:ro
- /etc/letsencrypt:/etc/nginx/ssl:ro
server:
image: ghcr.io/bluewave-labs/checkmate:backend-demo
restart: always
ports:
- "52345:52345"
env_file:
- server.env
depends_on:
- mongodb
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb:
image: ghcr.io/bluewave-labs/checkmate:mongo-demo
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data:/data/db
env_file:
- mongo.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
capture:
image: ghcr.io/bluewave-labs/capture:latest
container_name: capture
restart: unless-stopped
ports:
- "59232:59232"
environment:
- API_SECRET=my_secret
- GIN_MODE=release
volumes:
- /etc/os-release:/etc/os-release:ro
-41
View File
@@ -1,41 +0,0 @@
function initiateReplicaSet() {
try {
rs.initiate({
_id: "rs0",
members: [{ _id: 0, host: "localhost:27017" }],
});
} catch (e) {
print("Replica set already initiated or error occurred: " + e);
}
}
function waitForPrimary() {
while (true) {
const isMaster = db.isMaster();
if (isMaster.ismaster) {
print("This node is now PRIMARY.");
break;
}
print("Waiting to become PRIMARY...");
sleep(2000);
}
}
function createUser() {
db = db.getSiblingDB("uptime_db");
var username = process.env.USERNAME_ENV_VAR;
var password = process.env.PASSWORD_ENV_VAR;
db.createUser({
user: username,
pwd: password,
roles: [{ role: "readWrite", db: "uptime_db" }],
});
print("User '" + username + "' created successfully");
}
initiateReplicaSet();
waitForPrimary();
createUser();
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-15
View File
@@ -1,15 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-demo.bluewavelabs.ca www.checkmate-demo.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://[domain-name]$request_uri;
}
}
-69
View File
@@ -1,69 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-demo.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:52345/api/;
proxy_http_version 1.1;
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 /api-docs/ {
proxy_pass http://server:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name checkmate-demo.bluewavelabs.ca;
ssl_certificate /etc/nginx/ssl/live/demo.checkmate.so/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/demo.checkmate.so/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:52345/api/;
proxy_http_version 1.1;
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 /api-docs/ {
proxy_pass http://server:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
-24
View File
@@ -1,24 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_OPTIONS="--max-old-space-size=2048"
WORKDIR /app
COPY ./server/package*.json ./
RUN npm install
COPY ./server ./
RUN npm run build
RUN cp -r src/templates dist/templates
EXPOSE 52345
CMD ["node", "dist/index.js"]
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=uptime_client
set dockerfiles[0]=.\docker\staging\client.Dockerfile
set services[1]=uptime_database_mongo
set dockerfiles[1]=.\docker\staging\mongoDB.Dockerfile
set services[2]=uptime_server
set dockerfiles[2]=.\docker\staging\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-25
View File
@@ -1,25 +0,0 @@
#!/bin/bash
# Change directory to root directory for correct Docker Context
cd "$(dirname "$0")"
cd ../../
# Define an array of services and their Dockerfiles
declare -A services=(
["uptime_client"]="./docker/staging/client.Dockerfile"
["uptime_database_mongo"]="./docker/staging/mongoDB.Dockerfile"
["uptime_server"]="./docker/staging/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for service in "${!services[@]}"; do
docker build -f "${services[$service]}" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-19
View File
@@ -1,19 +0,0 @@
version: "3"
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf.d/:/etc/nginx/conf.d/:ro
- ./certbot/www/:/var/www/certbot/:ro
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
depends_on:
- webserver
-20
View File
@@ -1,20 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client ./
RUN npm run build
FROM nginx:1.27.1-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
-62
View File
@@ -1,62 +0,0 @@
services:
client:
image: ghcr.io/bluewave-labs/checkmate:frontend-staging
restart: always
environment:
UPTIME_APP_API_BASE_URL: "https://checkmate-test.bluewavelabs.ca/api/v1"
UPTIME_APP_CLIENT_HOST: "https://checkmate-test.bluewavelabs.ca"
ports:
- "80:80"
- "443:443"
depends_on:
- server
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
certbot:
image: certbot/certbot:latest
restart: always
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${!}; done;'"
server:
image: ghcr.io/bluewave-labs/checkmate:backend-staging
restart: always
ports:
- "52345:52345"
env_file:
- server.env
depends_on:
- mongodb
mongodb:
image: ghcr.io/bluewave-labs/checkmate:mongo-staging
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
ports:
- "27017:27017"
volumes:
- ./mongo/data:/data/db
env_file:
- mongo.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
capture:
image: ghcr.io/bluewave-labs/capture:latest
container_name: capture
restart: unless-stopped
ports:
- "59232:59232"
environment:
- API_SECRET=my_secret
- GIN_MODE=release
volumes:
- /etc/os-release:/etc/os-release:ro
@@ -1,15 +0,0 @@
try {
const status = rs.status();
printjson(status);
} catch (e) {
if (e.codeName === "NotYetInitialized") {
print("Replica set not initialized. Initiating...");
rs.initiate({
_id: "rs0",
members: [{ _id: 0, host: "mongodb:27017" }],
});
} else {
print("Unexpected error during rs.status():");
printjson(e);
}
}
@@ -1,16 +0,0 @@
var username = process.env.USERNAME_ENV_VAR;
var password = process.env.PASSWORD_ENV_VAR;
db = db.getSiblingDB("uptime_db");
db.createUser({
user: username,
pwd: password,
roles: [
{
role: "readWrite",
db: "uptime_db",
},
],
});
print("User uptime_user created successfully");
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-15
View File
@@ -1,15 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-test.bluewavelabs.ca www.checkmate-test.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://[domain-name]$request_uri;
}
}
-77
View File
@@ -1,77 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name checkmate-test.bluewavelabs.ca;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:52345/api/;
proxy_http_version 1.1;
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;
proxy_set_header Connection '';
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
location /api-docs/ {
proxy_pass http://server:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name checkmate-test.bluewavelabs.ca;
ssl_certificate /etc/nginx/ssl/live/checkmate-test.bluewavelabs.ca/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/checkmate-test.bluewavelabs.ca/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server:52345/api/;
proxy_http_version 1.1;
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;
proxy_set_header Connection '';
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
}
location /api-docs/ {
proxy_pass http://server:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
-24
View File
@@ -1,24 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_OPTIONS="--max-old-space-size=2048"
WORKDIR /app
COPY ./server/package*.json ./
RUN npm install
COPY ./server ./
RUN npm run build
RUN cp -r src/templates dist/templates
EXPOSE 52345
CMD ["node", "dist/index.js"]
-33
View File
@@ -1,33 +0,0 @@
@echo off
setlocal enabledelayedexpansion
REM Change directory to root Server directory for correct Docker Context
cd /d "%~dp0"
cd ../..
REM Define service names and their corresponding Dockerfiles
set services[0]=uptime_client
set dockerfiles[0]=.\docker\unified\client.Dockerfile
set services[1]=uptime_database_mongo
set dockerfiles[1]=.\docker\unified\mongoDB.Dockerfile
set services[2]=uptime_server
set dockerfiles[2]=.\docker\unified\server.Dockerfile
REM Loop through each service and build the corresponding image
for /L %%i in (0,1,2) do (
set service=!services[%%i]!
set dockerfile=!dockerfiles[%%i]!
docker build -f "!dockerfile!" -t "!service!" .
REM Check if the build succeeded
if errorlevel 1 (
echo Error building !service! image. Exiting...
exit /b 1
)
)
echo All images built successfully
exit /b 0
-25
View File
@@ -1,25 +0,0 @@
#!/bin/bash
# Change directory to root directory for correct Docker Context
cd "$(dirname "$0")"
cd ../../
# Define an array of services and their Dockerfiles
declare -A services=(
["uptime_client"]="./docker/unified/client.Dockerfile"
["uptime_database_mongo"]="./docker/unified/mongoDB.Dockerfile"
["uptime_server"]="./docker/unified/server.Dockerfile"
)
# Loop through each service and build the corresponding image
for service in "${!services[@]}"; do
docker build -f "${services[$service]}" -t "$service" .
# Check if the build succeeded
if [ $? -ne 0 ]; then
echo "Error building $service image. Exiting..."
exit 1
fi
done
echo "All images built successfully"
-19
View File
@@ -1,19 +0,0 @@
version: "3"
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf.d/:/etc/nginx/conf.d/:ro
- ./certbot/www/:/var/www/certbot/:ro
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
depends_on:
- webserver
-20
View File
@@ -1,20 +0,0 @@
FROM node:20-slim AS build
ENV NODE_OPTIONS="--max-old-space-size=4096"
WORKDIR /app
COPY ./client/package*.json ./
RUN npm install
COPY ./client .
RUN npm run build
FROM nginx:1.27.1-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY --from=build /app/env.sh /docker-entrypoint.d/env.sh
RUN chmod +x /docker-entrypoint.d/env.sh
CMD ["nginx", "-g", "daemon off;"]
-114
View File
@@ -1,114 +0,0 @@
# sudo certbot certonly --standalone --http-01-port 8080
# cerbot needs to run on 8080 since port 80 is used by the gateway
services:
# Gateway (Single Entry Point)
gateway:
image: nginx:1.27.1-alpine
container_name: checkmate-gateway
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /etc/letsencrypt:/etc/nginx/ssl:ro
- ./gateway/nginx.conf:/etc/nginx/conf.d/default.conf:ro
# Production Stack -----
client-prod:
image: ghcr.io/bluewave-labs/checkmate:frontend-demo
container_name: client-prod
restart: always
environment:
UPTIME_APP_API_BASE_URL: "https://demo.checkmate.so/api/v1"
UPTIME_APP_CLIENT_HOST: "https://demo.checkmate.so"
expose:
- "80"
depends_on:
- server-prod
volumes:
- ./nginx/conf.d/prod.conf:/etc/nginx/conf.d/default.conf:ro
server-prod:
image: ghcr.io/bluewave-labs/checkmate:backend-demo
container_name: server-prod
restart: always
env_file:
- server-prod.env
depends_on:
- mongodb-prod
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-prod:
image: ghcr.io/bluewave-labs/checkmate:mongo-demo
container_name: mongodb-prod
restart: always
command: [ "mongod", "--quiet", "--bind_ip_all" ]
volumes:
- ./mongo/data-prod:/data/db
env_file:
- mongo-prod.env
healthcheck:
test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet" ]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Staging Stack -----
client-staging:
image: ghcr.io/bluewave-labs/checkmate:frontend-staging
container_name: client-staging
restart: always
environment:
UPTIME_APP_API_BASE_URL: "https://staging.checkmate.so/api/v1"
UPTIME_APP_CLIENT_HOST: "https://staging.checkmate.so"
expose:
- "80"
depends_on:
- server-staging
volumes:
- ./nginx/conf.d/staging.conf:/etc/nginx/conf.d/default.conf:ro
server-staging:
image: ghcr.io/bluewave-labs/checkmate:backend-staging
container_name: server-staging
restart: always
env_file:
- server-staging.env
depends_on:
- mongodb-staging
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-staging:
image: ghcr.io/bluewave-labs/checkmate:mongo-staging
container_name: mongodb-staging
restart: always
command: [ "mongod", "--quiet", "--bind_ip_all" ]
volumes:
- ./mongo/data-staging:/data/db
env_file:
- mongo-staging.env
healthcheck:
test: [ "CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet" ]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Shared Utils
capture:
image: ghcr.io/bluewave-labs/capture:latest
container_name: capture
restart: unless-stopped
ports:
- "59232:59232"
environment:
- API_SECRET=my_secret
- GIN_MODE=release
volumes:
- /etc/os-release:/etc/os-release:ro
-3
View File
@@ -1,3 +0,0 @@
FROM mongo
EXPOSE 27017
CMD ["mongod"]
-31
View File
@@ -1,31 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name _;
server_tokens off;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server-prod:52345/api/;
proxy_http_version 1.1;
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 /api-docs/ {
proxy_pass http://server-prod:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
-31
View File
@@ -1,31 +0,0 @@
server {
listen 80;
listen [::]:80;
server_name _;
server_tokens off;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://server-staging:52345/api/;
proxy_http_version 1.1;
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 /api-docs/ {
proxy_pass http://server-staging:52345/api-docs/;
proxy_http_version 1.1;
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;
}
}
-22
View File
@@ -1,22 +0,0 @@
FROM node:22-slim
# Install ping
RUN apt-get update \
&& apt-get install -y iputils-ping \
&& rm -rf /var/lib/apt/lists/*
ENV NODE_OPTIONS="--max-old-space-size=2048"
WORKDIR /app
COPY ./server/package*.json ./
RUN npm install
COPY ./server ./
RUN npm run build
EXPOSE 52345
CMD ["node", "dist/index.js"]
-2
View File
@@ -19,8 +19,6 @@ If you need to monitor internal HTTPS endpoints with certificates from private C
### Example Configurations
The `docker/dev/` directory contains example configurations:
- `docker-compose.custom-ca-example.yaml` - Example Docker Compose with custom CA
- `server-custom-ca.Dockerfile` - Example Dockerfile for OS-level CA trust
- `export-smallstep-ca.sh` - Helper script for Smallstep CA export
## Contributing to Documentation
+18 -33
View File
@@ -18,8 +18,8 @@ Add a volume mount for your CA certificate and set the environment variable:
```yaml
services:
server:
image: uptime_server:latest
checkmate:
image: ghcr.io/bluewave-labs/checkmate:latest
restart: always
ports:
- "52345:52345"
@@ -30,7 +30,6 @@ services:
volumes:
- ./certs:/certs:ro
depends_on:
- redis
- mongodb
```
@@ -52,67 +51,53 @@ For more comprehensive trust configuration, you can create a derived Dockerfile
### Custom Dockerfile
Create `docker/dev/server-custom-ca.Dockerfile`:
Create `checkmate-custom-ca.Dockerfile`:
```dockerfile
FROM node:20-alpine
FROM ghcr.io/bluewave-labs/checkmate:latest
# Install ca-certificates for Alpine
RUN apk add --no-cache ca-certificates
USER root
WORKDIR /app
RUN apt-get update \
&& apt-get install -y ca-certificates \
&& rm -rf /var/lib/apt/lists/*
COPY ./server/package*.json ./
RUN npm install
COPY ./server/ ./
# Copy your custom CA certificate
# Copy your custom CA certificate (must have a .crt extension)
COPY ./certs/custom-ca.crt /usr/local/share/ca-certificates/
# Update CA certificates
RUN update-ca-certificates
EXPOSE 52345
USER node
CMD ["node", "src/index.js"]
# Node uses its bundled CA store by default; make it read the system store
ENV NODE_OPTIONS="--use-system-ca"
```
### Docker Compose Override
Create `docker/dev/docker-compose.custom-ca.yaml`:
Create `docker-compose.custom-ca.yaml`:
```yaml
services:
server:
checkmate:
build:
context: .
dockerfile: server-custom-ca.Dockerfile
dockerfile: checkmate-custom-ca.Dockerfile
restart: always
ports:
- "52345:52345"
env_file:
- server.env
depends_on:
- redis
- mongodb
```
Run with: `docker-compose -f docker-compose.yaml -f docker-compose.custom-ca.yaml up`
Run with: `docker compose -f docker-compose.yaml -f docker-compose.custom-ca.yaml up`
## Alpine Linux Considerations
## Base Image Considerations
Since Checkmate uses Alpine Linux as the base image, you need to install the `ca-certificates` package:
```dockerfile
# Install ca-certificates for Alpine
RUN apk add --no-cache ca-certificates
# Copy and update CA certificates
COPY ./certs/custom-ca.crt /usr/local/share/ca-certificates/
RUN update-ca-certificates
```
The Checkmate image is Debian-based (`node:22-slim`), which does not ship the `ca-certificates` package — install it before running `update-ca-certificates` (see the Dockerfile above). Certificates dropped into `/usr/local/share/ca-certificates/` must have a `.crt` extension, and Node only consults the system store when started with `--use-system-ca`. For most setups the `NODE_EXTRA_CA_CERTS` compose approach is simpler.
## Smallstep CA Configuration
+56
View File
@@ -0,0 +1,56 @@
# checkmate.so hosting (demo + staging)
Config for BlueWave's hosted instances at `demo.checkmate.so` and
`staging.checkmate.so`: one host, one nginx gateway terminating TLS, two
independent Checkmate stacks running the mono image
(`ghcr.io/bluewave-labs/checkmate`), plus a shared
[Capture](https://github.com/bluewave-labs/capture) agent. It replaces the old
`docker/unified/` setup (nginx client images + separate backend images + a
republished Mongo image) and doubles as a worked example of running the mono
image behind a TLS reverse proxy.
## How deploys work
`.github/workflows/build-image.yml` builds and pushes the image, then SSHes in
and runs `docker compose pull <service> && docker compose up -d <service>` in
this directory:
- merge to `develop` → image tagged `:develop` → `checkmate-staging` recreated
- merge to `master` → image tagged `:master` → `checkmate-demo` (prod) recreated
The host keeps a git checkout of this repo (on `develop`); the deploy does
`git pull` first so compose changes land with the code. Note the deploy only
recreates the checkmate service — changes to `gateway/nginx.conf` or the mongo
services need a manual `docker compose up -d` / gateway restart on the host.
## Host-local files (not committed)
Kept next to this compose file on the host:
- `server-prod.env` / `server-staging.env` — Checkmate server env
(`DB_CONNECTION_STRING`, `JWT_SECRET`, `CLIENT_HOST=https://demo.checkmate.so`
etc.). The old `UPTIME_APP_*` client vars are no-ops now and can be removed;
if a client override is ever needed, use the `CLIENT_CONFIG_*` vars (see the
Configuration section of the root README).
- `mongo-prod.env` / `mongo-staging.env` — Mongo credentials.
- `mongo/data-prod` / `mongo/data-staging` — Mongo data directories.
TLS certs live in `/etc/letsencrypt` (see `certbot-compose.yaml`; certbot
answers ACME challenges on port 8080 behind the gateway).
## One-time migration from docker/unified
1. `cd ~/checkmate && git pull` (must be on a branch containing this directory).
2. Stop the old stack: `cd docker/unified && docker compose down`.
3. Move host-local files here:
`mv docker/unified/{server-prod.env,server-staging.env,mongo-prod.env,mongo-staging.env} docs/hosting/checkmate-so/`
`mv docker/unified/mongo docs/hosting/checkmate-so/mongo`
4. **Check the Mongo data version before first start.** The old
`checkmate:mongo-*` images were built `FROM mongo` (floating latest), so the
data files follow whatever version was current at their last image build. Run
`db.adminCommand({ getParameter: 1, featureCompatibilityVersion: 1 })`
against the old container first and make the compose's `mongo:` tag match
(checked 2026-07-09: both stacks report FCV 8.2, hence the `mongo:8.2` pin
here). A lower pin than the data's FCV will refuse to start; a higher one
should step up one release at a time.
5. `cd docs/hosting/checkmate-so && docker compose up -d`.
@@ -0,0 +1,122 @@
# BlueWave's hosted demo + staging instances: one nginx gateway terminating TLS
# in front of two independent Checkmate stacks, both running the mono image
# (ghcr.io/bluewave-labs/checkmate). Doubles as a worked example of putting a
# TLS proxy in front of the image.
#
# Deployed by .github/workflows/build-image.yml (deploy-staging / deploy-demo
# jobs). Env files (server-prod.env, server-staging.env, mongo-prod.env,
# mongo-staging.env) live on the host next to this file and are not committed.
services:
# Gateway (single entry point)
gateway:
image: nginx:1.27.1-alpine
container_name: checkmate-gateway
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- /etc/letsencrypt:/etc/nginx/ssl:ro
- ./gateway/nginx.conf:/etc/nginx/conf.d/default.conf:ro
# Prod: demo.checkmate.so -----
checkmate-demo:
image: ghcr.io/bluewave-labs/checkmate:master
container_name: checkmate-demo
restart: always
env_file:
- server-prod.env
stop_grace_period: 60s
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:52346/livez',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))",
]
interval: 15s
timeout: 3s
start_period: 60s
start_interval: 2s
retries: 3
depends_on:
mongodb-prod:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-prod:
image: mongo:8.2
container_name: mongodb-prod
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data-prod:/data/db
env_file:
- mongo-prod.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Staging: staging.checkmate.so -----
checkmate-staging:
image: ghcr.io/bluewave-labs/checkmate:develop
container_name: checkmate-staging
restart: always
env_file:
- server-staging.env
stop_grace_period: 60s
healthcheck:
test:
[
"CMD",
"node",
"-e",
"require('http').get('http://localhost:52346/livez',r=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))",
]
interval: 15s
timeout: 3s
start_period: 60s
start_interval: 2s
retries: 3
depends_on:
mongodb-staging:
condition: service_healthy
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
mongodb-staging:
image: mongo:8.2
container_name: mongodb-staging
restart: always
command: ["mongod", "--quiet", "--bind_ip_all"]
volumes:
- ./mongo/data-staging:/data/db
env_file:
- mongo-staging.env
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')", "--quiet"]
interval: 5s
timeout: 30s
start_period: 0s
start_interval: 1s
retries: 30
# Shared utils
capture:
image: ghcr.io/bluewave-labs/capture:latest
container_name: capture
restart: unless-stopped
ports:
- "59232:59232"
environment:
- API_SECRET=my_secret
- GIN_MODE=release
volumes:
- /etc/os-release:/etc/os-release:ro
@@ -19,7 +19,7 @@ server {
}
# --- PRODUCTION: demo.checkmate.so ---
# --- DEMO: demo.checkmate.so ---
server {
listen 443 ssl;
server_name demo.checkmate.so;
@@ -31,25 +31,24 @@ server {
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
# Passes traffic to the prod client on port 80
proxy_pass http://client-prod:80;
# The mono image serves both the SPA and the API
proxy_pass http://checkmate-demo:52345;
}
}
# --- STAGING: staging.checkmate.so ---
server {
listen 443 ssl;
server_name staging.checkmate.so;
server {
listen 443 ssl;
server_name staging.checkmate.so;
ssl_certificate /etc/nginx/ssl/live/staging.checkmate.so/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/staging.checkmate.so/privkey.pem;
ssl_certificate /etc/nginx/ssl/live/staging.checkmate.so/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/staging.checkmate.so/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
# Passes traffic to the staging client on port 80
proxy_pass http://client-staging:80;
}
}
location / {
# The mono image serves both the SPA and the API
proxy_pass http://checkmate-staging:52345;
}
}
+1 -1
View File
@@ -87,7 +87,7 @@
اطّلع على تعليمات التثبيت في [بوابة وثائق Checkmate](https://checkmate.so/docs).
بدلاً من ذلك، يمكنك استخدام [Coolify](https://coolify.io/)، أو [Elestio](https://elest.io/open-source/checkmate)، أو [K8s](./charts/helm/checkmate/INSTALLATION.md)، أو [Sive Host](https://sive.host) (جنوب أفريقيا)، أو [Cloudzy](https://cloudzy.com/marketplace/checkmate)، أو [Pikapods](https://www.pikapods.com/) لتشغيل نسخة من Checkmate بسرعة. إن أردت مراقبة البنية التحتية لخوادمك، ستحتاج إلى [وكيل Capture](https://github.com/bluewave-labs/capture). يحتوي مستودع Capture أيضًا على تعليمات التثبيت.
بدلاً من ذلك، يمكنك استخدام [Coolify](https://coolify.io/)، أو [Elestio](https://elest.io/open-source/checkmate)، أو [K8s](../../charts/helm/checkmate/INSTALLATION.md)، أو [Sive Host](https://sive.host) (جنوب أفريقيا)، أو [Cloudzy](https://cloudzy.com/marketplace/checkmate)، أو [Pikapods](https://www.pikapods.com/) لتشغيل نسخة من Checkmate بسرعة. إن أردت مراقبة البنية التحتية لخوادمك، ستحتاج إلى [وكيل Capture](https://github.com/bluewave-labs/capture). يحتوي مستودع Capture أيضًا على تعليمات التثبيت.
### استخدام شهادة CA مخصصة
+1 -1
View File
@@ -85,7 +85,7 @@ Pots trobar les instruccions d'ús [aquí](https://checkmate.so/docs).
Consulta les instruccions d'instal·lació al [portal de documentació de Checkmate](https://checkmate.so/docs).
Alternativament, també pots utilitzar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sud-àfrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) per posar en marxa ràpidament una instància de Checkmate. Si vols monitoritzar la infraestructura de servidors, necessitaràs l'[agent Capture](https://github.com/bluewave-labs/capture). El repositori de Capture també conté les instruccions d'instal·lació.
Alternativament, també pots utilitzar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sud-àfrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) per posar en marxa ràpidament una instància de Checkmate. Si vols monitoritzar la infraestructura de servidors, necessitaràs l'[agent Capture](https://github.com/bluewave-labs/capture). El repositori de Capture també conté les instruccions d'instal·lació.
### Utilitzar una CA personalitzada
+1 -1
View File
@@ -85,7 +85,7 @@ Pokyny k použití najdete [zde](https://checkmate.so/docs).
Pokyny k instalaci najdete v [dokumentačním portálu Checkmate](https://checkmate.so/docs).
Případně můžete použít [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Jižní Afrika), [Cloudzy](https://cloudzy.com/marketplace/checkmate) nebo [Pikapods](https://www.pikapods.com/) pro rychlé spuštění instance Checkmate. Pokud chcete monitorovat infrastrukturu serverů, budete potřebovat [agenta Capture](https://github.com/bluewave-labs/capture). Repozitář Capture obsahuje také pokyny k instalaci.
Případně můžete použít [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Jižní Afrika), [Cloudzy](https://cloudzy.com/marketplace/checkmate) nebo [Pikapods](https://www.pikapods.com/) pro rychlé spuštění instance Checkmate. Pokud chcete monitorovat infrastrukturu serverů, budete potřebovat [agenta Capture](https://github.com/bluewave-labs/capture). Repozitář Capture obsahuje také pokyny k instalaci.
### Použití vlastní CA
+1 -1
View File
@@ -82,7 +82,7 @@ Die Nutzungsanleitung findest du [hier](https://checkmate.so/docs).
Die Installationsanleitung findest du im [Dokumentationsportal von Checkmate](https://checkmate.so/docs).
Alternativ kannst du [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Südafrika), [Cloudzy](https://cloudzy.com/marketplace/checkmate) oder [Pikapods](https://www.pikapods.com/) nutzen, um schnell eine Checkmate-Instanz hochzuziehen. Für das Monitoring deiner Server-Infrastruktur brauchst du den [Capture-Agenten](https://github.com/bluewave-labs/capture); dessen Repository enthält ebenfalls eine Installationsanleitung.
Alternativ kannst du [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Südafrika), [Cloudzy](https://cloudzy.com/marketplace/checkmate) oder [Pikapods](https://www.pikapods.com/) nutzen, um schnell eine Checkmate-Instanz hochzuziehen. Für das Monitoring deiner Server-Infrastruktur brauchst du den [Capture-Agenten](https://github.com/bluewave-labs/capture); dessen Repository enthält ebenfalls eine Installationsanleitung.
### Eigene CA verwenden
+1 -1
View File
@@ -82,7 +82,7 @@ Las instrucciones de uso están disponibles [aquí](https://checkmate.so/docs).
Consulta las instrucciones de instalación en el [portal de documentación de Checkmate](https://checkmate.so/docs).
También puedes utilizar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sudáfrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) para levantar rápidamente una instancia de Checkmate. Si quieres monitorizar la infraestructura de tus servidores, necesitarás el [agente Capture](https://github.com/bluewave-labs/capture). El repositorio de Capture también incluye las instrucciones de instalación.
También puedes utilizar [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sudáfrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) para levantar rápidamente una instancia de Checkmate. Si quieres monitorizar la infraestructura de tus servidores, necesitarás el [agente Capture](https://github.com/bluewave-labs/capture). El repositorio de Capture también incluye las instrucciones de instalación.
### Uso de una CA personalizada
+1 -1
View File
@@ -85,7 +85,7 @@ Käyttöohjeet löytyvät [täältä](https://checkmate.so/docs).
Asennusohjeet löytyvät [Checkmaten dokumentaatioportaalista](https://checkmate.so/docs).
Vaihtoehtoisesti voit käyttää [Coolifya](https://coolify.io/), [Elestiota](https://elest.io/open-source/checkmate), [K8s:ää](./charts/helm/checkmate/INSTALLATION.md), [Sive Hostia](https://sive.host) (Etelä-Afrikka), [Cloudzya](https://cloudzy.com/marketplace/checkmate) tai [Pikapodsia](https://www.pikapods.com/) Checkmate-instanssin nopeaan käynnistämiseen. Jos haluat valvoa palvelininfrastruktuuriasi, tarvitset [Capture-agentin](https://github.com/bluewave-labs/capture). Capturen repositorio sisältää myös sen asennusohjeet.
Vaihtoehtoisesti voit käyttää [Coolifya](https://coolify.io/), [Elestiota](https://elest.io/open-source/checkmate), [K8s:ää](../../charts/helm/checkmate/INSTALLATION.md), [Sive Hostia](https://sive.host) (Etelä-Afrikka), [Cloudzya](https://cloudzy.com/marketplace/checkmate) tai [Pikapodsia](https://www.pikapods.com/) Checkmate-instanssin nopeaan käynnistämiseen. Jos haluat valvoa palvelininfrastruktuuriasi, tarvitset [Capture-agentin](https://github.com/bluewave-labs/capture). Capturen repositorio sisältää myös sen asennusohjeet.
### Mukautetun CA:n käyttö
+1 -1
View File
@@ -82,7 +82,7 @@ Les instructions d'utilisation sont disponibles [ici](https://checkmate.so/docs)
Consultez les instructions d'installation dans le [portail de documentation Checkmate](https://checkmate.so/docs).
Vous pouvez également utiliser [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Afrique du Sud), [Cloudzy](https://cloudzy.com/marketplace/checkmate) ou [Pikapods](https://www.pikapods.com/) pour démarrer rapidement une instance Checkmate. Pour surveiller votre infrastructure serveur, vous aurez besoin de l'[agent Capture](https://github.com/bluewave-labs/capture). Le dépôt Capture contient également les instructions d'installation.
Vous pouvez également utiliser [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Afrique du Sud), [Cloudzy](https://cloudzy.com/marketplace/checkmate) ou [Pikapods](https://www.pikapods.com/) pour démarrer rapidement une instance Checkmate. Pour surveiller votre infrastructure serveur, vous aurez besoin de l'[agent Capture](https://github.com/bluewave-labs/capture). Le dépôt Capture contient également les instructions d'installation.
### Utiliser une autorité de certification personnalisée
+1 -1
View File
@@ -82,7 +82,7 @@ Le istruzioni per l'uso sono disponibili [qui](https://checkmate.so/docs).
Consulta le istruzioni di installazione nel [portale della documentazione di Checkmate](https://checkmate.so/docs).
In alternativa, puoi usare [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](./charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sudafrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) per creare rapidamente un'istanza di Checkmate. Se desideri monitorare l'infrastruttura dei tuoi server, ti servirà l'[agente Capture](https://github.com/bluewave-labs/capture). Anche il repository di Capture contiene le istruzioni di installazione.
In alternativa, puoi usare [Coolify](https://coolify.io/), [Elestio](https://elest.io/open-source/checkmate), [K8s](../../charts/helm/checkmate/INSTALLATION.md), [Sive Host](https://sive.host) (Sudafrica), [Cloudzy](https://cloudzy.com/marketplace/checkmate) o [Pikapods](https://www.pikapods.com/) per creare rapidamente un'istanza di Checkmate. Se desideri monitorare l'infrastruttura dei tuoi server, ti servirà l'[agente Capture](https://github.com/bluewave-labs/capture). Anche il repository di Capture contiene le istruzioni di installazione.
### Usare una CA personalizzata
Loaded 100 of 182 files, more files were not shown because too many files have changed in this diff. Show more