❓ QWAY Studio HelpQWAY · WRIGHT · RIDLEY · RAMS

Deploy Studio: HTTPS, SMTP and backups

Recommended: clone and run the installation wizard

On Ubuntu 24.04 or newer with Git, sudo and an already running Nginx, use an SSH account authorized to read the repository:

Reference
git clone git@gitlab.wd3.fun:gitlab-instance-bd01154c/quay.git
cd quay
sudo ./qway install

The first invocation needs ./qway; installation then adds the global qway command. The wizard asks for domain, ingress mode, API/HTTP/HTTPS ports, certificate email and terms, SMTP settings and hidden mailbox password, an optional OpenAI key/model, and the initial administrator password. Choose nginx for shared host Nginx. It asks for the existing Linux user (defaulting to the sudo caller, for example ricardo) and reuses an existing Node executable, including nvm installations. Node 22.23.2 is supported; the minimum is 22.12. The absolute path and user are persisted for systemd, which exposes only the selected Node installation read-only inside its otherwise hidden home. Keep that version installed. No nvm or shell profile changes are needed. A private Node 24 download is available only by explicitly entering download at the prompt. It installs other dependencies, builds as the selected non-root user, prepares protected environment/vault settings, initializes ricardo@ricardopiana.com, configures Nginx/TLS/renewal/systemd and verifies production authentication. It does not change Node used by other services or require PostgreSQL/Redis.

Point DNS at the VPS and configure the provider firewall first. HTTP-01 needs public port 80; custom local HTTP ports require existing forwarding. The SMTP connection/login is checked without sending email: test registration and recovery after installation. Only committed files are installed; local project data, untracked files and .env are not copied.

Rerun sudo ./qway install from an updated clone to install its committed version. Existing secrets, vault keys, administrator passwords and data are preserved. Code is built in a new /opt/quay/releases directory before activation. Failure restores the previous code/static links and managed service configuration; prepared packages/data/certificates remain for retries. Back up before updates. Existing unmanaged installation paths are refused. The numbered sections below are an alternative manual installation and operational reference; do not repeat them after a successful wizard installation.

What you are deploying

This chapter deploys the private authoring service and public Studio homepage. Publishing a RAMS visitor website is a separate task described in RAMS publishing. Use a VPS with SSH/sudo, Python 3.12+, Node 22.12+, Nginx and persistent storage. A static-only or PHP-only hosting plan cannot run the Studio API.

The supplied configuration targets qway.ricardopiana.com and Register.it SMTP. Adapt the domain consistently for another installation. Start with at least 2 GB RAM; large scenes and builds may require more.

1. Prepare DNS and directories

Point the domain’s A record at the VPS. Add AAAA only when IPv6 works. Allow SSH and only the public ports selected in the installer. API ports stay on loopback; an existing HTTPS proxy can also keep the web listener private. On Ubuntu 24.04:

Reference
sudo apt update
sudo apt install git nginx python3.12 python3.12-venv build-essential snapd iproute2
sudo useradd --system --user-group --home-dir /var/lib/quay --create-home --shell /usr/sbin/nologin quay
sudo install -d -o quay -g quay -m 700 /var/lib/quay
sudo install -d -m 755 /opt/quay /var/www/quay
sudo install -d -m 700 /etc/quay

Install Node from an official distribution. It must be available to systemd in /usr/bin or /usr/local/bin; an nvm installation available only in your interactive shell is insufficient because the API invokes Node.

2. Install and build the application

Use your deployment user for the checkout/build and the separate quay user for the running service. Replace URL_OF_YOUR_REPOSITORY with your actual repository URL.

Reference
sudo chown "$USER" /opt/quay
git clone URL_OF_YOUR_REPOSITORY /opt/quay/current
cd /opt/quay/current
npx --yes npm@10.9.3 ci
python3.12 -m venv .venv
.venv/bin/pip install "setuptools>=75"
.venv/bin/pip install --no-build-isolation -e apps/api
npm run build
sudo cp -a apps/web/dist/. /var/www/quay/
sudo chmod -R a+rX /var/www/quay

Leave VITE_API_URL unset: the production browser uses /api/v2 on the same HTTPS origin. Do not serve the development Vite process in production. Only built web files belong in /var/www/quay; never put data, .env or keys there.

3. Configure production and SMTP

Reference
sudo install -m 600 deploy/production/quay.env.example /etc/quay/quay.env
sudoedit /etc/quay/quay.env
Environment
QUAY_ENV=production
QUAY_PUBLIC_ORIGIN=https://qway.ricardopiana.com
QUAY_ALLOWED_ORIGINS=https://qway.ricardopiana.com
QUAY_DATA_DIR=/var/lib/quay
QUAY_SMTP_HOST=authsmtp.securemail.pro
QUAY_SMTP_PORT=465
QUAY_SMTP_SSL=true
QUAY_SMTP_USER=ricardo@ricardopiana.com
QUAY_SMTP_FROM=ricardo@ricardopiana.com
QUAY_SMTP_PASSWORD="REPLACE_ON_SERVER"

