Skip to content

Vix Production Simplicity Checklist

This checklist comes from analyzing PulseGrid running in production. PulseGrid showed an important reality:

Vix can build and run a real C++ backend, but production still requires too much manual work. The goal of this checklist is to make Vix extremely simple for real production apps. A developer should be able to build, run, deploy, inspect, debug, and operate a Vix app without manually wiring systemd, Nginx, logs, health checks, ports, services, and production diagnostics.


1. Production diagnosis

Goal

Vix should understand the production state of an app. A command like this should exist:

bash
vix doctor production

It should inspect the current project and report:

txt
App: PulseGrid
Status: running
Binary: build-ninja/PulseGrid
Service: pulsegrid.service
HTTP port: 8080
WebSocket port: 9090
Public URL: https://pulsegrid.softadastra.com
Proxy: nginx
TLS: enabled
Healthcheck: ok
Logs: available

Checklist

  • [x] Detect project name from vix.json, vix.app, PulseGrid.vix, or CMake target.
  • [x] Detect build directory.
  • [x] Detect executable path.
  • [x] Detect whether the binary exists.
  • [x] Detect whether the binary is currently running.
  • [x] Detect systemd service linked to the app.
  • [x] Detect service status.
  • [x] Detect service restart policy.
  • [x] Detect app working directory from systemd.
  • [x] Detect environment variables from systemd.
  • [x] Detect HTTP listening port.
  • [x] Detect WebSocket listening port.
  • [x] Detect Nginx config for the app domain.
  • [x] Detect proxy target.
  • [x] Detect TLS certificate presence.
  • [x] Detect local health endpoint.
  • [x] Detect public HTTPS health.
  • [x] Show clear errors with fixes.

2. Service management

Goal

Vix should manage production services directly. Current PulseGrid production setup uses a manual systemd service. Vix should provide:

bash
vix service install
vix service start
vix service stop
vix service restart
vix service status
vix service logs

Checklist

  • [x] Generate a systemd service from project config.
  • [x] Support app name.
  • [x] Support working directory.
  • [x] Support executable path.
  • [x] Support user.
  • [x] Support environment variables.
  • [x] Support restart policy.
  • [x] Support restart delay.
  • [x] Support file descriptor limit.
  • [x] Support reload after service generation.
  • [x] Support service enable on boot.
  • [x] Support service restart.
  • [x] Support service status.
  • [x] Support service logs through journalctl.
  • [x] Warn when service points to an old build directory.
  • [x] Warn when service uses a different Vix installation than the current CLI.

Example generated service:

ini
[Unit]
Description=PulseGrid
After=network.target

[Service]
User=gaspard
WorkingDirectory=/home/gaspard/PulseGrid
Environment=Vix_DIR=/home/gaspard/vix-clean/build-ninja
Environment=CMAKE_PREFIX_PATH=/home/gaspard/vix-clean/build-ninja
ExecStart=/home/gaspard/PulseGrid/build-ninja/PulseGrid
Restart=always
RestartSec=3
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target

3. Reverse proxy management

Goal

Vix should make Nginx setup simple. PulseGrid manually uses:

txt
HTTP app port: 8080
WebSocket port: 9090
Domain: pulsegrid.softadastra.com
TLS: Let's Encrypt

Vix should provide:

bash
vix proxy nginx init
vix proxy nginx check
vix proxy nginx reload

Checklist

  • [x] Generate an Nginx config for a Vix app.
  • [x] Support HTTP proxy.
  • [x] Support WebSocket proxy.
  • [x] Support custom WebSocket path such as /ws.
  • [x] Support HTTPS redirect.
  • [x] Support TLS certificate paths.
  • [x] Validate TLS certificate file.
  • [x] Detect invalid PEM X.509 certificate.
  • [x] Detect expired TLS certificate.
  • [x] Detect TLS certificate domain mismatch.
  • [x] Support automatic Let's Encrypt / Certbot integration.
  • [x] Validate Nginx config before reload.
  • [x] Detect wrong upstream port.
  • [x] Detect missing WebSocket upgrade headers.
  • [x] Detect missing X-Forwarded-* headers.
  • [x] Detect missing proxy timeouts.
  • [x] Detect inactive site symlink.
  • [x] Show exact command to fix the proxy.

Example production config Vix should generate:

