Compare commits
64
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b09895098 | ||
|
|
bf255a0178 | ||
|
|
36434c1160 | ||
|
|
63cecf3447 | ||
|
|
4d9e5821a8 | ||
|
|
5433a0cf5f | ||
|
|
d485adbb54 | ||
|
|
3eadb99c5e | ||
|
|
9c04061a04 | ||
|
|
897ffd5736 | ||
|
|
368595178d | ||
|
|
924c862244 | ||
|
|
cf451416b1 | ||
|
|
6e2a64fc9f | ||
|
|
0e52cb6231 | ||
|
|
507b96164f | ||
|
|
887521c376 | ||
|
|
caee9510eb | ||
|
|
825a81d326 | ||
|
|
bd13e9d9c8 | ||
|
|
92696d3685 | ||
|
|
5120390923 | ||
|
|
0810fcbb88 | ||
|
|
15453c2d8d | ||
|
|
70f10a73d8 | ||
|
|
930c06f5ff | ||
|
|
b088a8c878 | ||
|
|
067a186765 | ||
|
|
107b5cbd96 | ||
|
|
7fdd51c072 | ||
|
|
2331035da0 | ||
|
|
fd4edb7227 | ||
|
|
538b0df7e9 | ||
|
|
9f79feec8e | ||
|
|
fe703199f5 | ||
|
|
800080fd06 | ||
|
|
c1bcd9b206 | ||
|
|
5d55750b7b | ||
|
|
4f398e98d3 | ||
|
|
242e853bf0 | ||
|
|
523bf2253c | ||
|
|
f92dc835b7 | ||
|
|
0b0d412187 | ||
|
|
77b817778b | ||
|
|
eddb9a82a8 | ||
|
|
9459edce00 | ||
|
|
eaf1064413 | ||
|
|
dae6f9a570 | ||
|
|
9fa45c5871 | ||
|
|
2810cd3562 | ||
|
|
f4177baed5 | ||
|
|
5feb666bdb | ||
|
|
ceacaa5499 | ||
|
|
91343f996b | ||
|
|
312961e8c9 | ||
|
|
0475f194e9 | ||
|
|
bbb051406f | ||
|
|
40a7599388 | ||
|
|
dffce2709e | ||
|
|
62031a0ab1 | ||
|
|
ef175950b2 | ||
|
|
6d91efecad | ||
|
|
f7d3bcb696 | ||
|
|
4a093e2b97 |
No files matched your search
@@ -0,0 +1,6 @@
|
|||||||
|
**/node_modules
|
||||||
|
**/dist
|
||||||
|
**/.env
|
||||||
|
**/*.env
|
||||||
|
.git
|
||||||
|
docker/dev/mongo/data
|
||||||
@@ -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 }}
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -35,9 +35,9 @@ npm run format # Prettier formatting
|
|||||||
|
|
||||||
### Docker Development
|
### Docker Development
|
||||||
```bash
|
```bash
|
||||||
cd docker/dev
|
docker build -f docker/Dockerfile -t checkmate . # build the mono image (server + built client)
|
||||||
./build_images.sh
|
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:6.0
|
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
|
## Environment Setup
|
||||||
@@ -51,6 +51,7 @@ TOKEN_TTL="99d"
|
|||||||
ORIGIN="localhost"
|
ORIGIN="localhost"
|
||||||
LOG_LEVEL="debug"
|
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`
|
### Client `.env`
|
||||||
```env
|
```env
|
||||||
|
|||||||
+37
-30
@@ -88,34 +88,10 @@ cd Checkmate
|
|||||||
|
|
||||||
#### Step 2: Set Up Docker Containers (MongoDB)
|
#### 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:
|
Run MongoDB container:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:6.0
|
docker run -d -p 27017:27017 -v uptime_mongo_data:/data/db --name uptime_database_mongo mongo:8.0
|
||||||
```
|
|
||||||
|
|
||||||
Navigate back to the root directory:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd ../..
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 3: Set Up the Backend (Server)
|
#### Step 3: Set Up the Backend (Server)
|
||||||
@@ -148,10 +124,12 @@ LOG_LEVEL="debug"
|
|||||||
- `CLIENT_HOST`: Frontend URL (default: http://localhost:5173)
|
- `CLIENT_HOST`: Frontend URL (default: http://localhost:5173)
|
||||||
- `JWT_SECRET`: Secret key for JWT tokens (change to something secure)
|
- `JWT_SECRET`: Secret key for JWT tokens (change to something secure)
|
||||||
- `DB_CONNECTION_STRING`: MongoDB connection URL
|
- `DB_CONNECTION_STRING`: MongoDB connection URL
|
||||||
- `ORIGIN`: Origin for CORS purposes
|
- `ORIGIN`: Origin for CORS purposes (optional)
|
||||||
- `TOKEN_TTL`: Token time to live (in vercel/ms format)
|
- `TOKEN_TTL`: Token time to live in vercel/ms format (optional, default: `99d`)
|
||||||
- `LOG_LEVEL`: Debug level (debug, info, warn, error)
|
- `LOG_LEVEL`: Debug level: debug, info, warn, error (optional, default: `debug`)
|
||||||
- `QUEUE_TYPE`: Job queue implementation (`superSimpleQueue` or `lessSimpleQueue`, optional, default: `superSimpleQueue`)
|
- `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:
|
Start the backend server:
|
||||||
|
|
||||||
@@ -227,7 +205,7 @@ docker rm uptime_database_mongo
|
|||||||
|
|
||||||
**Port already in use:**
|
**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
|
- Stop the conflicting service or change the port in `.env` files
|
||||||
|
|
||||||
**MongoDB connection issues:**
|
**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).
|
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?
|
### Submit a pull request?
|
||||||
|
|
||||||
Follow the [pull request checklist](#pull-request-checklist). Your PR should:
|
Follow the [pull request checklist](#pull-request-checklist). Your PR should:
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
🇪🇸 <a href="docs/translations/README.es.md">Español</a> |
|
🇪🇸 <a href="docs/translations/README.es.md">Español</a> |
|
||||||
🇫🇮 <a href="docs/translations/README.fi.md">Suomi</a> |
|
🇫🇮 <a href="docs/translations/README.fi.md">Suomi</a> |
|
||||||
🇫🇷 <a href="docs/translations/README.fr.md">Français</a> |
|
🇫🇷 <a href="docs/translations/README.fr.md">Français</a> |
|
||||||
|
🇮🇹 <a href="docs/translations/README.it.md">Italiano</a> |
|
||||||
🇯🇵 <a href="docs/translations/README.ja.md">日本語</a> |
|
🇯🇵 <a href="docs/translations/README.ja.md">日本語</a> |
|
||||||
🇧🇷 <a href="docs/translations/README.pt-BR.md">Português (Brasil)</a> |
|
🇧🇷 <a href="docs/translations/README.pt-BR.md">Português (Brasil)</a> |
|
||||||
🇷🇺 <a href="docs/translations/README.ru.md">Русский</a> |
|
🇷🇺 <a href="docs/translations/README.ru.md">Русский</a> |
|
||||||
@@ -79,7 +80,37 @@ Usage instructions can be found [here](https://checkmate.so/docs).
|
|||||||
<a id="installation"></a>
|
<a id="installation"></a>
|
||||||
## Installation
|
## 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.
|
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.
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,8 @@ name: checkmate-chart
|
|||||||
description: A Helm chart for Checkmate App
|
description: A Helm chart for Checkmate App
|
||||||
type: application
|
type: application
|
||||||
version: 0.2.0
|
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)
|
appVersion: "v3.8.1" # "v" prefix: published image tags are v-prefixed (ghcr.io/.../checkmate-*:v3.8.1)
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
VITE_APP_API_BASE_URL=UPTIME_APP_API_BASE_URL
|
# Production builds use same-origin defaults: API at /api/v1, client host from
|
||||||
VITE_APP_API_V2_BASE_URL=UPTIME_APP_API_V2_BASE_URL
|
# window.location.origin. The empty values below override any local .env so a
|
||||||
VITE_APP_CLIENT_HOST=UPTIME_APP_CLIENT_HOST
|
# production build never bakes in a developer's localhost URLs.
|
||||||
VITE_APP_LOG_LEVEL=UPTIME_APP_LOG_LEVEL
|
VITE_APP_API_BASE_URL=
|
||||||
|
VITE_APP_CLIENT_HOST=
|
||||||
|
VITE_APP_LOG_LEVEL=
|
||||||
@@ -28,5 +28,4 @@ dist-ssr
|
|||||||
|
|
||||||
# Scripts
|
# Scripts
|
||||||
*.sh
|
*.sh
|
||||||
!env.sh
|
|
||||||
.env.development
|
.env.development
|
||||||
@@ -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
|
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<title>Checkmate</title>
|
<title>Checkmate</title>
|
||||||
|
<script src="/config.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
Generated
+2
-22
@@ -92,7 +92,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
|
||||||
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
|
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/code-frame": "^7.29.7",
|
"@babel/code-frame": "^7.29.7",
|
||||||
"@babel/generator": "^7.29.7",
|
"@babel/generator": "^7.29.7",
|
||||||
@@ -408,7 +407,6 @@
|
|||||||
"node_modules/@emotion/react": {
|
"node_modules/@emotion/react": {
|
||||||
"version": "11.14.0",
|
"version": "11.14.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
"@emotion/babel-plugin": "^11.13.5",
|
"@emotion/babel-plugin": "^11.13.5",
|
||||||
@@ -446,7 +444,6 @@
|
|||||||
"node_modules/@emotion/styled": {
|
"node_modules/@emotion/styled": {
|
||||||
"version": "11.14.1",
|
"version": "11.14.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.18.3",
|
"@babel/runtime": "^7.18.3",
|
||||||
"@emotion/babel-plugin": "^11.13.5",
|
"@emotion/babel-plugin": "^11.13.5",
|
||||||
@@ -1226,7 +1223,6 @@
|
|||||||
"node_modules/@mui/material": {
|
"node_modules/@mui/material": {
|
||||||
"version": "7.3.7",
|
"version": "7.3.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
"@mui/core-downloads-tracker": "^7.3.7",
|
"@mui/core-downloads-tracker": "^7.3.7",
|
||||||
@@ -1331,7 +1327,6 @@
|
|||||||
"node_modules/@mui/system": {
|
"node_modules/@mui/system": {
|
||||||
"version": "7.3.7",
|
"version": "7.3.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.28.4",
|
"@babel/runtime": "^7.28.4",
|
||||||
"@mui/private-theming": "^7.3.7",
|
"@mui/private-theming": "^7.3.7",
|
||||||
@@ -2376,7 +2371,6 @@
|
|||||||
"version": "24.5.2",
|
"version": "24.5.2",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.12.0"
|
"undici-types": "~7.12.0"
|
||||||
}
|
}
|
||||||
@@ -2392,7 +2386,6 @@
|
|||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.3.27",
|
"version": "18.3.27",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"csstype": "^3.2.2"
|
"csstype": "^3.2.2"
|
||||||
@@ -2483,7 +2476,6 @@
|
|||||||
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
"integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "7.18.0",
|
"@typescript-eslint/scope-manager": "7.18.0",
|
||||||
"@typescript-eslint/types": "7.18.0",
|
"@typescript-eslint/types": "7.18.0",
|
||||||
@@ -2764,7 +2756,6 @@
|
|||||||
"version": "8.15.0",
|
"version": "8.15.0",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"acorn": "bin/acorn"
|
"acorn": "bin/acorn"
|
||||||
},
|
},
|
||||||
@@ -3121,7 +3112,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.10.42",
|
"baseline-browser-mapping": "^2.10.42",
|
||||||
"caniuse-lite": "^1.0.30001800",
|
"caniuse-lite": "^1.0.30001800",
|
||||||
@@ -3565,8 +3555,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/dayjs": {
|
"node_modules/dayjs": {
|
||||||
"version": "1.11.13",
|
"version": "1.11.13",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/debug": {
|
"node_modules/debug": {
|
||||||
"version": "4.4.3",
|
"version": "4.4.3",
|
||||||
@@ -3965,7 +3954,6 @@
|
|||||||
"version": "8.57.1",
|
"version": "8.57.1",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.2.0",
|
||||||
"@eslint-community/regexpp": "^4.6.1",
|
"@eslint-community/regexpp": "^4.6.1",
|
||||||
@@ -4778,7 +4766,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.27.6"
|
"@babel/runtime": "^7.27.6"
|
||||||
},
|
},
|
||||||
@@ -5590,7 +5577,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.19.0.tgz",
|
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-5.19.0.tgz",
|
||||||
"integrity": "sha512-REhYUN8gNP3HlcIZS6QU2uy8iovl31cXsrNDkCcqWSQbCkcpdYLczqDz5PVIwNH42UQNyvukjes/RoHPDrOUmQ==",
|
"integrity": "sha512-REhYUN8gNP3HlcIZS6QU2uy8iovl31cXsrNDkCcqWSQbCkcpdYLczqDz5PVIwNH42UQNyvukjes/RoHPDrOUmQ==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/geojson-rewind": "^0.5.2",
|
"@mapbox/geojson-rewind": "^0.5.2",
|
||||||
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
"@mapbox/jsonlint-lines-primitives": "^2.0.2",
|
||||||
@@ -6372,7 +6358,6 @@
|
|||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "18.3.1",
|
"version": "18.3.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"loose-envify": "^1.1.0",
|
"loose-envify": "^1.1.0",
|
||||||
"scheduler": "^0.23.2"
|
"scheduler": "^0.23.2"
|
||||||
@@ -6384,7 +6369,6 @@
|
|||||||
"node_modules/react-hook-form": {
|
"node_modules/react-hook-form": {
|
||||||
"version": "7.71.1",
|
"version": "7.71.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0.0"
|
"node": ">=18.0.0"
|
||||||
},
|
},
|
||||||
@@ -6588,8 +6572,7 @@
|
|||||||
},
|
},
|
||||||
"node_modules/redux": {
|
"node_modules/redux": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT"
|
||||||
"peer": true
|
|
||||||
},
|
},
|
||||||
"node_modules/redux-persist": {
|
"node_modules/redux-persist": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
@@ -6739,7 +6722,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
|
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
|
||||||
"integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
|
"integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/estree": "1.0.9"
|
"@types/estree": "1.0.9"
|
||||||
},
|
},
|
||||||
@@ -7581,7 +7563,6 @@
|
|||||||
"version": "5.9.3",
|
"version": "5.9.3",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"peer": true,
|
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
@@ -7719,7 +7700,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/vite/-/vite-6.4.3.tgz",
|
||||||
"integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
|
"integrity": "sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"peer": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esbuild": "^0.25.0",
|
"esbuild": "^0.25.0",
|
||||||
"fdir": "^6.4.4",
|
"fdir": "^6.4.4",
|
||||||
|
|||||||
@@ -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à",
|
ca: "Català",
|
||||||
es: "Español",
|
es: "Español",
|
||||||
fr: "Français",
|
fr: "Français",
|
||||||
|
it: "Italiano",
|
||||||
"pt-BR": "Português (BR)",
|
"pt-BR": "Português (BR)",
|
||||||
|
pl: "Polski",
|
||||||
cs: "Čeština",
|
cs: "Čeština",
|
||||||
fi: "Suomi",
|
fi: "Suomi",
|
||||||
tr: "Türkçe",
|
tr: "Türkçe",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const RadialAvgResponse = ({ avg, max }: { avg: number; max: number }) =>
|
|||||||
const msg: Record<string, string> = {
|
const msg: Record<string, string> = {
|
||||||
success: "Excellent",
|
success: "Excellent",
|
||||||
warning: "Average",
|
warning: "Average",
|
||||||
danger: "Poor",
|
error: "Poor",
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ import { useInviteForm } from "@/Hooks/useInviteForm";
|
|||||||
import type { InviteFormData } from "@/Validation/invite";
|
import type { InviteFormData } from "@/Validation/invite";
|
||||||
import { usePost } from "@/Hooks/UseApi";
|
import { usePost } from "@/Hooks/UseApi";
|
||||||
import { LAYOUT } from "@/Utils/Theme/constants";
|
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 {
|
interface InviteResponse {
|
||||||
token: string;
|
token: string;
|
||||||
@@ -56,7 +57,7 @@ export const InviteTeamMemberDialog = ({
|
|||||||
const result = await generateToken("/invite", data);
|
const result = await generateToken("/invite", data);
|
||||||
if (result?.data?.token) {
|
if (result?.data?.token) {
|
||||||
const token = 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);
|
setInviteLink(link);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -63,10 +63,20 @@ const getChartConfigs = (
|
|||||||
return configs;
|
return configs;
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasAnyNetworkTraffic = (checks: HardwareCheckStats[]): boolean =>
|
// Loopback / bridge names Capture sees when it can only observe the container's
|
||||||
checks.some((c) =>
|
// own network namespace. When ALL reported interfaces match this set we assume
|
||||||
c.net?.some((iface) => iface.bytesSentPerSecond > 0 || iface.deltaBytesRecv > 0)
|
// the "no real interfaces visible" case and surface the notice.
|
||||||
);
|
const CONTAINER_ONLY_IFACE_NAMES = new Set(["lo", "lo0", "docker0"]);
|
||||||
|
|
||||||
|
const onlyContainerVisibleInterfaces = (checks: HardwareCheckStats[]): boolean => {
|
||||||
|
const named = new Set<string>();
|
||||||
|
checks.forEach((c) => c.net?.forEach((iface) => named.add(iface.name)));
|
||||||
|
if (named.size === 0) return false;
|
||||||
|
for (const name of named) {
|
||||||
|
if (!CONTAINER_ONLY_IFACE_NAMES.has(name)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
export const InfraNetworkCharts = ({
|
export const InfraNetworkCharts = ({
|
||||||
checks,
|
checks,
|
||||||
@@ -82,13 +92,14 @@ export const InfraNetworkCharts = ({
|
|||||||
() => getChartConfigs(theme, checks, t),
|
() => getChartConfigs(theme, checks, t),
|
||||||
[theme, checks, t]
|
[theme, checks, t]
|
||||||
);
|
);
|
||||||
const showNoTrafficNotice = chartConfigs.length > 0 && !hasAnyNetworkTraffic(checks);
|
const showLoopbackOnlyNotice =
|
||||||
|
chartConfigs.length > 0 && onlyContainerVisibleInterfaces(checks);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap={theme.spacing(LAYOUT.XS)}>
|
<Stack gap={theme.spacing(LAYOUT.XS)}>
|
||||||
{showNoTrafficNotice && (
|
{showLoopbackOnlyNotice && (
|
||||||
<NoticeBanner severity="warning">
|
<NoticeBanner severity="warning">
|
||||||
{t("pages.infrastructure.charts.labels.netNoTraffic")}
|
{t("pages.infrastructure.charts.labels.loopbackOnlyNotice")}
|
||||||
</NoticeBanner>
|
</NoticeBanner>
|
||||||
)}
|
)}
|
||||||
<Grid
|
<Grid
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
getStatusPagePublicUrl,
|
getStatusPagePublicUrl,
|
||||||
isCustomDomainHost,
|
isCustomDomainHost,
|
||||||
} from "@/Utils/statusPageUrl";
|
} from "@/Utils/statusPageUrl";
|
||||||
|
import { cssReferencesExternalResource } from "@/Utils/customCss";
|
||||||
import { HeaderStatusPageControls } from "@/Pages/StatusPage/Status/Components/HeaderStatusPageControls";
|
import { HeaderStatusPageControls } from "@/Pages/StatusPage/Status/Components/HeaderStatusPageControls";
|
||||||
import { StatusPageThemeProvider } from "@/Pages/StatusPage/Status/themes/StatusPageThemeProvider";
|
import { StatusPageThemeProvider } from "@/Pages/StatusPage/Status/themes/StatusPageThemeProvider";
|
||||||
import {
|
import {
|
||||||
@@ -132,13 +133,19 @@ const StatusPageView = () => {
|
|||||||
// Public route: render directly on the viewport, themed background covers everything.
|
// Public route: render directly on the viewport, themed background covers everything.
|
||||||
if (isPublic) {
|
if (isPublic) {
|
||||||
const themeConfig = THEME_CONFIGS[resolveStatusPageTheme(statusPage.theme)];
|
const themeConfig = THEME_CONFIGS[resolveStatusPageTheme(statusPage.theme)];
|
||||||
|
const customCss =
|
||||||
|
statusPage.customCSS && !cssReferencesExternalResource(statusPage.customCSS)
|
||||||
|
? statusPage.customCSS
|
||||||
|
: "";
|
||||||
return (
|
return (
|
||||||
<StatusPageThemeProvider
|
<StatusPageThemeProvider
|
||||||
theme={statusPage.theme}
|
theme={statusPage.theme}
|
||||||
themeMode={statusPage.themeMode}
|
themeMode={statusPage.themeMode}
|
||||||
timezone={statusPage.timezone}
|
timezone={statusPage.timezone}
|
||||||
|
brandColor={statusPage.color}
|
||||||
paintBody
|
paintBody
|
||||||
>
|
>
|
||||||
|
{customCss && <style>{customCss}</style>}
|
||||||
<BaseStatusPage
|
<BaseStatusPage
|
||||||
statusPage={statusPage}
|
statusPage={statusPage}
|
||||||
monitors={monitors}
|
monitors={monitors}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
type ReactNode,
|
type ReactNode,
|
||||||
} from "react";
|
} from "react";
|
||||||
|
import { alpha, darken } from "@mui/material/styles";
|
||||||
import {
|
import {
|
||||||
DEFAULT_STATUS_PAGE_THEME,
|
DEFAULT_STATUS_PAGE_THEME,
|
||||||
resolveStatusPageTheme,
|
resolveStatusPageTheme,
|
||||||
@@ -36,6 +37,15 @@ interface Props {
|
|||||||
theme?: StatusPageTheme;
|
theme?: StatusPageTheme;
|
||||||
themeMode?: StatusPageThemeMode;
|
themeMode?: StatusPageThemeMode;
|
||||||
timezone?: string;
|
timezone?: string;
|
||||||
|
/**
|
||||||
|
* Brand color picked in the status-page appearance settings. When
|
||||||
|
* provided, it feeds `tokens.brand` / `brandStrong` / `brandSoft`,
|
||||||
|
* which theme styles use for accent surfaces (hero, active tabs,
|
||||||
|
* links). It does NOT recolor the semantic `up`/OK status color, so
|
||||||
|
* a red or orange brand cannot make the "all operational" indicator
|
||||||
|
* signal downtime.
|
||||||
|
*/
|
||||||
|
brandColor?: string;
|
||||||
/**
|
/**
|
||||||
* When true, paint the document body with the theme background so it
|
* When true, paint the document body with the theme background so it
|
||||||
* covers beyond the provider's wrapper (useful on the public route
|
* covers beyond the provider's wrapper (useful on the public route
|
||||||
@@ -54,10 +64,32 @@ interface Props {
|
|||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const HEX_COLOR = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
|
||||||
|
|
||||||
|
// Resolve the brand triple that theme styles read from. A customer's
|
||||||
|
// picked color (when valid) overrides the theme's default; otherwise
|
||||||
|
// the theme's own `brand*` values win, and finally we fall back to the
|
||||||
|
// `up*` triple so unmigrated theme styles have something to consume.
|
||||||
|
const resolveBrandTokens = (
|
||||||
|
tokens: StatusPageThemeTokens,
|
||||||
|
brandColor: string | undefined
|
||||||
|
): StatusPageThemeTokens => {
|
||||||
|
const validOverride = brandColor && HEX_COLOR.test(brandColor) ? brandColor : undefined;
|
||||||
|
const brand = validOverride ?? tokens.brand ?? tokens.up;
|
||||||
|
const brandStrong = validOverride
|
||||||
|
? darken(validOverride, 0.2)
|
||||||
|
: (tokens.brandStrong ?? tokens.upStrong);
|
||||||
|
const brandSoft = validOverride
|
||||||
|
? alpha(validOverride, 0.15)
|
||||||
|
: (tokens.brandSoft ?? tokens.upSoft);
|
||||||
|
return { ...tokens, brand, brandStrong, brandSoft };
|
||||||
|
};
|
||||||
|
|
||||||
export const StatusPageThemeProvider = ({
|
export const StatusPageThemeProvider = ({
|
||||||
theme,
|
theme,
|
||||||
themeMode,
|
themeMode,
|
||||||
timezone,
|
timezone,
|
||||||
|
brandColor,
|
||||||
paintBody = false,
|
paintBody = false,
|
||||||
transparent = false,
|
transparent = false,
|
||||||
children,
|
children,
|
||||||
@@ -109,7 +141,11 @@ export const StatusPageThemeProvider = ({
|
|||||||
|
|
||||||
const resolvedMode: ResolvedMode =
|
const resolvedMode: ResolvedMode =
|
||||||
resolvedThemeMode === "auto" ? systemMode : resolvedThemeMode;
|
resolvedThemeMode === "auto" ? systemMode : resolvedThemeMode;
|
||||||
const tokens = themeTokens[resolvedTheme][resolvedMode];
|
const baseTokens = themeTokens[resolvedTheme][resolvedMode];
|
||||||
|
const tokens = useMemo(
|
||||||
|
() => resolveBrandTokens(baseTokens, brandColor),
|
||||||
|
[baseTokens, brandColor]
|
||||||
|
);
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ export const refinedStyles = (
|
|||||||
width: 28,
|
width: 28,
|
||||||
height: 28,
|
height: 28,
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
background: tokens.up,
|
background: tokens.brand,
|
||||||
display: "grid",
|
display: "grid",
|
||||||
placeItems: "center",
|
placeItems: "center",
|
||||||
color: "#fff",
|
color: "#fff",
|
||||||
@@ -191,16 +191,16 @@ export const refinedStyles = (
|
|||||||
whiteSpace: "nowrap",
|
whiteSpace: "nowrap",
|
||||||
textAlign: "center",
|
textAlign: "center",
|
||||||
border: 0,
|
border: 0,
|
||||||
background: active ? tokens.upSoft : "transparent",
|
background: active ? tokens.brandSoft : "transparent",
|
||||||
fontFamily: "inherit",
|
fontFamily: "inherit",
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
padding: { xs: "5px 6px", md: "5px 14px" },
|
padding: { xs: "5px 6px", md: "5px 14px" },
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
color: active ? tokens.up : tokens.textMuted,
|
color: active ? tokens.brand : tokens.textMuted,
|
||||||
borderRadius: "5px",
|
borderRadius: "5px",
|
||||||
transition: "background 0.15s ease, color 0.15s ease",
|
transition: "background 0.15s ease, color 0.15s ease",
|
||||||
fontWeight: active ? 600 : 500,
|
fontWeight: active ? 600 : 500,
|
||||||
"&:hover": { color: active ? tokens.up : tokens.text },
|
"&:hover": { color: active ? tokens.brand : tokens.text },
|
||||||
}),
|
}),
|
||||||
|
|
||||||
monitorList: {
|
monitorList: {
|
||||||
@@ -259,9 +259,9 @@ export const refinedStyles = (
|
|||||||
},
|
},
|
||||||
pillHardware: {
|
pillHardware: {
|
||||||
...pillBase,
|
...pillBase,
|
||||||
color: tokens.up,
|
color: tokens.brand,
|
||||||
border: `1px solid ${tokens.border}`,
|
border: `1px solid ${tokens.border}`,
|
||||||
background: tokens.upSoft,
|
background: tokens.brandSoft,
|
||||||
},
|
},
|
||||||
monitorUrl: {
|
monitorUrl: {
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
@@ -382,11 +382,11 @@ export const refinedStyles = (
|
|||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
mt: "40px",
|
mt: "40px",
|
||||||
"& a": {
|
"& a": {
|
||||||
color: tokens.up,
|
color: tokens.brand,
|
||||||
textDecoration: "underline",
|
textDecoration: "underline",
|
||||||
textUnderlineOffset: "3px",
|
textUnderlineOffset: "3px",
|
||||||
fontWeight: 600,
|
fontWeight: 600,
|
||||||
"&:hover": { color: tokens.upStrong || tokens.up },
|
"&:hover": { color: tokens.brandStrong },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ export interface StatusPageThemeTokens {
|
|||||||
up: string;
|
up: string;
|
||||||
upStrong: string;
|
upStrong: string;
|
||||||
upSoft: string;
|
upSoft: string;
|
||||||
|
// Accent used for brand-tinted surfaces (hero background, active tab
|
||||||
|
// underline, "view all" links). Distinct from `up` so a red/orange
|
||||||
|
// brand color cannot recolor the semantic OK/up status indicators.
|
||||||
|
// Themes leave these undefined by default; the provider falls back
|
||||||
|
// to `up`/`upStrong`/`upSoft` so styles have a value to consume.
|
||||||
|
brand?: string;
|
||||||
|
brandStrong?: string;
|
||||||
|
brandSoft?: string;
|
||||||
degraded: string;
|
degraded: string;
|
||||||
degradedSoft: string;
|
degradedSoft: string;
|
||||||
down: string;
|
down: string;
|
||||||
|
|||||||
Vendored
+2
-1
@@ -3,7 +3,8 @@
|
|||||||
declare const __APP_VERSION__: string;
|
declare const __APP_VERSION__: string;
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
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";
|
readonly VITE_APP_LOG_LEVEL?: "debug" | "info" | "warn" | "error";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import type { AxiosError } from "axios";
|
import type { AxiosError } from "axios";
|
||||||
import type { AxiosRequestConfig, AxiosResponse } 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({
|
const api = axios.create({
|
||||||
baseURL: BASE_URL,
|
baseURL: BASE_URL,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { LogLevel } from "@/Types/Log";
|
import type { LogLevel } from "@/Types/Log";
|
||||||
|
import { runtimeConfig } from "@/Utils/runtimeConfig";
|
||||||
|
|
||||||
interface LogContext {
|
interface LogContext {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@@ -25,7 +26,8 @@ interface ErrorLogData {
|
|||||||
userAgent: string;
|
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 configuredPriority = LOG_LEVEL_PRIORITY[configuredLevel];
|
||||||
|
|
||||||
const shouldLog = (level: LogLevel): boolean => {
|
const shouldLog = (level: LogLevel): boolean => {
|
||||||
|
|||||||
@@ -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__) || {};
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import { PUBLIC_STATUS_PAGE_PREFIX, type StatusPage } from "@/Types/StatusPage";
|
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 getClientOriginProtocol = (): string => {
|
||||||
const source =
|
const source =
|
||||||
|
|||||||
@@ -844,7 +844,7 @@
|
|||||||
"memory": "Memory usage",
|
"memory": "Memory usage",
|
||||||
"netBytesRecv": "{{name}} - Bytes Received",
|
"netBytesRecv": "{{name}} - Bytes Received",
|
||||||
"netBytesSent": "{{name}} - Bytes Sent",
|
"netBytesSent": "{{name}} - Bytes Sent",
|
||||||
"netNoTraffic": "Capture is reporting zero traffic on every interface. This is normal when Capture runs inside a container that can only see loopback interfaces — run Capture directly on the host to see real network activity.",
|
"loopbackOnlyNotice": "Capture is only reporting loopback or container-bridge interfaces (lo, lo0, docker0). This is normal when Capture runs inside a container that can only see its own network namespace — run Capture directly on the host to see real network activity.",
|
||||||
"temp": "Temp"
|
"temp": "Temp"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
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
|
# 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
|
# pure JS so it's arch-independent, and this avoids the esbuild host/native
|
||||||
# binary version mismatch under emulation.
|
# 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
|
WORKDIR /app/client
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ RUN npm run build
|
|||||||
# ---------------------
|
# ---------------------
|
||||||
# Backend stage
|
# Backend stage
|
||||||
# ---------------------
|
# ---------------------
|
||||||
FROM node:22-slim AS backend
|
FROM node:22-slim AS app
|
||||||
|
|
||||||
# Install ping
|
# Install ping
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
@@ -28,23 +28,18 @@ RUN apt-get update \
|
|||||||
|
|
||||||
WORKDIR /app/server
|
WORKDIR /app/server
|
||||||
|
|
||||||
COPY server/package.json ./
|
COPY server/package*.json ./
|
||||||
|
|
||||||
RUN npm install
|
RUN npm ci
|
||||||
|
|
||||||
COPY server ./
|
COPY server ./
|
||||||
|
|
||||||
RUN chmod +x ./scripts/inject-vars.sh
|
|
||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
COPY --from=frontend-build /app/client/dist ./public
|
COPY --from=frontend-build /app/client/dist ./public
|
||||||
|
|
||||||
RUN chown -R node:node ./public \
|
USER node
|
||||||
&& chown -R node:node ./dist \
|
|
||||||
&& chown -R node:node ./scripts
|
|
||||||
|
|
||||||
|
EXPOSE 52345 52346
|
||||||
|
|
||||||
EXPOSE 52345
|
CMD ["node", "dist/index.js"]
|
||||||
|
|
||||||
CMD ["sh", "-c", "./scripts/inject-vars.sh && node ./dist/index.js"]
|
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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;"]
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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"]
|
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
# Dev/Test only: Not required in production
|
||||||
# Example Docker Compose configuration for custom CA trust
|
# Example Docker Compose configuration for custom CA trust
|
||||||
# This file demonstrates how to configure Checkmate to trust custom CAs
|
# 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:
|
services:
|
||||||
server:
|
checkmate:
|
||||||
image: uptime_server:latest
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "52345:52345"
|
|
||||||
env_file:
|
|
||||||
- server.env
|
|
||||||
environment:
|
environment:
|
||||||
# Mount your custom CA certificate
|
# Mount your custom CA certificate
|
||||||
NODE_EXTRA_CA_CERTS: /certs/custom-ca.pem
|
NODE_EXTRA_CA_CERTS: /certs/custom-ca.pem
|
||||||
volumes:
|
volumes:
|
||||||
# Mount the certs directory (read-only for security)
|
# Mount the certs directory (read-only for security)
|
||||||
- ./certs:/certs:ro
|
- ./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
|
|
||||||
@@ -1,27 +1,20 @@
|
|||||||
services:
|
services:
|
||||||
client:
|
checkmate:
|
||||||
image: uptime_client:latest
|
build:
|
||||||
restart: always
|
context: ../..
|
||||||
ports:
|
dockerfile: docker/Dockerfile
|
||||||
- "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
|
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "52345:52345"
|
- "52345:52345"
|
||||||
env_file:
|
env_file:
|
||||||
- server.env
|
- server.env
|
||||||
depends_on:
|
depends_on:
|
||||||
- mongodb
|
mongodb:
|
||||||
|
condition: service_healthy
|
||||||
worker:
|
worker:
|
||||||
image: uptime_server:latest
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: docker/Dockerfile
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "52346:52346"
|
- "52346:52346"
|
||||||
@@ -43,9 +36,10 @@ services:
|
|||||||
timeout: 3s
|
timeout: 3s
|
||||||
retries: 3
|
retries: 3
|
||||||
depends_on:
|
depends_on:
|
||||||
- mongodb
|
mongodb:
|
||||||
|
condition: service_healthy
|
||||||
mongodb:
|
mongodb:
|
||||||
image: uptime_mongo:latest
|
image: mongo:8.0
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "27017:27017"
|
- "27017:27017"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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;
|
|
||||||
# }
|
|
||||||
}
|
|
||||||
@@ -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"]
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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"]
|
|
||||||
Vendored
-33
@@ -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
|
|
||||||
Vendored
-25
@@ -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"
|
|
||||||
Vendored
-22
@@ -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;"]
|
|
||||||
Vendored
-38
@@ -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
|
|
||||||
Vendored
-3
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
-35
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Vendored
-20
@@ -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"]
|
|
||||||
@@ -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:
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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,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
|
|
||||||
@@ -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();
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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"]
|
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
@@ -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,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");
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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"]
|
|
||||||
@@ -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
|
|
||||||
@@ -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"
|
|
||||||
@@ -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
|
|
||||||
@@ -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,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
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
FROM mongo
|
|
||||||
EXPOSE 27017
|
|
||||||
CMD ["mongod"]
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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"]
|
|
||||||
@@ -19,8 +19,6 @@ If you need to monitor internal HTTPS endpoints with certificates from private C
|
|||||||
### Example Configurations
|
### Example Configurations
|
||||||
The `docker/dev/` directory contains example configurations:
|
The `docker/dev/` directory contains example configurations:
|
||||||
- `docker-compose.custom-ca-example.yaml` - Example Docker Compose with custom CA
|
- `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
|
## Contributing to Documentation
|
||||||
|
|
||||||
|
|||||||
+18
-33
@@ -18,8 +18,8 @@ Add a volume mount for your CA certificate and set the environment variable:
|
|||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
server:
|
checkmate:
|
||||||
image: uptime_server:latest
|
image: ghcr.io/bluewave-labs/checkmate:latest
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "52345:52345"
|
- "52345:52345"
|
||||||
@@ -30,7 +30,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./certs:/certs:ro
|
- ./certs:/certs:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
|
||||||
- mongodb
|
- mongodb
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -52,67 +51,53 @@ For more comprehensive trust configuration, you can create a derived Dockerfile
|
|||||||
|
|
||||||
### Custom Dockerfile
|
### Custom Dockerfile
|
||||||
|
|
||||||
Create `docker/dev/server-custom-ca.Dockerfile`:
|
Create `checkmate-custom-ca.Dockerfile`:
|
||||||
|
|
||||||
```dockerfile
|
```dockerfile
|
||||||
FROM node:20-alpine
|
FROM ghcr.io/bluewave-labs/checkmate:latest
|
||||||
|
|
||||||
# Install ca-certificates for Alpine
|
USER root
|
||||||
RUN apk add --no-cache ca-certificates
|
|
||||||
|
|
||||||
WORKDIR /app
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y ca-certificates \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
COPY ./server/package*.json ./
|
# Copy your custom CA certificate (must have a .crt extension)
|
||||||
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
COPY ./server/ ./
|
|
||||||
|
|
||||||
# Copy your custom CA certificate
|
|
||||||
COPY ./certs/custom-ca.crt /usr/local/share/ca-certificates/
|
COPY ./certs/custom-ca.crt /usr/local/share/ca-certificates/
|
||||||
|
|
||||||
# Update CA certificates
|
# Update CA certificates
|
||||||
RUN 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
|
### Docker Compose Override
|
||||||
|
|
||||||
Create `docker/dev/docker-compose.custom-ca.yaml`:
|
Create `docker-compose.custom-ca.yaml`:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
server:
|
checkmate:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: server-custom-ca.Dockerfile
|
dockerfile: checkmate-custom-ca.Dockerfile
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
- "52345:52345"
|
- "52345:52345"
|
||||||
env_file:
|
env_file:
|
||||||
- server.env
|
- server.env
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
|
||||||
- mongodb
|
- 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:
|
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.
|
||||||
|
|
||||||
```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
|
|
||||||
```
|
|
||||||
|
|
||||||
## Smallstep CA Configuration
|
## Smallstep CA Configuration
|
||||||
|
|
||||||
|
|||||||
@@ -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`.
|
||||||
File renamed without changes.
@@ -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 {
|
server {
|
||||||
listen 443 ssl;
|
listen 443 ssl;
|
||||||
server_name demo.checkmate.so;
|
server_name demo.checkmate.so;
|
||||||
@@ -31,25 +31,24 @@ server {
|
|||||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
# Passes traffic to the prod client on port 80
|
# The mono image serves both the SPA and the API
|
||||||
proxy_pass http://client-prod:80;
|
proxy_pass http://checkmate-demo:52345;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- STAGING: staging.checkmate.so ---
|
# --- STAGING: staging.checkmate.so ---
|
||||||
|
server {
|
||||||
|
listen 443 ssl;
|
||||||
|
server_name staging.checkmate.so;
|
||||||
|
|
||||||
server {
|
ssl_certificate /etc/nginx/ssl/live/staging.checkmate.so/fullchain.pem;
|
||||||
listen 443 ssl;
|
ssl_certificate_key /etc/nginx/ssl/live/staging.checkmate.so/privkey.pem;
|
||||||
server_name staging.checkmate.so;
|
|
||||||
|
|
||||||
ssl_certificate /etc/nginx/ssl/live/staging.checkmate.so/fullchain.pem;
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
ssl_certificate_key /etc/nginx/ssl/live/staging.checkmate.so/privkey.pem;
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||||
|
|
||||||
ssl_protocols TLSv1.2 TLSv1.3;
|
location / {
|
||||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
# The mono image serves both the SPA and the API
|
||||||
|
proxy_pass http://checkmate-staging:52345;
|
||||||
location / {
|
}
|
||||||
# Passes traffic to the staging client on port 80
|
}
|
||||||
proxy_pass http://client-staging:80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
🇪🇸 <a href="README.es.md">Español</a> |
|
🇪🇸 <a href="README.es.md">Español</a> |
|
||||||
🇫🇮 <a href="README.fi.md">Suomi</a> |
|
🇫🇮 <a href="README.fi.md">Suomi</a> |
|
||||||
🇫🇷 <a href="README.fr.md">Français</a> |
|
🇫🇷 <a href="README.fr.md">Français</a> |
|
||||||
|
🇮🇹 <a href="README.it.md">Italiano</a> |
|
||||||
🇯🇵 <a href="README.ja.md">日本語</a> |
|
🇯🇵 <a href="README.ja.md">日本語</a> |
|
||||||
🇧🇷 <a href="README.pt-BR.md">Português (Brasil)</a> |
|
🇧🇷 <a href="README.pt-BR.md">Português (Brasil)</a> |
|
||||||
🇷🇺 <a href="README.ru.md">Русский</a> |
|
🇷🇺 <a href="README.ru.md">Русский</a> |
|
||||||
@@ -86,7 +87,7 @@
|
|||||||
|
|
||||||
اطّلع على تعليمات التثبيت في [بوابة وثائق Checkmate](https://checkmate.so/docs).
|
اطّلع على تعليمات التثبيت في [بوابة وثائق 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 مخصصة
|
### استخدام شهادة CA مخصصة
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
🇪🇸 <a href="README.es.md">Español</a> |
|
🇪🇸 <a href="README.es.md">Español</a> |
|
||||||
🇫🇮 <a href="README.fi.md">Suomi</a> |
|
🇫🇮 <a href="README.fi.md">Suomi</a> |
|
||||||
🇫🇷 <a href="README.fr.md">Français</a> |
|
🇫🇷 <a href="README.fr.md">Français</a> |
|
||||||
|
🇮🇹 <a href="README.it.md">Italiano</a> |
|
||||||
🇯🇵 <a href="README.ja.md">日本語</a> |
|
🇯🇵 <a href="README.ja.md">日本語</a> |
|
||||||
🇧🇷 <a href="README.pt-BR.md">Português (Brasil)</a> |
|
🇧🇷 <a href="README.pt-BR.md">Português (Brasil)</a> |
|
||||||
🇷🇺 <a href="README.ru.md">Русский</a> |
|
🇷🇺 <a href="README.ru.md">Русский</a> |
|
||||||
@@ -84,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).
|
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
|
### Utilitzar una CA personalitzada
|
||||||
|
|
||||||
|
|||||||
Loaded 100 of 188 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user