Enter the real mailbox password only in that protected server file. Check the SMTP product, mailbox credentials and SPF/DKIM settings in the hosting panel. The sample leaves AI providers disabled; manual editing works. Add OPENAI_API_KEY and deliberately enable the providers if required. All users then consume the server’s provider account.

For RAMS credential storage without a native keyring, provide a Fernet QUAY_DEPLOY_VAULT_KEY through the server environment. Preserve it separately from the encrypted vault. Replacing it without migrating the vault makes existing secrets unreadable.

4. Choose ports and HTTPS routing

The production network installer asks for the domain, deployment mode, private API port, HTTP listener and public HTTPS port. First generate reviewable files without changing services:

Shell
python3 deploy/production/install.py --output /tmp/quay-config

For a server with a separately managed HTTPS ingress, choose proxy. For example, API 18080 and web 18081 both bind to 127.0.0.1, while public HTTPS stays on the existing proxy's selected port. Configure that proxy to forward the domain to http://127.0.0.1:18081, preserving Host (including a custom port), supporting 1 GB uploads and 600-second timeouts. The installer requires an existing running host Nginx for the local listener; it does not disable other sites or start a default listener on port 80. Container proxies need an explicit route to the host; their own loopback is not the host.

Choose nginx to add a TLS virtual host directly to the host Nginx. Enter its HTTP/HTTPS ports; shared Nginx listeners are permitted, other owners are rejected. The default nginx mode now handles certificates automatically. After completing application/environment and administrator setup, run:

Reference
sudo python3 deploy/production/install.py --apply --output /tmp/quay-config

The installer asks for the certificate contact email and acceptance of Let's Encrypt terms, installs Certbot if missing, prepares the challenge endpoint, probes its public route, obtains TLS, checks renewal against staging, starts QUAY and verifies production authentication locally and over public HTTPS. Existing certificates are reused and renewed when due. The quay-cert-renew.timer runs twice daily; a certificate-scoped deploy hook reloads Nginx after renewal, including renewals by an existing Certbot timer. HTTP-01 validation always reaches public port 80. If your local HTTP port differs, forward the challenge path from the existing ingress, or select proxy mode for an externally managed certificate. DNS and provider firewall rules must be configured separately; the installer reports public challenge routing failures. Use proxy mode when the public TLS port differs from the local ingress port.

Do not copy the repository's Nginx/service templates directly. The installer generates every dependent setting, refuses foreign configuration files, checks occupied ports before applying, and rolls configuration back on validation or service-command failure. It never kills another service to free a port.

5. Initialize the superadministrator

Reference
sudo systemd-run --wait --pty --collect \
  --property=User=quay --property=Group=quay \
  --property=WorkingDirectory=/opt/quay/current \
  --property=EnvironmentFile=/etc/quay/quay.env \
  --setenv=PYTHONPATH=/opt/quay/current/apps/api \
  /opt/quay/current/.venv/bin/python -m app.auth.bootstrap

Enter and repeat a 15–128-character password interactively. The command initializes ricardo@ricardopiana.com as verified and approved. It refuses to overwrite an initialized account; use email recovery afterward. Passwords are not command-line arguments.

6. Start and verify

Reference
sudo python3 deploy/production/install.py --apply --output /tmp/quay-config
sudo systemctl status quay
curl -fsS https://qway.ricardopiana.com/api/v2/auth/me

Use https://DOMAIN:PORT when the chosen public HTTPS port is not 443. Successful choices are remembered in /etc/quay/network.json. The generated service loads /etc/quay/network.env after quay.env, preserving SMTP/provider/vault secrets while setting the matching production origin. For automation, pass --non-interactive with --domain, --mode, --api-port, --http-port and --https-port (all required on first setup), plus --email and --agree-tos in nginx mode.

Without login the final response must report mode=production and user=null. If it reports local, stop public access and fix the environment configuration. Use one worker: job/compiler state is process-local. Inspect service failures with sudo journalctl -u quay -n 100.

  1. Open the public homepage and sign in as the superadministrator.
  2. Register another real email address in a separate browser session; test delivery and verification.
  3. Confirm that the pending account cannot enter editors. Approve it, then sign in again.
  4. Create a private project and GLB. Verify a second member cannot see or fetch them.
  5. Test password recovery and session revocation. Suspend and restore the test account.
  6. Test RAMS publishing separately; no automated test proves delivery through your actual SMTP mailbox.

7. Back up, update and recover

For a consistent backup, briefly stop the service, copy all of /var/lib/quay to protected storage and restart. Include accounts, workspaces, projects, GLBs, images, audio, content and deployment data. Store all of /etc/quay, including network settings and the vault key, separately and securely. A .qway archive is a project checkpoint, not a complete server backup.

Before updating, retain a backup and the previous build. Check out the desired revision, install dependencies, build, replace the web output and restart the service. Verify login, reopening a project and resource loading. Test restoration periodically on a separate installation, retaining quay ownership and private permissions.

To move your local work, import its .qway archive into the intended user’s workspace and re-enter deployment credentials. Do not copy unrelated private users into the public web root. Production activation and real SMTP delivery are installation checks, not claims made by documentation tests.