nginx
server {
    listen 80;
    listen [::]:80;
    server_name pulsegrid.softadastra.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name pulsegrid.softadastra.com;

    ssl_certificate /etc/letsencrypt/live/pulsegrid.softadastra.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pulsegrid.softadastra.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        proxy_set_header Connection "";
        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;

        proxy_connect_timeout 10s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }

    location = /ws {
        proxy_pass http://127.0.0.1:9090/;
        proxy_http_version 1.1;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        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;

        proxy_read_timeout 3600s;
        proxy_send_timeout 3600s;
        proxy_buffering off;
    }
}

4. Health checks

Goal

Vix should not only build the app. It should verify that the app is alive. PulseGrid currently uses a manual deploy script with:

bash
curl -I http://127.0.0.1

That checks Nginx, not necessarily the internal app.

Vix should provide:

bash
vix health
vix health local
vix health public

Checklist

  • [x] Check local app endpoint directly.
  • [x] Check public HTTPS endpoint.
  • [x] Check WebSocket endpoint.
  • [x] Verify expected HTTP status.
  • [x] Verify response time.
  • [x] Verify TLS availability.
  • [x] Verify service is running before health request.
  • [x] Print clear result.
  • [x] Fail with non-zero exit code when unhealthy.
  • [x] Support health config in vix.json.

Example:

json
{
  "production": {
    "health": {
      "local": "http://127.0.0.1:8080/",
      "public": "https://pulsegrid.softadastra.com/",
      "websocket": "wss://pulsegrid.softadastra.com/ws"
    }
  }
}

5. Deployment workflow

Goal

A Vix production app should not need a custom deploy.sh for basic deployment. PulseGrid currently does:

bash
git pull origin main
vix build --with-sqlite
sudo systemctl restart pulsegrid
sudo systemctl is-active pulsegrid
curl -I http://127.0.0.1

Vix should provide:

bash
vix deploy

Checklist

  • [x] Pull latest code optionally.
  • [x] Build app with correct preset/options.
  • [x] Run tests optionally.
  • [x] Restart systemd service.
  • [x] Verify service status.
  • [x] Run local health check.
  • [x] Run public health check.
  • [x] Show last logs on failure.
  • [x] Roll back later if needed.
  • [x] Support dry run.
  • [x] Support verbose mode.
  • [x] Support production config from vix.json.

Example production deployment config:

json
{
  "production": {
    "deploy": {
      "pull": true,
      "branch": "main",
      "build": "vix build --with-sqlite",
      "service": "pulsegrid",
      "health": "http://127.0.0.1:8080/"
    }
  }
}

6. Production logs

Goal

Vix should centralize app logs, systemd logs, and proxy logs. PulseGrid logs are currently split between:

txt
journalctl -u pulsegrid
/var/log/nginx/pulsegrid.access.log
/var/log/nginx/pulsegrid.error.log

Vix should provide:

bash
vix logs
vix logs app
vix logs proxy
vix logs errors

Checklist

  • [x] Show systemd app logs.
  • [x] Show Nginx access logs.
  • [x] Show Nginx error logs.
  • [x] Filter by errors.
  • [x] Filter by time.
  • [x] Follow logs live.
  • [x] Show last N lines.
  • [x] Detect repeated errors.
  • [x] Group common network disconnects.
  • [x] Hide normal disconnect noise by default.
  • [x] Support JSON logs later.

Example:

bash
vix logs --since "1 hour ago"
vix logs --follow
vix logs --errors

7. Network error classification

Goal

Vix should not treat normal client disconnects as production errors. PulseGrid revealed repeated logs like:

txt
[session] write error: Broken pipe

This usually means the client closed the connection before the server finished writing. Vix already handles normal disconnects while reading. The same logic must be applied during response writing.

Checklist

  • [x] Detect normal disconnects in HTTP read path.
  • [x] Detect normal disconnects in HTTP response write path.
  • [x] Log client disconnects at Debug level.
  • [x] Keep unexpected write failures at Error level.
  • [x] Apply similar logic to WebSocket writes.
  • [x] Classify common errors:
    • [x] Broken pipe
    • [x] Connection reset by peer
    • [x] Operation canceled
    • [x] EOF
  • [x] Add tests for response write disconnects.
  • [x] Add tests for WebSocket disconnects.
  • [x] Avoid noisy logs in production.
  • [x] Improve log messages with context.

Expected behavior:

txt
[session] client disconnected during response write: Broken pipe

instead of:

txt
[session] write error: Broken pipe

8. WebSocket production support

Goal

