Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deployment

All Hone backend services run on a single server and are managed by systemd. TLS is terminated by nginx with Let’s Encrypt certificates.

Server

PropertyValue
IP84.32.223.50
OSUbuntu 24.04
Hostwebserver.skelpo.net

Services

ServiceBinary PathPortSystemd UnitDomain
Auth/opt/hone-auth/hone-auth8445hone-auth.serviceauth.hone.codes
Relay (HTTP)/opt/hone-relay/hone-relay8443hone-relay.servicesync.hone.codes
Relay (WS)(same binary)8444(same)sync.hone.codes/ws
Marketplace/opt/hone-marketplace/hone-marketplace8446hone-marketplace.servicemarketplace.hone.codes
Build/opt/hone-build/hone-build8447hone-build.service

DNS

A records pointing to 84.32.223.50:

  • auth.hone.codes
  • sync.hone.codes
  • marketplace.hone.codes

TLS

Certificates are provisioned by Let’s Encrypt via certbot and auto-renewed. nginx terminates TLS and proxies to the service ports over localhost HTTP.

nginx Configuration

Standard HTTP Service (Auth, Marketplace)

server {
    listen 443 ssl;
    server_name auth.hone.codes;

    ssl_certificate /etc/letsencrypt/live/auth.hone.codes/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/auth.hone.codes/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8445;
        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;
    }
}

WebSocket Service (Relay)

server {
    listen 443 ssl;
    server_name sync.hone.codes;

    ssl_certificate /etc/letsencrypt/live/sync.hone.codes/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sync.hone.codes/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8443;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

    location /ws {
        proxy_pass http://127.0.0.1:8444;
        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_read_timeout 86400s;
    }
}

The proxy_read_timeout on the WebSocket location prevents nginx from closing idle connections.

Systemd Units

Each service has a systemd unit file in /etc/systemd/system/.

Example: hone-auth.service

[Unit]
Description=Hone Auth Service
After=network.target mysql.service

[Service]
Type=simple
WorkingDirectory=/opt/hone-auth
ExecStart=/opt/hone-auth/hone-auth
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Common Operations

# Start a service
sudo systemctl start hone-auth

# Stop a service
sudo systemctl stop hone-auth

# Restart after deploying a new binary
sudo systemctl restart hone-auth

# View logs
sudo journalctl -u hone-auth -f

# Enable service on boot
sudo systemctl enable hone-auth

Database

MySQL runs on the same server (webserver.skelpo.net). Only the auth service connects to MySQL directly. The relay uses local SQLite.

PropertyValue
Hostwebserver.skelpo.net
Userhone
Databasehone

Landing Page

The landing page (hone.codes) is a static index.html with no build step:

scp landing/index.html root@webserver.skelpo.net:/var/www/hone.codes/

Deploying a New Binary

  1. Compile the package on the build machine:

    cd hone-auth && perry compile src/app.ts --output hone-auth
    
  2. Upload the binary:

    scp hone-auth root@webserver.skelpo.net:/opt/hone-auth/hone-auth
    
  3. Restart the service:

    ssh root@webserver.skelpo.net 'systemctl restart hone-auth'
    
  4. Verify:

    curl https://auth.hone.codes/health