Skip to main content

CRUD Application Example

This example demonstrates how to use systemg to manage a production-ready Node.js CRUD application with automated testing, database backups, rolling deployments, and Slack notifications.

Overview

This example showcases advanced systemg features:

  • Zero-downtime deployments with rolling_start strategy
  • Scheduled cron jobs for automated testing and database backups
  • Webhook notifications to Slack for operational awareness
  • Environment variable management for secure configuration
  • Comprehensive restart policies for service reliability

Application Setup

The example includes a standard Node.js/Express application with:

  • REST API with CRUD endpoints (GET, POST, PUT, DELETE)
  • PostgreSQL database integration
  • Automated test suite
  • Database backup scripts

The application code itself is intentionally simple to keep the focus on systemg configuration.

Configuration File

The complete systemg configuration is in crud.sysg.yaml:

Environment Configuration

version: "1"

env:
file: ".env.example"

What this does:

  • version: "1": Specifies the configuration schema version
  • env.file: Loads all environment variables from .env.example file, making them available to all services and cron jobs

Web Server Service

services:
node__web_server:
command: "node server.js"
deployment_strategy: "rolling_start"
env:
vars:
NODE_ENV: "${NODE_ENV}"
PORT: "${PORT}"
DATABASE_URL: "${DATABASE_URL}"
restart_policy: "on_failure"
retries: "10"
backoff: "10s"

Configuration breakdown:

  • node__web_server: Service identifier used in commands like sysg logs node__web_server
  • command: "node server.js": The command to execute to start the service
  • deployment_strategy: "rolling_start": Enables zero-downtime deployments by:
    1. Starting the new version of the service
    2. Waiting for it to become healthy
    3. Stopping the old version
    4. This ensures no dropped requests during deployments
  • env.vars: Service-specific environment variables that override or supplement the global env
    • NODE_ENV: Application environment (development, staging, production)
    • PORT: The port the web server listens on
    • DATABASE_URL: PostgreSQL connection string
  • restart_policy: "on_failure": Automatically restart if the service exits with non-zero status
  • retries: "10": Maximum number of restart attempts before marking service as failed
  • backoff: "10s": Wait 10 seconds between restart attempts to avoid rapid restart loops

Deployment Webhooks

    webhooks:
on_success:
url: "${SLACK_WEBHOOK_SUCCESS_URL}"
method: "POST"
headers:
Content-Type: "application/json"
body: |
{
"text": "✅ CRUD API deployment successful - Web server is running",
...
}
on_error:
url: "${SLACK_WEBHOOK_ERROR_URL}"
method: "POST"
headers:
Content-Type: "application/json"
body: |
{
"text": "❌ CRUD API deployment failed - Web server encountered an error",
...
}

Configuration breakdown:

  • webhooks.on_success: Triggered when the service successfully starts
    • url: Slack webhook URL for success notifications
    • method: "POST": HTTP method for the webhook request
    • headers: HTTP headers, here specifying JSON content
    • body: JSON payload sent to Slack with deployment details
  • webhooks.on_error: Triggered when the service fails to start
    • Sends critical alerts to a different Slack channel or with mentions (<!channel>)
    • Enables immediate response to deployment failures

Automated Test Suite (Cron Job)

cron:
test_suite:
schedule: "0 * * * *"
command: "npm test"
env:
vars:
DATABASE_URL: "${TEST_DATABASE_URL}"
NODE_ENV: "test"

Configuration breakdown:

  • test_suite: Identifier for this cron job
  • schedule: "0 * * * *": Cron expression meaning "run at minute 0 of every hour"
    • Format: minute hour day month weekday
    • This runs hourly: 00:00, 01:00, 02:00, etc.
  • command: "npm test": Executes the test suite defined in package.json
  • env.vars: Job-specific environment variables
    • DATABASE_URL: Points to test database instead of production
    • NODE_ENV: "test": Ensures tests run in test mode

The test suite also includes on_success and on_error webhooks to notify the team of test results.

Database Backup (Cron Job)

  database_backup:
