Skip to content

Self-Hosting in Production

This page covers what you need in week one after your initial Wayland server install. It picks up where Run Wayland on a Server leaves off. Read that page first if you have not set the server up yet: it covers requirements, the three-step install, the first-login QR code, and the Tailscale private-network option.

Once the server is running interactively, you will probably want it to survive a reboot, sit behind a proper reverse proxy, and be straightforward to upgrade. This page covers all of that.

Two environment variables let you change where Wayland listens and where it stores data:

VariableDefaultWhat it changes
PORT3000The port the server binds on
DATA_DIR(a platform default under the user’s home)Where Wayland stores its database, config, and provider credentials

The wayland command is the global binary from npm install -g getwayland (done during the server install on the page linked above). Set these variables before wayland start, or put them in the systemd unit file shown below.

Terminal window
PORT=8080 DATA_DIR=/srv/wayland wayland start

Running wayland start in a terminal is fine for testing, but it stops when you log out. A systemd unit keeps the server running across sessions and reboots.

Create the file /etc/systemd/system/wayland.service:

[Unit]
Description=Wayland server
After=network.target
[Service]
Type=simple
User=wayland
WorkingDirectory=/home/wayland
Environment=PORT=3000
Environment=DATA_DIR=/home/wayland/.wayland
ExecStart=/usr/bin/env wayland start
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

Replace wayland (under User and WorkingDirectory) with the Linux user you want the server to run as. Then enable and start it:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable wayland
sudo systemctl start wayland
sudo systemctl status wayland

To see live logs:

Terminal window
journalctl -u wayland -f

The server binds on 0.0.0.0:3000 by default. For a public-facing deployment you should put it behind a reverse proxy that handles TLS, so that traffic reaches your box over HTTPS and Wayland itself only listens on localhost.

Install nginx and certbot, then obtain a certificate:

Terminal window
sudo apt install nginx certbot python3-certbot-nginx
sudo certbot --nginx -d your.domain.com

Create /etc/nginx/sites-available/wayland:

server {
listen 443 ssl;
server_name your.domain.com;
ssl_certificate /etc/letsencrypt/live/your.domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your.domain.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
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 3600;
proxy_send_timeout 3600;
}
}
server {
listen 80;
server_name your.domain.com;
return 301 https://$host$request_uri;
}

Enable it and reload:

Terminal window
sudo ln -s /etc/nginx/sites-available/wayland /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Update the systemd unit to bind on loopback only by adding Environment=HOST=127.0.0.1 if the server supports a HOST override, or use your firewall to block external access to port 3000 directly:

Terminal window
sudo ufw allow 80
sudo ufw allow 443
sudo ufw deny 3000

Caddy handles certificate acquisition and renewal automatically. Install it, then create or edit /etc/caddy/Caddyfile:

your.domain.com {
reverse_proxy localhost:3000 {
header_up X-Forwarded-Proto {scheme}
transport http {
read_buffer 4096
}
}
}

Start or reload Caddy:

Terminal window
sudo systemctl enable caddy
sudo systemctl start caddy

Caddy obtains a certificate from Let’s Encrypt automatically on first access.

If you do not need the server reachable from the public internet, Tailscale is the simplest option. It was introduced in Run Wayland on a Server. The one-line setup:

Terminal window
tailscale serve 3000

This serves the Wayland server over HTTPS, reachable only from devices on your tailnet. No nginx, no certbot, no firewall rules needed. For a personal or small-team setup this is the recommended path.

Wayland is installed as a global npm package. To upgrade to the latest release:

Terminal window
npm install -g getwayland@latest

Then restart the service:

Terminal window
sudo systemctl restart wayland

To upgrade to a specific version, pin the version tag (otherwise @latest installs the newest published release):

Terminal window
npm install -g getwayland@latest
sudo systemctl restart wayland

Your data and config in DATA_DIR are preserved across upgrades. The server migrates its own database on startup when the schema changes.

Before upgrading in production, check the Releases page for any manual migration steps called out in the release notes.

If you lose the admin password, the wayland resetpass command resets it locally without needing to log in:

Terminal window
wayland resetpass

Run this on the server itself (not over the web UI). It prints a new temporary password to the terminal. Log in with that password and change it immediately.

This command reads from DATA_DIR, so if you set a custom data directory in your systemd unit, make sure that environment variable is also set when you run wayland resetpass:

Terminal window
DATA_DIR=/srv/wayland wayland resetpass

The server exits immediately after wayland start. Check the logs:

Terminal window
journalctl -u wayland -n 50

Common causes:

  • Port already in use. Another process is on port 3000. Change the port with PORT=<other> or stop the conflicting process.
  • DATA_DIR does not exist or is not writable by the service user. Create it and set ownership: sudo mkdir -p /path/to/data && sudo chown wayland:wayland /path/to/data.
  • Node version too old. Wayland requires Node 18 or newer. Check with node --version.

The server starts but the web UI is unreachable. Check that the service is running (systemctl status wayland), that your firewall allows the port you are using, and that your reverse proxy configuration points at the right port.

The QR code does not appear on restart. The QR code only prints on the very first boot, when the admin account is created. On subsequent starts the server just logs that it is running. Use the printed admin password from the first boot, or use wayland resetpass if you did not save it.