Production Proxy
The production proxy section describes how a public domain reaches your application process. In a typical Linux deployment, the C++ application listens on a local port such as 127.0.0.1:8080, while Nginx receives public HTTP or HTTPS traffic and forwards requests to that local upstream.
Vix uses the proxy metadata in vix.json to generate, install, check, reload, and maintain the Nginx configuration for the project. This is useful for projects generated by Vix templates, but it is not limited to them. An existing C++ service can keep its own build system and still use Vix to describe the public domain, upstream port, TLS certificate paths, and WebSocket forwarding rules.
Why the proxy section matters
A production service is rarely exposed directly to the internet. The application process should stay simple: it listens on a local port, serves HTTP, and focuses on application logic. Nginx handles the public edge: domain routing, HTTPS, forwarding headers, timeouts, and WebSocket upgrades when needed.
Without a project-level proxy file, these details often live only on the server, detached from the application repository. Vix keeps the proxy configuration close to the project so it can be reviewed, regenerated, checked, and used during deployment. The generated Nginx file is still a normal Nginx configuration; Vix simply produces it from the project metadata and validates that the installed file matches what the project expects.
Basic configuration
Proxy configuration lives under production.proxy in vix.json.
{
"name": "myapp",
"production": {
"proxy": {
"domain": "example.com",
"http": {
"port": 8080
},
"tls": {
"enabled": true,
"certificate": "/etc/letsencrypt/live/example.com/fullchain.pem",
"certificate_key": "/etc/letsencrypt/live/example.com/privkey.pem"
}
}
}
}This configuration tells Vix that public traffic for example.com should be proxied to the local application running on port 8080. When TLS is enabled, Vix expects certificate files to be available and writes an HTTPS Nginx configuration with an HTTP-to-HTTPS redirect.
Fields
| Field | Purpose |
|---|---|
domain | Public domain handled by the generated Nginx site. |
http.port | Local HTTP port where the application listens. |
websocket.enabled | Enables a WebSocket proxy location. |
websocket.path | Public WebSocket path, usually /ws. |
websocket.port | Local WebSocket upstream port. |
tls.enabled | Enables HTTPS and HTTP-to-HTTPS redirect. |
tls.certificate | Path to the TLS certificate file. |
tls.certificate_key | Path to the TLS private key file. |
The domain and HTTP port are the core fields. WebSocket and TLS settings should be added only when the application actually needs them.
Plain HTTP proxy
For an internal server, staging environment, or first setup before TLS, the proxy can start with plain HTTP.
{
"production": {
"proxy": {
"domain": "example.com",
"http": {
"port": 8080
},
"tls": {
"enabled": false
}
}
}
}Then initialize the Nginx configuration:
vix proxy nginx initVix writes a site configuration under the Nginx sites directory, enables it, validates Nginx with nginx -t, and reloads the server when the configuration is valid.
HTTPS proxy
For a public application, TLS should normally be enabled.
{
"production": {
"proxy": {
"domain": "example.com",
"http": {
"port": 8080
},
"tls": {
"enabled": true,
"certificate": "/etc/letsencrypt/live/example.com/fullchain.pem",
"certificate_key": "/etc/letsencrypt/live/example.com/privkey.pem"
}
}
}
}When TLS is enabled, the generated configuration contains two server blocks: one for port 80 that redirects to HTTPS, and one for port 443 that proxies requests to the local application. Vix also checks that the installed Nginx file contains the expected certificate paths.
If the certificate and key paths are omitted while TLS is enabled, Vix resolves the usual Let's Encrypt paths from the domain:
/etc/letsencrypt/live/<domain>/fullchain.pem
/etc/letsencrypt/live/<domain>/privkey.pemThis keeps the configuration short when the server uses Certbot with the standard directory layout.
WebSocket proxy
If the application exposes a WebSocket server, add a websocket object to the proxy section.
{
"production": {
"proxy": {
"domain": "example.com",
"http": {
"port": 8080
},
"websocket": {
"enabled": true,
"path": "/ws",
"port": 9090
},
"tls": {
"enabled": true
}
}
}
}With this configuration, normal HTTP traffic is forwarded to 127.0.0.1:8080, while WebSocket traffic at /ws is forwarded to 127.0.0.1:9090. Vix writes the required upgrade headers, disables buffering for the WebSocket location, and uses longer WebSocket timeouts.
The WebSocket path should match the route exposed by the application or WebSocket server. If the path is written without a leading slash, Vix normalizes it before generating the proxy configuration.
Commands
The proxy workflow is grouped under the Nginx provider.
vix proxy nginx init
vix proxy nginx check
vix proxy nginx reload
vix proxy nginx certbotvix proxy nginx init generates the Nginx site file, installs it, enables the site, validates Nginx, and reloads the server.
vix proxy nginx check inspects the installed configuration and verifies the important parts: domain, upstream ports, forwarding headers, timeout settings, WebSocket rules when enabled, TLS certificate paths when enabled, and the Nginx syntax test.
vix proxy nginx reload runs the proxy check first. If the check passes, it reloads Nginx. This avoids reloading a broken configuration.
vix proxy nginx certbot prepares a temporary HTTP configuration, runs Certbot for the configured domain, then installs the final TLS proxy configuration after the certificate has been issued or renewed.
Certbot workflow
When a domain points to the server and Nginx is installed, Vix can call Certbot for the configured domain.
vix proxy nginx certbotThe command expects nginx and certbot to be available on the server. It first installs an HTTP configuration so Certbot can complete the domain challenge, then it runs Certbot with the Nginx plugin. After the certificate exists, Vix installs the final TLS configuration and reloads Nginx.
A typical proxy section for this workflow can omit explicit certificate paths:
{
"production": {
"proxy": {
"domain": "example.com",
"http": {
"port": 8080
},
"tls": {
"enabled": true
}
}
}
}Vix will use the standard Let's Encrypt paths after Certbot completes.
Proxy and health checks
The proxy section should be paired with a health section. The proxy can be valid while the application is still failing behind it, so production checks should verify both the Nginx configuration and the application endpoint.
{
"production": {
"health": {
"service": "myapp",
"local": "http://127.0.0.1:8080/health",
"public": "https://example.com/health",
"expected_status": 200,
"timeout_ms": 2000,
"max_response_ms": 1000
}
}
}Then run:
vix proxy nginx check
vix healthThe proxy check validates the Nginx side. The health check validates that the application responds as expected through the configured endpoints.
Proxy and deployment
Deployment can include proxy validation and reload behavior.
{
"production": {
"deploy": {
"pull": true,
"branch": "main",
"build": "vix build --preset release",
"tests": false,
"service": "myapp",
"health_local": true,
"health_public": true,
"proxy_check": true,
"proxy_reload": false,
"logs_on_failure": true
}
}
}With proxy_check enabled, vix deploy validates the Nginx configuration after the service restart and health checks. proxy_reload should be enabled only when the deployment workflow is expected to reload Nginx as part of the release.
vix deploy --dry-run
vix deployUse the dry run first to see the steps Vix will execute before changing the server.
Using proxy files with an existing C++ project
An existing C++ project can use the proxy workflow without using Vix templates. The only requirement is that the project describes the real application port and domain in vix.json.
{
"name": "legacy-api",
"production": {
"service": {
"name": "legacy-api",
"user": "deploy",
"working_dir": "/srv/legacy-api",
"exec": "/srv/legacy-api/build/legacy-api"
},
"proxy": {
"domain": "api.example.com",
"http": {
"port": 8080
},
"tls": {
"enabled": true
}
},
"health": {
"service": "legacy-api",
"local": "http://127.0.0.1:8080/health",
"public": "https://api.example.com/health"
}
}
}The source tree can stay exactly as it is. Vix only uses the metadata to generate and validate the Nginx configuration around the deployed process.
Common problems
The most common proxy problems are not caused by C++ code. They usually come from mismatched ports, a domain that does not point to the server, missing certificate files, or an Nginx site file that was edited manually after generation.
When the proxy check fails, start with:
vix proxy nginx checkThen check the application itself:
vix service status
vix health localIf the local health check fails, fix the service or application before debugging the public proxy. If the local endpoint works but the public endpoint fails, inspect the Nginx configuration, DNS, TLS certificate, and firewall rules.
Practical workflow
A good first setup is to configure plain HTTP, initialize the proxy, verify the local application, then add TLS.
vix service status
vix health local
vix proxy nginx init
vix proxy nginx checkAfter DNS points to the server, enable TLS and run:
vix proxy nginx certbot
vix proxy nginx check
vix health publicKeep the proxy metadata close to the real server state. The domain should be the domain users will actually hit, the port should match the application process, and TLS paths should match the certificates installed on the server.
Next step
Continue with the health documentation to configure the local, public, and WebSocket checks that confirm the service and proxy are working together.