diff --git a/.github/workflows/distribution-deploy.yml b/.github/workflows/distribution-deploy.yml index 69f3afd73..d4bcfc8b7 100644 --- a/.github/workflows/distribution-deploy.yml +++ b/.github/workflows/distribution-deploy.yml @@ -11,9 +11,6 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Log in to GitHub Container Registry uses: docker/login-action@v3 with: diff --git a/.github/workflows/distribution-mono-deploy.yml b/.github/workflows/distribution-mono-deploy.yml new file mode 100644 index 000000000..547cf2efe --- /dev/null +++ b/.github/workflows/distribution-mono-deploy.yml @@ -0,0 +1,30 @@ +name: Distribution deploy + +on: + push: + branches: ["master"] + workflow_dispatch: +jobs: + docker-build-and-push-server: + 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-dist-mono \ + -f ./docker/dist-mono/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-dist-mono diff --git a/docker/.gitignore b/docker/.gitignore index 1e35b3731..81ba730c9 100755 --- a/docker/.gitignore +++ b/docker/.gitignore @@ -8,5 +8,6 @@ dist/redis/data/* prod/mongo/data/* prod/redis/data/* dist/docker-compose-test.yaml +/dist-mono/mongo/data/* +/dist-mono/redis/data/* *.env -prod/certbot/* \ No newline at end of file diff --git a/docker/dist-mono/build_images.sh b/docker/dist-mono/build_images.sh new file mode 100755 index 000000000..b56b9052c --- /dev/null +++ b/docker/dist-mono/build_images.sh @@ -0,0 +1,29 @@ +#!/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_redis" "mono_server") +dockerfiles=( + "./docker/dist-mono/mongoDB.Dockerfile" + "./docker/dist-mono/redis.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" \ No newline at end of file diff --git a/docker/dist-mono/docker-compose.yaml b/docker/dist-mono/docker-compose.yaml new file mode 100755 index 000000000..35c642132 --- /dev/null +++ b/docker/dist-mono/docker-compose.yaml @@ -0,0 +1,36 @@ +services: + server: + image: ghcr.io/bluewave-labs/checkmate:backend-dist-mono + restart: always + ports: + - "52345:52345" + environment: + - UPTIME_APP_API_BASE_URL=http://localhost:52345/api/v1 + - UPTIME_APP_CLIENT_HOST=http://localhost + depends_on: + - redis + - mongodb + redis: + image: ghcr.io/bluewave-labs/checkmate:redis-dist + restart: always + volumes: + - ./redis/data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 5s + mongodb: + image: ghcr.io/bluewave-labs/checkmate:mongo-dist + restart: always + command: ["mongod", "--quiet", "--replSet", "rs0", "--bind_ip_all"] + volumes: + - ./mongo/data:/data/db + healthcheck: + test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'mongodb:27017'}]}) }" | mongosh --port 27017 --quiet + interval: 5s + timeout: 30s + start_period: 0s + start_interval: 1s + retries: 30 diff --git a/docker/dist-mono/mongoDB.Dockerfile b/docker/dist-mono/mongoDB.Dockerfile new file mode 100755 index 000000000..969a320c2 --- /dev/null +++ b/docker/dist-mono/mongoDB.Dockerfile @@ -0,0 +1,3 @@ +FROM mongo +EXPOSE 27017 +CMD ["mongod"] diff --git a/docker/dist-mono/redis.Dockerfile b/docker/dist-mono/redis.Dockerfile new file mode 100755 index 000000000..af68ec61e --- /dev/null +++ b/docker/dist-mono/redis.Dockerfile @@ -0,0 +1,2 @@ +FROM redis +EXPOSE 6379 \ No newline at end of file diff --git a/docker/dist-mono/server.Dockerfile b/docker/dist-mono/server.Dockerfile new file mode 100644 index 000000000..f28c834ea --- /dev/null +++ b/docker/dist-mono/server.Dockerfile @@ -0,0 +1,25 @@ +FROM node:20-alpine AS frontend-build + +WORKDIR /app/client + +COPY client/package*.json ./ +RUN npm install + +COPY client ./ +RUN npm run build + +FROM node:20-alpine AS app + +WORKDIR /app/server + +COPY server ./ + +COPY --from=frontend-build /app/client/dist ./public + +RUN npm install + +RUN chmod +x ./scripts/inject-vars.sh + +EXPOSE 52345 + +CMD ./scripts/inject-vars.sh && node ./index.js diff --git a/server/index.js b/server/index.js index 85ad2a31d..b101c7bff 100755 --- a/server/index.js +++ b/server/index.js @@ -99,6 +99,8 @@ const openApiSpec = JSON.parse( fs.readFileSync(path.join(__dirname, "openapi.json"), "utf8") ); +const frontendPath = path.join(__dirname, "public"); + let server; const shutdown = async () => { @@ -308,6 +310,7 @@ const startApp = async () => { const notificationRoutes = new NotificationRoutes(notificationController); const diagnosticRoutes = new DiagnosticRoutes(diagnosticController); // Middleware + app.use(express.static(frontendPath)); app.use(responseHandler); app.use( cors({ @@ -353,6 +356,10 @@ const startApp = async () => { status: "OK", }); }); + // FE routes + app.get("*", (req, res) => { + res.sendFile(path.join(frontendPath, "index.html")); + }); app.use(handleErrors); };