Vix should provide stronger production support for WebSocket apps. PulseGrid uses a live WebSocket endpoint for realtime status updates. Vix should make this easier to operate and debug.

Checklist

8. WebSocket production support

  • [x] Detect WebSocket port.
  • [x] Detect WebSocket route/path.
  • [x] Validate Nginx WebSocket proxy config. // via vix proxy nginx check
  • [x] Detect missing upgrade headers.
  • [x] Provide WebSocket health check.
  • [x] Provide active session count.
  • [x] Provide disconnect reason classification.
  • [x] Provide heartbeat diagnostics. // diagnostic temporaire, ping natif désactivé
  • [x] Provide backpressure or slow-client protection.
  • [x] Avoid logging normal disconnects as errors.
  • [x] Add vix ws check.

Example:

bash
vix ws check wss://pulsegrid.softadastra.com/ws

9. Static files and public assets

Goal

Vix should make backend apps with static files easy.

PulseGrid has:

txt
public/index.html
public/app.css
public/app.js
public/status.html
public/status.css
public/status.js

Vix should support this as a first-class backend app pattern.

Checklist

  • [ ] Detect public/.
  • [ ] Serve static files easily.
  • [ ] Support cache headers.
  • [ ] Support static file compression later.
  • [ ] Support SPA fallback.
  • [ ] Support public asset diagnostics.
  • [ ] Warn when public files are missing.
  • [ ] Add backend template with static UI.

10. SQLite and storage

Goal

Vix should simplify apps that use SQLite in production.

PulseGrid uses:

txt
storage/pulsegrid.db
storage/pulsegrid.db-shm
storage/pulsegrid.db-wal
migrations/

Vix should understand this pattern.

Checklist

  • [x] Detect SQLite usage.
  • [x] Detect database path.
  • [x] Detect WAL mode files.
  • [x] Detect storage directory.
  • [x] Warn if storage directory is missing.
  • [x] Warn if permissions are wrong.
  • [x] Support migrations directory.
  • [x] Add vix db status.
  • [x] Add vix db migrate later.
  • [x] Add backup helper later.

Example:

bash
vix db status

Expected output:

txt
Database: storage/pulsegrid.db
WAL: enabled
Migrations: migrations/
Status: ok

11. Environment management

Goal

Vix should make .env usage simple and visible.

PulseGrid has:

txt
.env
.env.example

Vix should help verify production environment variables.

Checklist

  • [x] Detect .env.
  • [x] Detect .env.example.
  • [x] Compare missing variables.
  • [x] Show which variables are loaded.
  • [x] Never print secrets by default.
  • [x] Support masked output.
  • [x] Validate required production env vars.
  • [x] Warn when systemd env differs from project env.
  • [x] Add vix env check.

Example:

bash
vix env check --production

12. Production config in vix.json

Goal

Vix needs one clear place to describe production.

A future vix.json should support:

json
{
  "name": "PulseGrid",
  "production": {
    "service": {
      "name": "pulsegrid",
      "user": "gaspard",
      "working_dir": "/home/gaspard/PulseGrid",
      "exec": "build-ninja/PulseGrid",
      "restart": "always",
      "restart_sec": 3,
      "limit_nofile": 65535
    },
    "ports": {
      "http": 8080,
      "websocket": 9090
    },
    "proxy": {
      "type": "nginx",
      "domain": "pulsegrid.softadastra.com",
      "tls": true,
      "websocket_path": "/ws"
    },
    "health": {
      "local": "http://127.0.0.1:8080/",
      "public": "https://pulsegrid.softadastra.com/",
      "websocket": "wss://pulsegrid.softadastra.com/ws"
    },
    "logs": {
      "app": "journalctl -u pulsegrid",
      "proxy_access": "/var/log/nginx/pulsegrid.access.log",
      "proxy_error": "/var/log/nginx/pulsegrid.error.log"
    }
  }
}

Checklist

  • [x] Define production schema.
  • [x] Validate production schema.
  • [x] Keep config simple.
  • [x] Avoid too much magic.
  • [x] Generate systemd from config.
  • [x] Generate Nginx from config.
  • [x] Run health checks from config.
  • [x] Show production status from config.

13. Backend production template

Goal

PulseGrid shows the architecture Vix should encourage for serious backend apps.

Current structure:

txt
src/pulsegrid/
  app/
  application/
  domain/
  infrastructure/
  presentation/
  support/
public/
storage/
migrations/
tests/

Vix should provide:

bash
vix new myapp --template backend

