-
Notifications
You must be signed in to change notification settings - Fork 133
Deployment Guide
The platform is designed to be deployed either via a unified single-container Docker image (recommended for production) or directly on a virtual private server (VPS/Bare-metal) using a process manager like PM2.
The project includes a multi-stage Dockerfile in apps/backend/Dockerfile that builds the Vite frontend, compiles backend dependencies, and packages both into a single runtime image. The backend automatically serves the frontend static assets out of the box.
Run this command from the root of the monorepo:
docker build -t csfaq-app -f apps/backend/Dockerfile .Start the container and map the API port (6767):
docker run -d \
-p 6767:6767 \
--name csfaq-instance \
--env-file apps/backend/.env \
csfaq-appThe Docker runtime includes the Infisical CLI for pulling secrets at runtime. If you use Infisical for secret injection:
- Ensure your orchestration environment passes the
INFISICAL_TOKENenv variable to the container. - Modify the startup command to:
infisical run -- node --import tsx src/server.ts
To deploy directly on a Linux VPS (e.g. Ubuntu):
- Node.js 22 or later
- pnpm 9.x (
npm install -g pnpm@9) - PM2 (
npm install -g pm2)
- Clone the repository and navigate to the directory:
git clone <repo-url> csfaq && cd csfaq
- Install monorepo dependencies:
pnpm install --frozen-lockfile
- Create and configure your environment files:
apps/backend/.envapps/frontend/.env
- Build the workspace:
pnpm build
Create a PM2 process file ecosystem.config.js in the root:
module.exports = {
apps: [
{
name: 'csfaq-backend',
cwd: './apps/backend',
script: 'node',
args: '--import tsx src/server.ts',
env: {
NODE_ENV: 'production',
PORT: 6767
}
}
]
};Launch the server:
pm2 start ecosystem.config.js
pm2 save
pm2 startupTo expose the application to the web on a specific domain over SSL, configure Nginx as a reverse proxy.
Add this location block to your server config (usually in /etc/nginx/sites-available/default):
server {
listen 443 ssl;
server_name yourdomain.com;
# SSL configuration here...
# Route all /csfaq traffic (both frontend and API) to the Node server
location /csfaq {
proxy_pass http://127.0.0.1:6767;
proxy_http_version 1.1;
# Enable WebSockets (needed for hot-reloads and status sync)
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
# Forward client headers
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;
# Disable caching for the API routes
proxy_cache_bypass $http_upgrade;
}
}Test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx-
API Endpoint: The backend serves a healthcheck endpoint at
/csfaq/api/health. It returns a 200 OK status containing health details (database connection state, Redis connectivity, and bot integrations status). -
Docker Healthcheck: The Dockerfile includes a built-in health check:
This runs every 30 seconds to ensure the process remains responsive.
curl -sf http://localhost:6767/csfaq/api/health || exit 1