v0.21

deployment

introduction

dframework is engineered for raw throughput and low latency execution. for production environments, dframework offers three deployment architectures:

  1. direct bare metal with native tls (default): single process architecture where the native transport addon handles openssl tls 1.3 termination, http to https redirects, and routing.
  2. reverse proxy (--proxy): traditional deployment behind caddy or nginx when sharing ports with other services or integrating with an existing proxy stack.
  3. edge deployment (--edge): running plain http behind cloudflare or another cdn where tls termination occurs at the edge.

deployment strategies

direct bare metal (default)

in direct bare metal mode, dframework binds port 443 with native openssl tls and simultaneously runs a lightweight listener on port 80 to redirect http traffic to https.

1[ client ] --( https:443 )--> [ dframework ssl app (native tls) ]
2[ client ] --( http:80 )----> [ dframework redirect app (301) ]

benefits:

reverse proxy with caddy

in reverse proxy mode, a dedicated web server such as caddy receives public https traffic on port 443 and proxies plain http requests over local loopback (127.0.0.1:825) to dframework.

1[ client ] --( https:443 )--> [ caddy ] --( loopback:825 )--> [ dframework ]

when to choose a reverse proxy:

edge deployment with cloudflare

in edge mode, cloudflare terminates public tls connections and forwards requests to your origin server over http or https.

1[ client ] --( https )--> [ cloudflare edge ] --( http/https )--> [ dframework ]

benefits:

automated deployment

the dstrn deploy command automates configuration generation, certificate provisioning, and service installation.

direct bare metal setup

to generate bare metal production configuration for your domain:

1dstrn deploy --domain=api.example.com --email=admin@example.com

for multi domain setups, provide comma separated domains:

1dstrn deploy --domain=api.example.com,admin.example.com --email=admin@example.com

this command performs the following actions:

  1. verifies or generates a production APP_KEY in .env.
  2. checks for existing certificates in storage/certs/{domain}/ and obtains missing certificates.
  3. creates deploy/dframework-<app>.service with AmbientCapabilities=CAP_NET_BIND_SERVICE so the application can bind ports 80 and 443 without root privileges.
  4. creates deploy/dframework-<app>-renew.timer and deploy/dframework-<app>-renew.service to automate weekly certificate renewal.

reverse proxy setup

to generate caddy and systemd service configurations:

1dstrn deploy --proxy --domain=api.example.com

this generates:

  1. deploy/Caddyfile with reverse proxy rules pointing to your application port.
  2. deploy/dframework-<app>.service configured for standard unprivileged execution.

edge setup

to generate systemd service files with cloudflare guidance:

1dstrn deploy --edge --domain=api.example.com

dry run preview

preview all generated service and configuration files in the terminal without writing to disk:

1dstrn deploy --domain=api.example.com --email=admin@example.com --dry-run

system installation

when running on your server with root privileges (sudo), dstrn deploy can write directly to /etc/systemd/system/ and activate the services:

1sudo dstrn deploy --domain=api.example.com --email=admin@example.com --install

manual deployment setup

if you prefer manual server provisioning or are using automation tools, follow these steps.

manual direct bare metal

place your ssl certificate and private key in the application storage directory:

1storage/certs/api.example.com/
2 cert.pem
3 key.pem

configure production environment variables in .env:

1APP_ENV=production
2APP_DEBUG=false
3APP_URL=https://api.example.com
4APP_KEY=your_64_character_hex_key

create /etc/systemd/system/dframework.service:

1[Unit]
2Description=dframework application server
3After=network.target
4
5[Service]
6Type=simple
7User=user
8WorkingDirectory=/var/www/app
9ExecStart=/usr/bin/node dstrn serve
10Restart=always
11RestartSec=3
12Environment=NODE_ENV=production
13AmbientCapabilities=CAP_NET_BIND_SERVICE
14
15[Install]
16WantedBy=multi-user.target

enable and start the service:

1sudo systemctl daemon-reload
2sudo systemctl enable dframework
3sudo systemctl start dframework

manual caddy reverse proxy

install caddy on debian or ubuntu:

1sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
2curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
3curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
4sudo apt update
5sudo apt install caddy

configure /etc/caddy/Caddyfile:

1api.example.com {
2 reverse_proxy 127.0.0.1:825
3}

reload caddy:

1sudo systemctl reload caddy

caddy will automatically obtain let's encrypt certificates for api.example.com, manage renewals, and proxy requests over loopback to dframework.

tls and certificate management

automatic certificate discovery

dframework automatically detects certificates in storage/certs/ upon startup:

