- Update Gitea pipeline to build cnoc:node18, cnoc:node20, cnoc:node22 - Update local-dev.sh to use cnoc container from registry - Update documentation references from CNC to CNOC - Update default app package name to cnoc-default-app - Avoid conflict with existing nginx container (cnc) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
Cloud Node Container
This is a base container for running Node.js applications, supporting multiple Node.js versions (18, 20, 22). The default is Node.js 20. The container is based on AlmaLinux 9 and uses Nginx as a reverse proxy with SSL. It is designed for both development and production use.
You must have Docker or compatible containerization software running.
What's Included?
- Multiple Node.js Versions: 18, 20, 22 (set with
NODEVERor-aflag) - PM2 Process Manager: For production-grade Node.js application management
- Nginx Reverse Proxy: SSL-enabled reverse proxy with automatic HTTP to HTTPS redirect
- Development Features: Memcached for sessions, automatic backups, log rotation
- Health Monitoring: Built-in
/pingendpoint for health checks
Quick Start: Local Development with local-dev.sh
The easiest way to start a local development environment is with the provided local-dev.sh script. This script automates container setup, volume creation, log directories, and creates a sample Node.js application.
Usage Example
./local-dev.sh -n local-dev
Flags:
-nName of the container (required)-pHTTP port (default: 80)-sHTTPS port (default: 443)-rRoot path for files (default: current directory)-aNode.js version (default: 20; options: 18, 20, 22)-vEnable verbose mode-hShow help
The script will:
- Create a user directory and log folders
- Create a default Node.js Express application if none exists
- Start the container with the correct environment variables
- Generate helper scripts in your root path:
instance_start– Start the containerinstance_stop– Stop the containerinstance_logs– View container logsinstance_shell– Access container shell
Manual Docker Usage
You can also run the container manually:
mkdir -p local-development/domain.tld
cd local-development/domain.tld
mkdir user
mkdir -p user/{app,logs/{nginx,nodejs}}
docker run -d -p 80:80 -p 443:443 -e NODEVER=20 -e environment=DEV --mount type=bind,source="$(pwd)"/user,target=/home/$(whoami) -e uid=$(id -u) -e user=$(whoami) -e domain=localhost --name local-dev repo.anhonesthost.net/cloud-hosting-platform/cnoc:latest
Accessing the Container
docker exec -it local-dev /bin/bash
For Users: How to Deploy Your Application
Step 1: Prepare Your Node.js Application
Your Node.js application needs just two files to get started:
Required Files:
package.json- Describes your app and its dependencies- A main JavaScript file (usually
server.jsorindex.js)
Optional Files:
public/folder for static files (HTML, CSS, images)ecosystem.config.jsfor advanced PM2 configuration
Step 2: What Users Need to Do
If you're not familiar with Node.js, here's what you need to know:
- Create a
package.jsonfile - This tells Node.js about your app:
{
"name": "my-website",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.18.2"
}
}
- Create your main server file - This runs your application:
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.static('public')); // Serve static files
app.get('/', (req, res) => {
res.send('<h1>My Website is Running!</h1>');
});
app.get('/ping', (req, res) => {
res.json({ status: 'ok' }); // Health check for the container
});
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
-
Put your files in the right place:
- Copy your
package.jsonandserver.jstouser/app/ - Put HTML, CSS, images in
user/app/public/
- Copy your
-
Start the container:
./local-dev.sh -n my-app
That's it! The container will:
- Install your dependencies automatically
- Start your application with PM2
- Handle SSL and reverse proxy
- Provide health monitoring
Step 3: Example Applications
See the examples/ directory for complete working examples:
Simple Website (examples/simple-website/):
- Static HTML pages with navigation
- CSS styling
- Express.js server for routing
API Server (examples/api-server/):
- REST API with CRUD operations
- JSON responses
- In-memory data storage
What Happens Automatically
When you place your app in user/app/, the container automatically:
- Runs
npm installto install dependencies - Starts your app with PM2 process manager
- Sets up Nginx reverse proxy with SSL
- Configures logging and health checks
- Starts Memcached for session storage (in DEV mode)
Troubleshooting for New Users
- App won't start? Check that your
package.jsonhas a valid "start" script - Can't access your site? Make sure your app listens on port 3000 and has a
/pingendpoint - Dependencies missing? List all required packages in your
package.jsondependencies section - Static files not loading? Put them in a
public/folder and useapp.use(express.static('public'))
Features
- Multiple Node.js Versions: 18, 20, 22 (set with
NODEVERenvironment variable) - Process Management: PM2 for production-grade Node.js application management
- Reverse Proxy: Nginx handles SSL termination and proxies requests to Node.js
- Automatic Backups: Application files backed up every 30 minutes in DEV mode
- Log Management: Log rotation compresses logs older than 3 days, deletes after 7 days
- Session Storage: Memcached available in DEV mode for session management
- SSL: Self-signed certificate enabled by default with automatic HTTP→HTTPS redirect
- Health Checks:
/ping,/infoendpoints for monitoring - Static Files: Nginx serves static files from
/home/$user/app/public/
Environment Variables
Required:
uid– User ID for file permissionsuser– Username for file permissionsdomain– Primary domain for configuration
Optional:
environment– Set toDEVto start Redis and enable development featuresserveralias– Comma-separated list of alternative hostnamesNODEVER– Node.js version (18, 20, 22)
Default Application Endpoints
The default Express.js application provides:
/– Basic application info and status/ping– Health check endpoint (JSON response)/info– Detailed system information/session– Session demo endpoint (shows Memcached sessions working)
Helpful Notes
- To restart the instance:
./instance_startordocker start {container-name} - To stop:
./instance_stopordocker stop {container-name} - To view logs:
./instance_logsordocker logs -f {container-name} - To access shell:
./instance_shellordocker exec -it {container-name} /bin/bash - To delete a container:
docker rm {container-name}(does not delete user files) - Application logs are in
/home/$user/logs/nodejs/ - Nginx logs are in
/home/$user/logs/nginx/
System Requirements
Memory Requirements
- Minimum RAM: 256MB (basic applications)
- Recommended RAM: 512MB (standard applications)
- Development: 512MB-1GB (with all services enabled)
The container is optimized for memory efficiency with automatic memory management and process restarts. See MEMORY-GUIDE.md for detailed memory optimization information.
Performance Features
- Automatic application restart at 256MB memory usage
- V8 heap limited to 200MB by default
- Nginx optimized for single-worker, low-memory operation
- Memcached limited to 32MB cache size
Troubleshooting
- The first run may take a few minutes as Node.js and dependencies are installed
- If you need to change Node.js version, stop and remove the container, then recreate with the desired version
- For custom applications, ensure your
package.jsonhas a valid start script - Check
/home/$user/logs/nodejs/error.logfor application errors - The health check endpoint
/pingshould return a 200 status when the application is running properly - Memory issues: Run
/scripts/memory-info.shinside container to check memory usage - Process monitoring: Use
pm2 monitto watch application performance