Skip to content

Commit

Permalink
Merge pull request #236 from serguun42/add-cloud-healthcheck
Browse files Browse the repository at this point in the history
Add cloud health check container
  • Loading branch information
serguun42 authored Nov 30, 2023
2 parents 7ca73fb + 6d8a306 commit 575cae7
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 4 deletions.
46 changes: 43 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ jobs:
cp $CONFIGS_LOCATION_BASE/notifier-and-logger.config.json ./notifier/;
cp $CONFIGS_LOCATION_BASE/scrapper.config.json ./scrapper/;
cp $CONFIGS_LOCATION_BASE/backend.config.json ./backend/;
cp $CONFIGS_LOCATION_BASE/healthcheck.config.json ./healthcheck/;
cp $CONFIGS_LOCATION_BASE/telegram-bot.config.json ./telegram/
[[ -f $CONFIGS_LOCATION_BASE/tag-manager.html ]] &&
cp $CONFIGS_LOCATION_BASE/tag-manager.html ./frontend/src/config/tag-manager.html ||
Expand Down Expand Up @@ -66,10 +67,47 @@ jobs:
CONFIGS_LOCATION_BASE: ${{ secrets.CONFIGS_LOCATION_BASE }}
run: docker compose -f docker-compose.yml --env-file $CONFIGS_LOCATION_BASE/docker.env up -d --force-recreate --no-deps

cloud:
name: Build and deploy Cloud Healthcheck image
runs-on: self-hosted
env:
YANDEX_CLOUD_REGISTRY_ID: ${{ secrets.YANDEX_CLOUD_REGISTRY_ID }}
YANDEX_CLOUD_IMAGE_NAME: ${{ secrets.YANDEX_CLOUD_IMAGE_NAME }}
CONFIGS_LOCATION_BASE: ${{ secrets.CONFIGS_LOCATION_BASE }}
YANDEX_CLOUD_JSON_KEYS_FILENAME: ${{ secrets.YANDEX_CLOUD_JSON_KEYS_FILENAME }}
needs:
- build
- testing

steps:
- name: Build Docker image
run: cd healthcheck && docker build . -t cr.yandex/$YANDEX_CLOUD_REGISTRY_ID/$YANDEX_CLOUD_IMAGE_NAME:latest
- name: Log into Yandex Cloud
run: |
cat $CONFIGS_LOCATION_BASE/$YANDEX_CLOUD_JSON_KEYS_FILENAME | docker login --username json_key --password-stdin cr.yandex
- name: Push to Yandex Cloud
run: |
docker push cr.yandex/$YANDEX_CLOUD_REGISTRY_ID/$YANDEX_CLOUD_IMAGE_NAME:latest
- name: Deploy serverless container
uses: yc-actions/yc-sls-container-deploy@v2
with:
yc-sa-json-credentials: ${{ secrets.YANDEX_CLOUD_JSON_KEYS }}
container-name: ${{ secrets.YANDEX_CLOUD_IMAGE_NAME }}
folder-id: ${{ secrets.YANDEX_CLOUD_FOLDER_ID }}
revision-service-account-id: ${{ secrets.YANDEX_CLOUD_SERVICE_ACCOUNT_ID }}
revision-image-url: cr.yandex/$YANDEX_CLOUD_REGISTRY_ID/$YANDEX_CLOUD_IMAGE_NAME:latest
revision-cores: 1
revision-memory: 256Mb
revision-env: |
CHECKING_ORIGIN=mirea.xyz
API_VERSION=1.3
clean:
name: Clean cache and dangling images
name: Clean unused images
runs-on: self-hosted
needs: deploy
needs:
- deploy
- cloud

steps:
- name: Clean dangling images
Expand All @@ -84,7 +122,9 @@ jobs:
notify:
name: Send final logs
runs-on: self-hosted
needs: deploy
needs:
- deploy
- cloud

