Self-Hosting a Next.js Browser Game on Coolify: A Production Setup Walkthrough

A hands-on walkthrough of self-hosting a Next.js browser mahjong game "Janten" on a VPS via Coolify — Nixpacks build, separate production/preview environments, GitHub Actions CI/CD, memory tuning, and Let's Encrypt SSL configuration.
代表 / エンジニア
At aduce, we develop a browser mahjong game called Janten (janten.net) in Next.js and self-host it on Coolify atop a VPS. This article walks through the production setup, with the actual configuration files.
What Is Coolify? A Choice for Self-Hosting Next.js on a VPS
Coolify is an open-source PaaS (Platform as a Service) that delivers a Vercel/Netlify-style deployment experience on your own VPS. It integrates with GitHub repositories and triggers builds and deploys on push.
We chose Coolify for self-hosting Next.js for a simple reason: it bundles automated SSL certificate management, health checks, and resource limits in a single VPS. We can operate a long-session app like a game without worrying about Vercel's usage-based billing.
The janten.net Infrastructure (Production + Preview)
Janten runs two Coolify environments: production and preview. Production tracks the prod branch, preview tracks main, each registered as a separate application in Coolify.
| Environment | Domain | Branch | Purpose |
|---|---|---|---|
| Production | janten.net | prod | Public-facing |
| Preview | pre.janten.net | main | Dev verification |
The preview environment has an IP allowlist so only authorized users can access it.
# IP restriction on the preview environment
ip_allow:
- 14.11.163.0/32Zero-Configuration Builds with Nixpacks
Coolify natively supports Nixpacks as a build pack. When it detects a package.json, it automatically sets up a Node.js environment and runs the build command.
Janten needs to pre-build a local package, mahjong-core, so we handle that in the package.json build script:
{
"scripts": {
"build": "cd mahjong-core && npm install && npm run build && cd .. && next build",
"start": "next start"
}
}Coolify's configuration is simple:
build:
pack: nixpacks
command: npm run build
runtime:
start_command: npm run start
port: 3000No need to maintain a custom Dockerfile. Just define build and start in package.json and the Next.js app deploys.
CI/CD Integration with GitHub Actions
Separate from Coolify's GitHub integration, we run CI (tests and build verification) via GitHub Actions. The pipeline below runs on pushes and PRs to the main and prod branches.
name: CI
on:
push:
branches: [main, prod]
pull_request:
branches: [main, prod]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- name: Build mahjong-core
run: cd mahjong-core && npm install && npm run build
- name: Test
run: npm test
- name: Build
run: npx next buildOnly commits that pass CI are merged to main, and merging main into prod triggers the production deploy. Coolify's webhook detects the push event and kicks off build and deploy automatically.
Production Tuning (Memory Limits, Health Checks)
VPS resources are finite, so we set memory and CPU caps on the container.
environment:
runtime:
NODE_ENV: production
NODE_OPTIONS: "--max-old-space-size=768"
resources:
memory: 512
cpu: 500
healthcheck:
path: /
interval: 30
timeout: 10
retries: 3The key here is NODE_OPTIONS with --max-old-space-size=768. Even though the container's memory cap is 512MB, setting Node.js's heap limit slightly higher prevents out-of-memory errors during build while still letting the OOM Killer step in to restart a runaway container — that's the design.
Health checks hit / every 30 seconds and restart the container after 3 consecutive failures. Browser games rely on long-running sessions, so automatic recovery on anomalies is critical.
Automatic SSL with Let's Encrypt
Coolify has built-in Let's Encrypt integration — just set the domain and SSL certs are obtained and renewed automatically.
domains:
primary: janten.net
ssl:
enabled: true
auto_renew: trueThat's the entire configuration. No manual certificate renewals, no cron jobs. Under the hood, Coolify runs Traefik as a reverse proxy, handling HTTPS termination and Let's Encrypt challenge responses. The same settings apply uniformly to both production and preview environments.
Summary
Running Coolify on a VPS lets us deploy a Next.js browser game like Janten without a Dockerfile, while unifying SSL, health checks, and resource management. Zero-config builds via Nixpacks, CI/CD combined with GitHub Actions, an IP-restricted preview environment — small teams can still maintain production-quality infrastructure.
At aduce we offer technical advisory based on this kind of infrastructure and DevOps experience. If you need help with VPS self-hosting or CI/CD pipeline setup, please reach out via Contact.