Adds healthcheck to quiz + adds image to build

This commit is contained in:
Gabriel Matte 2024-11-11 23:00:38 -05:00
parent 2c7fd9c828
commit 3c2bcb4ed4
11 changed files with 833 additions and 332 deletions

View file

@ -103,4 +103,35 @@ jobs:
tags: ${{ steps.meta.outputs.tags }} tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha cache-from: type=gha
cache-to: type=gha,mode=max
build-quizroom:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata for Quizroom Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}-quizroom
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
- name: Build and push Quizroom Docker image
uses: docker/build-push-action@v5
with:
context: ./quizRoom
push: ${{ github.event_name != 'pull_request' }}
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max cache-to: type=gha,mode=max

View file

@ -37,7 +37,7 @@ services:
- quiz_network - quiz_network
restart: always restart: always
quizroom: quizroom: # Forces image to update
build: build:
context: ./quizRoom context: ./quizRoom
dockerfile: Dockerfile dockerfile: Dockerfile

View file

@ -1,60 +0,0 @@
js_import njs/main.js;
js_set $quiz_room_host main.getQuizRoomHost;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Cache for room information
# keyval_zone zone=rooms:10m;
# keyval_zone zone=room_hosts:10m;
# keyval $room_id $room_info zone=rooms;
upstream frontend {
server localhost:5173;
}
upstream backend {
server localhost:3000;
}
server {
listen 80;
location /api {
rewrite /backend/(.*) /$1 break;
proxy_pass http://backend;
}
location /socket.io {
rewrite /backend/(.*) /$1 break;
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_hide_header 'Access-Control-Allow-Origin';
}
location /quiz/([^/]+)/socket {
# Routing logic
set $room_id $1;
js_content main.routeWebSocket;
#Proxy headers
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
location / {
proxy_pass http://frontend;
}
}

2
quizRoom/.dockerignore Normal file
View file

@ -0,0 +1,2 @@
Dockerfile
docker-compose.yml

View file

@ -1,6 +1,10 @@
# Use the Node base image # Use the Node base image
FROM node:18 AS quizroom FROM node:18 AS quizroom
ARG PORT=4500
ENV PORT=${PORT}
ENV ROOM_ID=${ROOM_ID}
# Create a working directory # Create a working directory
WORKDIR /usr/src/app WORKDIR /usr/src/app
@ -15,7 +19,11 @@ COPY . .
RUN npm run build RUN npm run build
# Expose WebSocket server port # Expose WebSocket server port
EXPOSE 4500 EXPOSE ${PORT}
# Add healthcheck
HEALTHCHECK --interval=30s --timeout=30s --start-period=30s --retries=3 \
CMD /usr/src/app/healthcheck.sh
# Start the server using the compiled JavaScript file # Start the server using the compiled JavaScript file
CMD ["node", "dist/app.js"] CMD ["node", "dist/app.js"]

View file

@ -2,18 +2,42 @@ import http from "http";
import { Server, ServerOptions } from "socket.io"; import { Server, ServerOptions } from "socket.io";
import { setupWebsocket } from "./socket/setupWebSocket"; import { setupWebsocket } from "./socket/setupWebSocket";
import dotenv from "dotenv"; import dotenv from "dotenv";
import express from 'express';
// Load environment variables // Load environment variables
dotenv.config(); dotenv.config();
const port = 4500; const port = process.env.PORT || 4500;
const roomId = process.env.ROOM_ID; // Load roomId from environment variable const roomId = process.env.ROOM_ID;
console.log(`I am: /api/room/${roomId}/socket`); console.log(`I am: /api/room/${roomId}/socket`);
// Create HTTP and WebSocket server // Create Express app for health check
const server = http.createServer(); const app = express();
const server = http.createServer(app);
// Health check endpoint
app.get('/health', (_, res) => {
try {
if (io.engine?.clientsCount !== undefined) {
res.status(200).json({
status: 'healthy',
path: `/api/room/${roomId}/socket`,
connections: io.engine.clientsCount,
uptime: process.uptime()
});
} else {
throw new Error('Socket.io server not initialized');
}
} catch (error: Error | any) {
res.status(500).json({
status: 'unhealthy',
error: error.message
});
}
});
const ioOptions: Partial<ServerOptions> = { const ioOptions: Partial<ServerOptions> = {
path: `/api/room/${roomId}/socket`, // Use roomId from env variable path: `/api/room/${roomId}/socket`,
cors: { cors: {
origin: "*", origin: "*",
methods: ["GET", "POST"], methods: ["GET", "POST"],
@ -28,4 +52,4 @@ setupWebsocket(io);
server.listen(port, () => { server.listen(port, () => {
console.log(`WebSocket server is running on port ${port}`); console.log(`WebSocket server is running on port ${port}`);
}); });

View file

@ -0,0 +1,19 @@
version: '3.8'
services:
quizroom:
build:
context: .
args:
- PORT=${PORT:-4500}
ports:
- "${PORT:-4500}:${PORT:-4500}"
environment:
- PORT=${PORT:-4500}
- ROOM_ID=${ROOM_ID}
healthcheck:
test: curl -f http://localhost:${PORT:-4500}/health || exit 1
interval: 30s
timeout: 30s
retries: 3
start_period: 30s

2
quizRoom/healthcheck.sh Normal file
View file

@ -0,0 +1,2 @@
#!/bin/sh
curl -f "http://0.0.0.0:${PORT}/health" || exit 1

File diff suppressed because it is too large Load diff

View file

@ -17,8 +17,8 @@
"typescript": "^5.6.3" "typescript": "^5.6.3"
}, },
"dependencies": { "dependencies": {
"@valkey/valkey-glide": "^1.1.0",
"dotenv": "^16.4.5", "dotenv": "^16.4.5",
"express": "^4.21.1",
"http": "^0.0.1-security", "http": "^0.0.1-security",
"socket.io": "^4.8.1" "socket.io": "^4.8.1"
} }

View file

@ -0,0 +1,2 @@
ROOM_ID=123456
PORT=4500