steps:
- name: Send logs via notifier
Expand Down
1 change: 0 additions & 1 deletion backend/backend.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"DATABASE_NAME": "mss",
"DATABASE_CONNECTION_URI": "mongodb://host1:27017,host2:27017,host3:27017/?replicaSet=myRs&readPreference=primaryPreferred",
"LOGGING_TAG": "backend",
"REMOTE_LOGS_TAG": "remote_logs",
"LOGGING_HOST": "mss-notifier",
"LOGGING_PORT": 80,
"MAX_NUMBER_OF_BACKEND_REQUESTS_IN_MINUTE": 100,
Expand Down
9 changes: 9 additions & 0 deletions healthcheck/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.vscode
/node_modules/

/data/
/out/
/local-stuff/
tsconfig.json
*.bat
*.example.json
11 changes: 11 additions & 0 deletions healthcheck/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FROM node:lts-alpine

ARG TESTING

WORKDIR /usr/src/app
COPY . /usr/src/app

ENV NODE_ENV=production
RUN npm ci --omit=dev

CMD [ "npm", "run", "production" ]
79 changes: 79 additions & 0 deletions healthcheck/healthcheck-server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const http = require("http");
const fetch = require("node-fetch").default;
const { AbortError } = require("node-fetch");
const IS_DEV = require("./util/is-dev.js");

const CONFIG = IS_DEV ? require("../../DEV_CONFIGS/healthcheck.config.json") : require("./healthcheck.config.json");

const CHECKING_ORIGIN = process.env.CHECKING_ORIGIN || CONFIG.CHECKING_ORIGIN;
const API_VERSION = process.env.API_VERSION || CONFIG.API_VERSION;

const PONG_API_METHOD = new URL(`/api/v${API_VERSION}/stats`, CHECKING_ORIGIN);
const STATS_API_METHOD = new URL(`/api/v${API_VERSION}/stats`, CHECKING_ORIGIN);

class CustomError extends Error {
constructor(message) {
super(message);
}
}

http
.createServer((req, res) => {
if (req.method !== "GET") {
res.statusCode = 405;
res.end();
return;
}

if (req.url !== "/" && req.url !== "") {
res.statusCode = 404;
res.end();
return;
}

const pingSignaling = new AbortController();
const pingSignalTimeout = setTimeout(() => pingSignaling.abort(), 5000);

fetch(PONG_API_METHOD, { signal: pingSignaling.signal })
.then((res) => {
clearTimeout(pingSignalTimeout);

if (!res.ok) return Promise.reject(new CustomError("Cannot ping service"));

const statsSignaling = new AbortController();
const statsSignalTimeout = setTimeout(() => pingSignaling.abort(), 5000);

return fetch(STATS_API_METHOD, { signal: statsSignaling.signal }).then(
/** @returns {Promise<{ groupsCount: number; scrapperUpdatedDate: string }>} */ (res) => {
clearTimeout(statsSignalTimeout);

if (!res.ok) return Promise.reject(new CustomError("Cannot get stats from service"));

return res.json();
}
);
})
.then((stats) => {
res.statusCode = 200;
res.setHeader("Content-Type", "application/json; charset=UTF-8");
res.end(JSON.stringify({ ok: true, stats }));
})
.catch((reason) => {
res.statusCode = 500;
res.setHeader("Content-Type", "application/json; charset=UTF-8");
res.end(
JSON.stringify({
ok: false,
reason:
reason instanceof CustomError
? reason.message
: reason instanceof AbortError
? "Connection timed out"
: typeof reason === "string"
? reason
: "Server is not OK"
})
);
});
})
.listen(80);
4 changes: 4 additions & 0 deletions healthcheck/healthcheck.config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"CHECKING_ORIGIN": "https://mirea.xyz",
"API_VERSION": "1.3"
}
54 changes: 54 additions & 0 deletions healthcheck/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions healthcheck/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "healthcheck",
"version": "1.0.0",
"description": "",
"main": "healthcheck-server.js",
"scripts": {
"production": "node healthcheck-server.js"
},
"author": "serguun42",
"license": "BSL-1.0",
"dependencies": {
"node-fetch": "^2.7.0"
}
}
3 changes: 3 additions & 0 deletions healthcheck/util/is-dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const IS_DEV = process.env.NODE_ENV !== "production";

module.exports = IS_DEV;

0 comments on commit 575cae7

Please sign in to comment.