1storage/certs/
2 api.example.com/
3 cert.pem (or fullchain.pem, certificate.crt, api.example.com.crt)
4 key.pem (or privkey.pem, private.key, api.example.com.key)
5 ca.pem (optional intermediate chain)
6 admin.example.com/
7 cert.pem
8 key.pem

when valid certificates are found and APP_URL starts with https://, dframework automatically boots with native openssl tls on port 443 and starts the http to https redirect listener on port 80.

certificate management commands

the dstrn cert command family provides management over the certificate lifecycle.

obtain certificates

obtain a new let's encrypt certificate for one or more domains:

1dstrn cert:obtain --domain=api.example.com --email=admin@example.com
TIP

test certificate generation with `--staging` before production issuance to avoid hitting let's encrypt rate limits during deployment validation.

1dstrn cert:obtain --domain=api.example.com --email=admin@example.com --staging

renew certificates

renew all certificates that expire within 30 days:

1dstrn cert:renew --domain=api.example.com --email=admin@example.com

inspect certificate status

check expiration dates, issuer information, and validity for all installed certificates:

1dstrn cert:status

multi domain and sni routing

the transport supports server name indication (sni). when multiple domain directories exist in storage/certs/, each domain receives its matching certificate during the tls handshake.

pair this with domain route groups in your application routes:

1Route.domain('api.example.com', (api) => {
2 api.get('/status', async () => json({ service: 'api' }));
3});
4
5Route.domain('admin.example.com', (admin => {
6 admin.get('/status', async () => json({ service: 'admin' }));
7});

http to https redirection

when tls is enabled, dframework automatically starts a native non ssl listener on port 80. any request to http://domain/path receives an immediate 301 Moved Permanently response pointing to https://domain/path.

to disable the redirect listener, set tls.redirect: false in config/app.js or TLS_REDIRECT=false in .env.

websocket secure connections

automatic wss promotion

the client automatically promotes websocket connections to wss:// whenever the page is loaded over https://.

because the initial page request is redirected from http to https, the browser always loads over https: and establishes a secure wss:// connection.

native websocket upgrades

on the server side, websocket connections over port 443 are handled directly inside the ssl event loop. the http upgrade handshake occurs over the existing encrypted tls connection, ensuring zero plaintext exposure and instant websocket availability.

systemd service setup

application service unit

the production systemd unit file (/etc/systemd/system/dframework.service):

1[Unit]
2Description=dframework application server
3After=network.target
4
5[Service]
6Type=simple
7User=ubuntu
8WorkingDirectory=/var/www/app
9ExecStart=/usr/bin/node dstrn serve
10Restart=always
11RestartSec=3
12Environment=NODE_ENV=production
13AmbientCapabilities=CAP_NET_BIND_SERVICE
14
15[Install]
16WantedBy=multi-user.target
NOTE

`AmbientCapabilities=CAP_NET_BIND_SERVICE` allows the systemd service to bind privileged low ports (80 and 443) while running under an unprivileged user account.

certificate renewal timer unit

automated certificate renewal uses a weekly systemd timer (/etc/systemd/system/dframework-renew.timer):

1[Unit]
2Description=certificate renewal timer for dframework
3
4[Timer]
5OnCalendar=weekly
6RandomizedDelaySec=3600
7Persistent=true
8
9[Install]
10WantedBy=timers.target

with the corresponding oneshot renewal service (/etc/systemd/system/dframework-renew.service):

1[Unit]
2Description=certificate renewal for dframework
3
4[Service]
5Type=oneshot
6WorkingDirectory=/var/www/app
7ExecStart=/usr/bin/node dstrn cert:renew --domain=api.example.com --email=admin@example.com
8ExecStartPost=/bin/systemctl restart dframework

enable the renewal timer with:

1sudo systemctl daemon-reload
2sudo systemctl enable dframework-renew.timer
3sudo systemctl start dframework-renew.timer

environment configuration

standard production .env configuration:

1APP_NAME=dframework
2APP_ENV=production
3APP_DEBUG=false
4APP_URL=https://api.example.com
5APP_KEY=your_generated_64_character_hex_key
6ACME_EMAIL=admin@example.com

optional explicit tls configuration (overrides auto discovery convention):

1TLS_CERT=storage/certs/api.example.com/cert.pem
2TLS_KEY=storage/certs/api.example.com/key.pem
3TLS_CA=storage/certs/api.example.com/ca.pem
4TLS_REDIRECT=true

performance considerations

traditional architectures place a reverse proxy like caddy or nginx in front of application runtimes. in benchmark measurements, a reverse proxy layer can potentially add over 60% of overhead for simple routes due to double socket buffering, process context switching, and loopback tcp serialization.

direct bare metal deployment eliminates intermediate proxy layers, delivering maximum throughput directly to the application event loop while maintaining automated let's encrypt certificate management and multi domain support.