mirror of
https://github.com/Infisical/infisical.git
synced 2025-03-25 14:05:03 +00:00
Add healthchecks and test image before push
This commit is contained in:
30
.github/resources/docker-compose.be-test.yml
vendored
Normal file
30
.github/resources/docker-compose.be-test.yml
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
backend:
|
||||
container_name: infisical-backend-test
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- mongo
|
||||
image: infisical/backend:test
|
||||
command: npm run start
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- MONGO_URL=mongodb://test:example@mongo:27017/?authSource=admin
|
||||
- MONGO_USERNAME=test
|
||||
- MONGO_PASSWORD=example
|
||||
networks:
|
||||
- infisical-test
|
||||
|
||||
mongo:
|
||||
container_name: infisical-mongo-test
|
||||
image: mongo
|
||||
restart: always
|
||||
environment:
|
||||
- MONGO_INITDB_ROOT_USERNAME=test
|
||||
- MONGO_INITDB_ROOT_PASSWORD=example
|
||||
networks:
|
||||
- infisical-test
|
||||
|
||||
networks:
|
||||
infisical-test:
|
26
.github/resources/healthcheck.sh
vendored
Executable file
26
.github/resources/healthcheck.sh
vendored
Executable file
@ -0,0 +1,26 @@
|
||||
# Name of the target container to check
|
||||
container_name="$1"
|
||||
# Timeout in seconds. Default: 60
|
||||
timeout=$((${2:-60}));
|
||||
|
||||
if [ -z $container_name ]; then
|
||||
echo "No container name specified";
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
echo "Container: $container_name";
|
||||
echo "Timeout: $timeout sec";
|
||||
|
||||
try=0;
|
||||
is_healthy="false";
|
||||
while [ $is_healthy != "true" ];
|
||||
do
|
||||
try=$(($try + 1));
|
||||
printf "■";
|
||||
is_healthy=$(docker inspect --format='{{json .State.Health}}' $container_name | jq '.Status == "healthy"');
|
||||
sleep 1;
|
||||
if [[ $try -eq $timeout ]]; then
|
||||
echo " Container was not ready within timeout";
|
||||
exit 1;
|
||||
fi
|
||||
done
|
88
.github/workflows/docker-image.yml
vendored
88
.github/workflows/docker-image.yml
vendored
@ -3,40 +3,38 @@ name: Push to Docker Hub
|
||||
on: [workflow_dispatch]
|
||||
|
||||
jobs:
|
||||
|
||||
backend-image:
|
||||
name: Build backend image
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
-
|
||||
name: ☁️ Checkout source
|
||||
- name: ☁️ Checkout source
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: 🔧 Set up QEMU
|
||||
- name: 🔧 Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: 🔧 Set up Docker Buildx
|
||||
- name: 🔧 Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: 🐋 Login to Docker Hub
|
||||
- name: 🐋 Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
# -
|
||||
# name: 📦 Build backend and export to Docker
|
||||
# uses: docker/build-push-action@v3
|
||||
# with:
|
||||
# load: true
|
||||
# context: backend
|
||||
# tags: infisical/backend:test
|
||||
# -
|
||||
# name: 🧪 Test backend image
|
||||
# run: |
|
||||
# docker run --rm infisical/backend:test
|
||||
-
|
||||
name: 🏗️ Build backend and push
|
||||
- name: 📦 Build backend and export to Docker
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
load: true
|
||||
context: backend
|
||||
tags: infisical/backend:test
|
||||
- name: ⏻ Spawn backend container and dependencies
|
||||
run: |
|
||||
docker compose -f .github/resources/docker-compose.be-test.yml up --wait --quiet-pull
|
||||
- name: 🧪 Test backend image
|
||||
run: |
|
||||
./.github/resources/healthcheck.sh infisical-backend-test
|
||||
- name: ⏻ Shut down backend container and dependencies
|
||||
run: |
|
||||
docker compose -f .github/resources/docker-compose.be-test.yml down
|
||||
- name: 🏗️ Build backend and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
@ -44,42 +42,40 @@ jobs:
|
||||
tags: infisical/backend:latest
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
|
||||
frontend-image:
|
||||
name: Build frontend image
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
-
|
||||
name: ☁️ Checkout source
|
||||
- name: ☁️ Checkout source
|
||||
uses: actions/checkout@v3
|
||||
-
|
||||
name: 🔧 Set up QEMU
|
||||
- name: 🔧 Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
-
|
||||
name: 🔧 Set up Docker Buildx
|
||||
- name: 🔧 Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
-
|
||||
name: 🐋 Login to Docker Hub
|
||||
- name: 🐋 Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
# -
|
||||
# name: 📦 Build frontend and export to Docker
|
||||
# uses: docker/build-push-action@v3
|
||||
# with:
|
||||
# load: true
|
||||
# context: frontend
|
||||
# tags: infisical/frontend:test
|
||||
# build-args: |
|
||||
# POSTHOG_API_KEY=${{ secrets.PUBLIC_POSTHOG_API_KEY }}
|
||||
# -
|
||||
# name: 🧪 Test frontend image
|
||||
# run: |
|
||||
# docker run --rm infisical/frontend:test
|
||||
-
|
||||
name: 🏗️ Build frontend and push
|
||||
- name: 📦 Build frontend and export to Docker
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
load: true
|
||||
context: frontend
|
||||
tags: infisical/frontend:test
|
||||
build-args: |
|
||||
POSTHOG_API_KEY=${{ secrets.PUBLIC_POSTHOG_API_KEY }}
|
||||
- name: ⏻ Spawn frontend container
|
||||
run: |
|
||||
docker run -d --rm --name infisical-frontend-test infisical/frontend:test
|
||||
- name: 🧪 Test frontend image
|
||||
run: |
|
||||
./.github/resources/healthcheck.sh infisical-frontend-test
|
||||
- name: ⏻ Shut down frontend container
|
||||
run: |
|
||||
docker stop infisical-frontend-test
|
||||
- name: 🏗️ Build frontend and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: true
|
||||
|
@ -2,11 +2,14 @@ FROM node:16-bullseye-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json .
|
||||
COPY package.json package-lock.json ./
|
||||
|
||||
RUN npm install
|
||||
RUN npm ci --only-production
|
||||
|
||||
COPY . .
|
||||
|
||||
CMD ["npm", "run", "start"]
|
||||
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
|
||||
CMD node healthcheck.js
|
||||
|
||||
|
||||
CMD ["npm", "run", "start"]
|
||||
|
27
backend/healthcheck.js
Normal file
27
backend/healthcheck.js
Normal file
@ -0,0 +1,27 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-undef */
|
||||
const http = require('http');
|
||||
const PORT = process.env.PORT || 4000;
|
||||
const options = {
|
||||
host: 'localhost',
|
||||
port: PORT,
|
||||
timeout: 2000,
|
||||
path: '/healthcheck'
|
||||
};
|
||||
|
||||
const healthCheck = http.request(options, (res) => {
|
||||
console.log(`HEALTHCHECK STATUS: ${res.statusCode}`);
|
||||
if (res.statusCode == 200) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
healthCheck.on('error', function (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
healthCheck.end();
|
155
backend/package-lock.json
generated
155
backend/package-lock.json
generated
@ -9,6 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@godaddy/terminus": "^4.11.2",
|
||||
"@sentry/node": "^7.14.0",
|
||||
"@sentry/tracing": "^7.19.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
@ -2028,6 +2029,14 @@
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@godaddy/terminus": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.11.2.tgz",
|
||||
"integrity": "sha512-e/kbOWpGKME42eltM/wXM3RxSUOrfureZxEd6Dt6NXyFoJ7E8lnmm7znXydJsL3B7ky4HRFZI+eHrep54NZbeQ==",
|
||||
"dependencies": {
|
||||
"stoppable": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||
@ -6731,7 +6740,129 @@
|
||||
"treeverse",
|
||||
"validate-npm-package-name",
|
||||
"which",
|
||||
"write-file-atomic"
|
||||
"write-file-atomic",
|
||||
"@colors/colors",
|
||||
"@gar/promisify",
|
||||
"@npmcli/disparity-colors",
|
||||
"@npmcli/git",
|
||||
"@npmcli/installed-package-contents",
|
||||
"@npmcli/metavuln-calculator",
|
||||
"@npmcli/move-file",
|
||||
"@npmcli/name-from-folder",
|
||||
"@npmcli/node-gyp",
|
||||
"@npmcli/promise-spawn",
|
||||
"@npmcli/query",
|
||||
"@tootallnate/once",
|
||||
"agent-base",
|
||||
"agentkeepalive",
|
||||
"aggregate-error",
|
||||
"ansi-regex",
|
||||
"ansi-styles",
|
||||
"aproba",
|
||||
"are-we-there-yet",
|
||||
"asap",
|
||||
"balanced-match",
|
||||
"bin-links",
|
||||
"binary-extensions",
|
||||
"brace-expansion",
|
||||
"builtins",
|
||||
"cidr-regex",
|
||||
"clean-stack",
|
||||
"clone",
|
||||
"cmd-shim",
|
||||
"color-convert",
|
||||
"color-name",
|
||||
"color-support",
|
||||
"common-ancestor-path",
|
||||
"concat-map",
|
||||
"console-control-strings",
|
||||
"cssesc",
|
||||
"debug",
|
||||
"debuglog",
|
||||
"defaults",
|
||||
"delegates",
|
||||
"depd",
|
||||
"dezalgo",
|
||||
"diff",
|
||||
"emoji-regex",
|
||||
"encoding",
|
||||
"env-paths",
|
||||
"err-code",
|
||||
"fs.realpath",
|
||||
"function-bind",
|
||||
"gauge",
|
||||
"has",
|
||||
"has-flag",
|
||||
"has-unicode",
|
||||
"http-cache-semantics",
|
||||
"http-proxy-agent",
|
||||
"https-proxy-agent",
|
||||
"humanize-ms",
|
||||
"iconv-lite",
|
||||
"ignore-walk",
|
||||
"imurmurhash",
|
||||
"indent-string",
|
||||
"infer-owner",
|
||||
"inflight",
|
||||
"inherits",
|
||||
"ip",
|
||||
"ip-regex",
|
||||
"is-core-module",
|
||||
"is-fullwidth-code-point",
|
||||
"is-lambda",
|
||||
"isexe",
|
||||
"json-stringify-nice",
|
||||
"jsonparse",
|
||||
"just-diff",
|
||||
"just-diff-apply",
|
||||
"lru-cache",
|
||||
"minipass-collect",
|
||||
"minipass-fetch",
|
||||
"minipass-flush",
|
||||
"minipass-json-stream",
|
||||
"minipass-sized",
|
||||
"minizlib",
|
||||
"mute-stream",
|
||||
"negotiator",
|
||||
"normalize-package-data",
|
||||
"npm-bundled",
|
||||
"npm-normalize-package-bin",
|
||||
"npm-packlist",
|
||||
"once",
|
||||
"path-is-absolute",
|
||||
"postcss-selector-parser",
|
||||
"promise-all-reject-late",
|
||||
"promise-call-limit",
|
||||
"promise-inflight",
|
||||
"promise-retry",
|
||||
"promzard",
|
||||
"read-cmd-shim",
|
||||
"readable-stream",
|
||||
"retry",
|
||||
"safe-buffer",
|
||||
"safer-buffer",
|
||||
"set-blocking",
|
||||
"signal-exit",
|
||||
"smart-buffer",
|
||||
"socks",
|
||||
"socks-proxy-agent",
|
||||
"spdx-correct",
|
||||
"spdx-exceptions",
|
||||
"spdx-expression-parse",
|
||||
"spdx-license-ids",
|
||||
"string_decoder",
|
||||
"string-width",
|
||||
"strip-ansi",
|
||||
"supports-color",
|
||||
"unique-filename",
|
||||
"unique-slug",
|
||||
"util-deprecate",
|
||||
"validate-npm-package-license",
|
||||
"walk-up-path",
|
||||
"wcwidth",
|
||||
"wide-align",
|
||||
"wrappy",
|
||||
"yallist"
|
||||
],
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
@ -10192,6 +10323,15 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/stoppable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
|
||||
"integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==",
|
||||
"engines": {
|
||||
"node": ">=4",
|
||||
"npm": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
@ -12607,6 +12747,14 @@
|
||||
"strip-json-comments": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"@godaddy/terminus": {
|
||||
"version": "4.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@godaddy/terminus/-/terminus-4.11.2.tgz",
|
||||
"integrity": "sha512-e/kbOWpGKME42eltM/wXM3RxSUOrfureZxEd6Dt6NXyFoJ7E8lnmm7znXydJsL3B7ky4HRFZI+eHrep54NZbeQ==",
|
||||
"requires": {
|
||||
"stoppable": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
"version": "0.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz",
|
||||
@ -18631,6 +18779,11 @@
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
|
||||
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="
|
||||
},
|
||||
"stoppable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/stoppable/-/stoppable-1.1.0.tgz",
|
||||
"integrity": "sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw=="
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@godaddy/terminus": "^4.11.2",
|
||||
"@sentry/node": "^7.14.0",
|
||||
"@sentry/tracing": "^7.19.0",
|
||||
"@types/crypto-js": "^4.1.1",
|
||||
|
@ -1,3 +1,5 @@
|
||||
/* eslint-disable no-console */
|
||||
import http from 'http';
|
||||
import express from 'express';
|
||||
import helmet from 'helmet';
|
||||
import cors from 'cors';
|
||||
@ -7,63 +9,67 @@ import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL, POSTHOG_PROJECT_API_KEY, POSTHOG_HOST, TELEMETRY_ENABLED } from './config';
|
||||
import { PORT, SENTRY_DSN, NODE_ENV, MONGO_URL, SITE_URL } from './config';
|
||||
import { apiLimiter } from './helpers/rateLimiter';
|
||||
import { createTerminus } from '@godaddy/terminus';
|
||||
|
||||
const app = express();
|
||||
|
||||
Sentry.init({
|
||||
dsn: SENTRY_DSN,
|
||||
tracesSampleRate: 1.0,
|
||||
debug: NODE_ENV === 'production' ? false : true,
|
||||
environment: NODE_ENV
|
||||
dsn: SENTRY_DSN,
|
||||
tracesSampleRate: 1.0,
|
||||
debug: NODE_ENV === 'production' ? false : true,
|
||||
environment: NODE_ENV
|
||||
});
|
||||
|
||||
import {
|
||||
signup as signupRouter,
|
||||
auth as authRouter,
|
||||
organization as organizationRouter,
|
||||
workspace as workspaceRouter,
|
||||
membershipOrg as membershipOrgRouter,
|
||||
membership as membershipRouter,
|
||||
key as keyRouter,
|
||||
inviteOrg as inviteOrgRouter,
|
||||
user as userRouter,
|
||||
userAction as userActionRouter,
|
||||
secret as secretRouter,
|
||||
serviceToken as serviceTokenRouter,
|
||||
password as passwordRouter,
|
||||
stripe as stripeRouter,
|
||||
integration as integrationRouter,
|
||||
integrationAuth as integrationAuthRouter
|
||||
signup as signupRouter,
|
||||
auth as authRouter,
|
||||
organization as organizationRouter,
|
||||
workspace as workspaceRouter,
|
||||
membershipOrg as membershipOrgRouter,
|
||||
membership as membershipRouter,
|
||||
key as keyRouter,
|
||||
inviteOrg as inviteOrgRouter,
|
||||
user as userRouter,
|
||||
userAction as userActionRouter,
|
||||
secret as secretRouter,
|
||||
serviceToken as serviceTokenRouter,
|
||||
password as passwordRouter,
|
||||
stripe as stripeRouter,
|
||||
integration as integrationRouter,
|
||||
integrationAuth as integrationAuthRouter
|
||||
} from './routes';
|
||||
|
||||
const connectWithRetry = () => {
|
||||
mongoose.connect(MONGO_URL)
|
||||
.then(() => console.log('Successfully connected to DB'))
|
||||
.catch((e) => {
|
||||
console.log('Failed to connect to DB ', e);
|
||||
setTimeout(() => {
|
||||
console.log(e);
|
||||
}, 5000);
|
||||
});
|
||||
}
|
||||
mongoose
|
||||
.connect(MONGO_URL)
|
||||
.then(() => console.log('Successfully connected to DB'))
|
||||
.catch((e) => {
|
||||
console.log('Failed to connect to DB ', e);
|
||||
setTimeout(() => {
|
||||
console.log(e);
|
||||
}, 5000);
|
||||
});
|
||||
};
|
||||
|
||||
connectWithRetry();
|
||||
|
||||
app.enable('trust proxy');
|
||||
app.use(cookieParser());
|
||||
app.use(cors({
|
||||
credentials: true,
|
||||
origin: SITE_URL
|
||||
}));
|
||||
app.use(
|
||||
cors({
|
||||
credentials: true,
|
||||
origin: SITE_URL
|
||||
})
|
||||
);
|
||||
|
||||
if (NODE_ENV === 'production') {
|
||||
// enable app-wide rate-limiting + helmet security
|
||||
// in production
|
||||
app.disable('x-powered-by');
|
||||
app.use(apiLimiter);
|
||||
app.use(helmet());
|
||||
// enable app-wide rate-limiting + helmet security
|
||||
// in production
|
||||
app.disable('x-powered-by');
|
||||
app.use(apiLimiter);
|
||||
app.use(helmet());
|
||||
}
|
||||
|
||||
app.use(express.json());
|
||||
@ -86,6 +92,31 @@ app.use('/api/v1/stripe', stripeRouter);
|
||||
app.use('/api/v1/integration', integrationRouter);
|
||||
app.use('/api/v1/integration-auth', integrationAuthRouter);
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log('Listening on PORT ' + PORT);
|
||||
const server = http.createServer(app);
|
||||
|
||||
const onSignal = () => {
|
||||
console.log('Server is starting clean-up');
|
||||
return Promise.all([
|
||||
// your clean logic, like closing database connections
|
||||
]);
|
||||
};
|
||||
|
||||
const healthCheck = () => {
|
||||
// `state.isShuttingDown` (boolean) shows whether the server is shutting down or not
|
||||
return Promise
|
||||
.resolve
|
||||
// optionally include a resolve value to be included as
|
||||
// info in the health check response
|
||||
();
|
||||
};
|
||||
|
||||
createTerminus(server, {
|
||||
healthChecks: {
|
||||
'/healthcheck': healthCheck,
|
||||
onSignal
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(PORT, () => {
|
||||
console.log('Listening on PORT ' + PORT);
|
||||
});
|
||||
|
@ -15,7 +15,7 @@ services:
|
||||
- backend
|
||||
networks:
|
||||
- infisical
|
||||
|
||||
|
||||
backend:
|
||||
container_name: infisical-backend
|
||||
restart: unless-stopped
|
||||
@ -28,7 +28,7 @@ services:
|
||||
- NODE_ENV=production
|
||||
networks:
|
||||
- infisical
|
||||
|
||||
|
||||
frontend:
|
||||
container_name: infisical-frontend
|
||||
restart: unless-stopped
|
||||
|
@ -60,5 +60,8 @@ EXPOSE 3000
|
||||
ENV PORT 3000
|
||||
ENV NEXT_TELEMETRY_DISABLED 1
|
||||
|
||||
HEALTHCHECK --interval=10s --timeout=3s --start-period=10s \
|
||||
CMD node scripts/healthcheck.js
|
||||
|
||||
|
||||
CMD ["/app/scripts/start.sh"]
|
||||
|
26
frontend/scripts/healthcheck.js
Normal file
26
frontend/scripts/healthcheck.js
Normal file
@ -0,0 +1,26 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
/* eslint-disable no-console */
|
||||
/* eslint-disable no-undef */
|
||||
const http = require('http');
|
||||
const options = {
|
||||
host: 'localhost',
|
||||
port: 3000,
|
||||
timeout: 2000,
|
||||
path: '/'
|
||||
};
|
||||
|
||||
const healthCheck = http.request(options, (res) => {
|
||||
console.log(`HEALTHCHECK STATUS: ${res.statusCode}`);
|
||||
if (res.statusCode == 200) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
healthCheck.on('error', function (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
healthCheck.end();
|
Reference in New Issue
Block a user