schedule: "0 */6 * * *"
command: "bash scripts/backup-database.sh"
env:
vars:
DATABASE_URL: "${DATABASE_URL}"
BACKUP_S3_BUCKET: "${BACKUP_S3_BUCKET}"
AWS_ACCESS_KEY_ID: "${AWS_ACCESS_KEY_ID}"
AWS_SECRET_ACCESS_KEY: "${AWS_SECRET_ACCESS_KEY}"
BACKUP_RETENTION_DAYS: "${BACKUP_RETENTION_DAYS}"

Configuration breakdown:

  • database_backup: Identifier for the backup job
  • schedule: "0 */6 * * *": Cron expression meaning "run every 6 hours"
    • Executes at: 00:00, 06:00, 12:00, 18:00 daily
    • Provides 4 backup points per day for disaster recovery
  • command: Runs the backup script that creates PostgreSQL dump and uploads to S3
  • env.vars: Credentials and configuration for backup operations
    • DATABASE_URL: Database to back up
    • BACKUP_S3_BUCKET: S3 bucket name for storing backups
    • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: AWS credentials for S3 access
    • BACKUP_RETENTION_DAYS: How long to keep old backups before deletion

Critical on_success and on_error webhooks notify the team of backup status, with on_error using <!channel> for urgent alerts.

Environment Variables

The .env.example file defines all required variables:

# Application Configuration
NODE_ENV=
PORT=

# Database Configuration
DATABASE_URL=
TEST_DATABASE_URL=

# Backup Configuration
BACKUP_S3_BUCKET=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
BACKUP_RETENTION_DAYS=

# Slack Webhook URLs for Notifications
SLACK_WEBHOOK_SUCCESS_URL=
SLACK_WEBHOOK_ERROR_URL=

What each variable controls:

  • NODE_ENV: Sets the application environment (development, staging, production)
  • PORT: Port number for the web server (e.g., 3000, 8080)
  • DATABASE_URL: PostgreSQL connection string (e.g., postgresql://user:pass@localhost:5432/dbname)
  • TEST_DATABASE_URL: Separate database for running tests
  • BACKUP_S3_BUCKET: S3 bucket name (e.g., my-app-backups)
  • AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY: AWS credentials with S3 write permissions
  • BACKUP_RETENTION_DAYS: Days to retain old backups (e.g., 30)
  • SLACK_WEBHOOK_SUCCESS_URL: Slack incoming webhook for success notifications
  • SLACK_WEBHOOK_ERROR_URL: Slack incoming webhook for error/critical alerts

Running the Example

  1. Setup environment:

    cd examples/crud
    cp .env.example .env
    # Edit .env with your actual values
  2. Install dependencies:

    npm install
  3. Start with systemg:

    sysg start
  4. Check status:

    sysg status
  5. View logs:

    sysg logs node__web_server
  6. Test the API:

    curl http://localhost:3000/api/items

Key Features Demonstrated

1. Rolling Deployments

When you update your code and restart the service, rolling_start ensures:

  • No connection errors for active users
  • Graceful transition between versions
  • Automatic rollback if new version fails health checks

2. Automated Testing

Hourly test execution helps:

  • Catch issues early, even in production
  • Monitor API health continuously
  • Get immediate alerts if tests fail

3. Database Backups

Regular automated backups ensure:

  • Protection against data loss
  • Compliance with backup policies
  • Point-in-time recovery capabilities
  • Automated cleanup of old backups

4. Operational Notifications

Slack webhooks provide:

  • Real-time deployment status
  • Test suite results
  • Backup completion confirmations
  • Critical alerts for failures

What You Learned

In this example, you learned how to:

  • ✅ Implement zero-downtime deployments with rolling_start
  • ✅ Schedule automated tasks using cron syntax
  • ✅ Configure webhook notifications for operational events
  • ✅ Manage environment variables securely
  • ✅ Set up comprehensive restart policies
  • ✅ Separate concerns between services and scheduled jobs
  • ✅ Build production-ready service configurations

Next Steps

  • Customize the webhook payloads for your notification system
  • Add more cron jobs for other operational tasks (log rotation, cache clearing, etc.)
  • Implement health check endpoints for better rolling deployment detection
  • Add monitoring and alerting for service metrics
  • Explore other systemg features in the documentation