Checklist

  • [x] Generate clean main.cpp.
  • [x] Generate AppBootstrap.
  • [x] Generate route registry.
  • [x] Generate middleware registry.
  • [x] Generate health controller.
  • [x] Generate static public folder.
  • [x] Generate storage folder.
  • [x] Generate migrations folder.
  • [x] Generate tests folder.
  • [x] Generate vix.json.
  • [x] Generate vix.app.
  • [x] Generate production config scaffold.
  • [x] Keep main() minimal.

Example main.cpp:

cpp
#include <myapp/app/AppBootstrap.hpp>

int main()
{
  myapp::app::AppBootstrap bootstrap;
  return bootstrap.run();
}

14. Build/install confusion detection

Goal

Vix should detect when the CLI and libraries come from different directories. PulseGrid revealed this situation:

txt
CLI:
  /home/gaspard/vix/build/vix

App build libraries:
  /home/gaspard/vix-clean/build-ninja

This can be confusing.

Vix should warn when:

txt
vix command != Vix_DIR used by project/service

Checklist

  • [x] Detect current vix binary path.
  • [x] Detect Vix_DIR.
  • [x] Detect CMAKE_PREFIX_PATH.
  • [x] Detect Vix version used by CLI.
  • [ ] Detect Vix version used by project build.
  • [x] Warn when they differ.
  • [x] Suggest exact fix.
  • [x] Add vix doctor toolchain.

Example warning:

txt
warning: Vix CLI and Vix libraries come from different installations

CLI:
  /home/gaspard/vix/build/vix

CMake package:
  /home/gaspard/vix-clean/build-ninja

This can cause confusing builds.

15. Better deploy script generation

Status

Replaced by vix deploy.

The original goal was to generate a safe deployment script while the deployment workflow was incomplete. Since vix deploy now supports pull, build, tests, service restart, service status, health checks, proxy checks, logs on failure, dry-run, verbose mode, and production config from vix.json, a generated deploy script is no longer required for the v2.6 production workflow.

Checklist

  • [x] Replaced by vix deploy.
  • [x] Use production config from vix.json.
  • [x] Pull latest code optionally.
  • [x] Build app with correct command.
  • [x] Restart service through vix service.
  • [x] Run health checks through vix health.
  • [x] Validate proxy through vix proxy nginx check.
  • [x] Show logs on failure.

16. Production readiness score

Goal

Vix should provide a simple production readiness score.

bash
vix doctor production

Should produce:

txt
Production readiness: 82/100

OK  service installed
OK  service running
OK  nginx proxy configured
OK  TLS enabled
OK  local health check
OK  public health check
WARN websocket health not configured
WARN deploy rollback not configured

Checklist

  • [x] Define scoring rules.
  • [x] Show OK/WARN/FAIL.
  • [x] Keep output simple.
  • [x] Make fixes actionable.
  • [x] Do not hide important details.
  • [x] Support JSON output for CI.

17. Immediate fixes from PulseGrid

These are the first concrete improvements to implement in Vix.

Priority 1

  • [x] Fix HTTP response write disconnect logging.
  • [x] Move normal write disconnects to Debug level.
  • [x] Keep unexpected write failures at Error level.
  • [x] Add test for Broken pipe during response write.

Priority 2

  • [x] Add vix doctor production.
  • [x] Detect service, port, proxy, TLS, and health state.
  • [x] Detect CLI/library mismatch.

Priority 3

  • [x] Add vix logs.
  • [x] Read systemd logs.
  • [x] Read Nginx logs.
  • [x] Group common disconnect noise.

Priority 4

  • [x] Add vix service.
  • [x] Generate and manage systemd service.

Priority 5

  • [x] Add vix proxy nginx.
  • [x] Generate and validate Nginx config.

Priority 6

  • [x] Add vix deploy.
  • [x] Build, restart, health check, and show logs on failure.

18. Final product direction

PulseGrid proves that Vix should become:

A C++ runtime that makes production backend apps simple to build, run, deploy, inspect, and operate.

The developer experience should feel like:

bash
vix new pulsegrid --template backend
vix dev
vix test
vix build
vix service install
vix proxy nginx init
vix deploy
vix doctor production
vix logs

The long-term goal:

txt
No manual systemd.
No manual Nginx guessing.
No unclear ports.
No noisy logs.
No hidden build mismatch.
No weak health checks.
No confusing production state.

Vix should make a production C++ backend feel simple, visible, and reliable.

Last updated: