Selfhosting is simple, but there’s a few things to keep in mind. First, and most importantly, is that it effectively requires a second VPS (or some way to use another IP address), so it’s unfortunately not available for everyone. Secondly, as it was made for which uses Cloudflare for DNS, it’s made to be used for that same configuration. This is important because issuing wildcard SSL certificates (* for example) requires DNS access, which needs to be automated in order to handle re-issuing certificates. Different services have different APIs, so supporting all providers would be difficult and unmanageable for a project at our scale, so we’re just supporting Cloudflare for now. If that’s all fine, here’s how to set it up.


Install the latest version of NodeJS. For Ubuntu / Debian, this can be done through NodeSource.

Clone the server:

git clone pages
cd pages
pnpm i
pnpm run build

You’ll also need to install PostgreSQL and Redis.


Configuration is done through environment variables, but you can use the .env file for convenience.

# PAGES_DOMAIN is the domain users will visit subdomains of. Be sure to have no leading period ( is not correct here)
# Used for requesting private repositories. If you'd not like to allow this functionality, just don't specify a FORGEJO_API_TOKEN.
# Get a Cloudflare API token for a zone with the domain you intend to use this on
# is useful for testing things
# Let's Encrypt can time you out if you issue too many certificates too often, so switch to this only once you confirm it to work on the staging API above (the staging API doesn't produce valid certificates, but it's still useful to make sure your configuration works).

Run pnpm run start (or start-cluster if you’d like to run as many processes as there are cores on your system) as the root user (required for access to ports 80 and 443) and confirm it works. If you used the staging ACME api for testing, you’ll want to remove those to be able to switch to the normal Let’s Encrypt API- for now you’ve just gotta delete certs.db to do this, there’s not yet a way to delete individual certificates automatically.

If you’d like to run pages-server without root, you’ll need to forward ports 80 and 443 to ports other users can access. For example, you could run pages-server bound to ports 3080 and 3443, and then forward 80 and 443 to each of those ports:

sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 3080
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 443 -j REDIRECT --to-port 3443

You’ll need to make these settings persistent so they run on system startup with iptables-persistent.

The homepage

The homepage, shown at PAGES_DOMAIN, is a custom domain just like any other, except that it uses the same certificate as the wildcard certificate. To set it up, use a TXT record as shown in the custom domain instructions.


You’ll probably want to automate starting the pages server when the system boots. This can be done with a service file. Create one at /etc/systemd/system/pages.service- Here’s an example.

Description=Pages server

ExecStart=node .