[Blog](https://deploywithox.com/blog) [Guides](https://deploywithox.com/blog#c-guides) # How to self-host Kellnr, a Rust registry, on your own VPS Run Kellnr v6.9.0, the private Rust crate registry, on your Ubuntu server with ox and no Docker: a Rust build and Postgres, from the config that ran. Saurav Sharma Oct 17, 2026 9 min read On this page - [What you need](https://deploywithox.com/blog/self-host-kellnr#what-you-need) - [The steps to install Kellnr on Ubuntu](https://deploywithox.com/blog/self-host-kellnr#steps) - [The ox.toml, line by line](https://deploywithox.com/blog/self-host-kellnr#config) - [Postgres and the data folder](https://deploywithox.com/blog/self-host-kellnr#services) - [Updates and backups](https://deploywithox.com/blog/self-host-kellnr#updates) - [Frequently asked questions](https://deploywithox.com/blog/self-host-kellnr#faq) To self-host Kellnr you need an Ubuntu server, a fork of the Kellnr repo with one `ox.toml` file added, and ten variables. In our run the first deploy took about 10 minutes, which covers building the web page and compiling the Rust code, and ox set up the Postgres database where Kellnr keeps its records. **How we tested** On Oct 17, 2026, ox deployed Kellnr v6.9.0 from commit [`4c946274`](https://github.com/kellnr/kellnr/commit/4c9462746b9366f1a02c8202964d4275c2919781) on a fresh DigitalOcean server with 8 vCPUs and 16 GB of memory. The run then redeployed it, backed it up and rebooted the server. Then a separate test agent, one that did not write the config, signed in, created an access token and saw it listed after a reload, and checked the app's services and its backup. [Kellnr](https://github.com/kellnr/kellnr) is an open-source registry for Rust crates, which its README likens to crates.io on your own hardware. You publish private crates to it with `cargo` and your other projects fetch them from it. A web page browses and searches them and manages tokens, users and groups. Rustdoc hosting and a crates.io cache exist and are off by default. Kellnr is written in Rust, its Vue web page is embedded in the one binary, and the license is MIT or Apache 2.0, at your choice. ox deployed Kellnr v6.9.0 (commit 4c946274) on Oct 17, 2026 on a fresh DigitalOcean server with 8 vCPUs and 16 GB of memory; the first deploy took 10 minutes and a redeploy took 9 minutes. - **First deploy:** 10 minutes, from adding the project until the app passed the run's first checks. - **Redeploy of the same commit:** 9 minutes, until the app passed the checks again. - **Server:** DigitalOcean, 8 vCPUs and 16 GB of memory (`s-8vcpu-16gb`), with this app alone on it. Every one of the 85 apps we deployed ran on this one size, so it was not picked for this app. - **Memory in use after the reboot:** 620 MB of 15986 MB, for the whole server: Ubuntu, the app and its staging copy, its services, Caddy and the ox agent. On a server with no apps, ox's tests on real servers hold the agent to 40 MB or less and Caddy to 50 MB or less. - **Services ox runs for it:** `postgres`. - **Source:** [github.com/kellnr/kellnr](https://github.com/kellnr/kellnr) at v6.9.0, commit [`4c946274`](https://github.com/kellnr/kellnr/commit/4c9462746b9366f1a02c8202964d4275c2919781). The Kellnr home page, a private Rust crate registry The Kellnr home page signed in as admin The Kellnr Authentication Tokens settings with the token verify-ci-token, its value not shown ## What you need - An Ubuntu LTS server. The run used the size in the facts above and measured the memory there. The server builds Kellnr itself, so it reaches npm and crates.io. - A GitHub account to fork `kellnr/kellnr`, and an ox account, which you open by signing in with GitHub. - No outside account. The run kept crate files in a data folder on the server's disk and records in Postgres. Storage on S3 or Google Cloud, the crates.io cache, rustdoc hosting and OAuth2 sign-in were not tested. ## The steps to install Kellnr on Ubuntu In the ox dashboard press Add a server and run the install command it shows, as root, on your Ubuntu machine. It installs the ox agent and Caddy. Fork `kellnr/kellnr` and start from commit `4c946274`, titled chore: release v6.9.0, the one the run deployed. Add the `ox.toml` shown below at the top of the repo, then commit and push. No other file is added. Write `kellnr.env` on your laptop with the ten keys listed under the variables, set as that section says. With the [ox CLI](https://deploywithox.com/docs/cli) signed in, run: Shell ```bash ox new /kellnr ox review kellnr --from-file kellnr.env --wait ``` The project takes the repo's name. The review saves the values and starts the first deploy, and `--wait` prints the run until it ends. The [quickstart](https://deploywithox.com/docs/quickstart) shows the same two steps in the browser. When the deploy is green, open the address ox shows. The home page says Welcome to Kellnr, with crate, version and download counts of zero on a new registry. The run used this preview address, and a domain of your own was not part of it. The [domains page](https://deploywithox.com/docs/operate/domains) covers adding one. Press Log in at the top right and sign in as `admin`. Kellnr has no sign-up page. The run left `KELLNR_SETUP__ADMIN_PWD` unset, so the password is Kellnr's default, `admin`. A wrong password gets Wrong user or password, and the right one puts the admin menu in the header. That default is in Kellnr's source, so anyone who finds the address can try it. Settings has a Change Password page, which the run did not use. Then open Settings, the Auth. Tokens page, type a name and press Create Token. Kellnr shows the token once, with a Copy button, and after a reload it is listed under Active Tokens. Kellnr says tokens let you publish crates with `cargo` without your password. Publishing or fetching a crate with cargo was not tested. ## The ox.toml, line by line TOML ```toml # Kellnr 6.9.0 (Rust, a private crate registry with a Vue UI) on ox's # postgres, as its operator would write it: the UI is built with npm and # copied into the embedded-resources crate (the justfile's npm-build # steps), then the registry is built. [tools] # The UI pins no node; its vite build needs 22 or newer. node = "24" [app] # Kellnr binds its own address and port (not PORT); the port is per # release, and its data is files in the data folder. start = "KELLNR_LOCAL__IP=127.0.0.1 KELLNR_LOCAL__PORT=$PORT exec target/release/kellnr start" health = "/api/v1/health" [build] install = "cd ui && npm ci" commands = [ "cd ui && npm run build", "mkdir -p crates/embedded-resources/static && cp -r ui/dist/* crates/embedded-resources/static/", "cargo build --release --locked", ] [services] postgres = {} ``` The file follows the repo's justfile: web page first, registry second. - `[tools]` asks for Node 24, since the web page's folder pins none and its build tool, Vite 8.3, asks for Node 20.19, or 22.12 and newer. No Rust line is needed. The repo pins no version, so ox's default, the stable release, builds the registry, and ox adds the C compilers, pkg-config and OpenSSL headers itself. - `start` runs the binary the build leaves at `target/release/kellnr`. Kellnr listens on every address at port 8000 and ignores `PORT`, so the line sets `KELLNR_LOCAL__IP` to the loopback address, where only Caddy reaches it, and `KELLNR_LOCAL__PORT` to the `$PORT` ox gives each release, so old and new copies can overlap during a deploy. `exec` lets ox's stop signal reach Kellnr itself. - `health` is Kellnr's own route, which answers OK. ox sends traffic to a new release only after it answers. - `install` runs `npm ci` in `ui`, which installs the web page's packages from its lockfile. - The build `commands` run in order. Vite builds the web page into `ui/dist`. The copy puts it in `crates/embedded-resources/static`, which Kellnr's Rust code embeds at compile time, so it must exist before Cargo starts. Then `cargo build --release --locked` builds the registry from the versions in `Cargo.lock`. - There is no `migrate` line, because Kellnr creates and updates its own tables at start. - `[services]` asks for Postgres. Without it Kellnr would use SQLite. There is no `[storage]` section: Kellnr's data folder is `$OX_DATA_DIR`, which ox keeps across releases. The test agent found no worker, scheduler or timer. Shell ```bash KELLNR_REGISTRY__DATA_DIR KELLNR_ORIGIN__HOSTNAME KELLNR_ORIGIN__PROTOCOL KELLNR_ORIGIN__PORT KELLNR_POSTGRESQL__ENABLED KELLNR_POSTGRESQL__ADDRESS KELLNR_POSTGRESQL__PORT KELLNR_POSTGRESQL__DB KELLNR_POSTGRESQL__USER KELLNR_POSTGRESQL__PWD ``` `KELLNR_REGISTRY__DATA_DIR` is `${OX_DATA_DIR}`. Kellnr stops at start without a data folder, and it keeps the crates and the index there. `KELLNR_ORIGIN__HOSTNAME`, `KELLNR_ORIGIN__PROTOCOL` and `KELLNR_ORIGIN__PORT` are the address people use to reach Kellnr, which it builds its links from. They are `${PUBLIC_HOST}`, `${PUBLIC_SCHEME}` and `${PUBLIC_PORT}`, filled in by ox. Kellnr marks its session cookie Secure when the protocol is https, and a browser drops that cookie on an http page, so a fixed https would break sign-in on an http address. The port is the public one, 443 or 80, which Kellnr leaves out of its links. `KELLNR_POSTGRESQL__ENABLED` is `true`, which switches Kellnr from SQLite to Postgres. Kellnr takes the database in five parts: `KELLNR_POSTGRESQL__ADDRESS`, `__PORT`, `__DB`, `__USER` and `__PWD` are `${postgres.host}`, `${postgres.port}`, `${postgres.database}`, `${postgres.user}` and `${postgres.password}`, the details of the Postgres ox set up. See [variables](https://deploywithox.com/docs/operate/variables) for how references work. `KELLNR_SETUP__ADMIN_PWD` is not in the list. It sets the first admin password, which defaults to `admin`, and it counts only when Kellnr finds no users, so changing it later leaves the password as it was. ## Postgres and the data folder ox's Postgres is shared with the server's other projects and gives Kellnr its own database and a role that alone may connect to it. The staging copy the run deployed beside production has a database of its own, and the memory figure above counts both. Postgres holds users, tokens and crate records. Kellnr's help text says the data folder holds the crates and the index. ## Updates and backups To update, merge a newer release into your fork, push, and run `ox deploy kellnr --wait`. ox builds the new release beside the running one and switches when the health path answers. The run redeployed the same commit, so a jump between Kellnr versions was not tested. The [release notes](https://github.com/kellnr/kellnr/releases) on Kellnr's GitHub page list what each version changed. Backups need no setup. The run's backups held a Postgres dump, the daily one and the one from Back up now, and nothing else: no copy of the data folder, where Kellnr keeps the files of published crates, and the run published no crate. List them with `ox backups kellnr`. A restore was not tested. The [backups page](https://deploywithox.com/docs/operate/backups) covers keeping copies in an S3 bucket. ## Frequently asked questions ### Do I need Docker to self-host Kellnr? No. Kellnr's README starts with a Docker image and also lists binary releases and a Kubernetes chart. ox builds Kellnr from your fork on the server and runs it as a system service, with Postgres beside it. There is no image to pull, and an update is a push and one deploy command. ### Does Kellnr need Postgres? No. Kellnr uses SQLite unless `KELLNR_POSTGRESQL__ENABLED` is true, and it supports both. The run used Postgres, which ox installed and wired in through five variables. Crate files stay in the data folder on disk either way, unless you point Kellnr at S3 or Google Cloud storage, which was not tested. ### What is the first Kellnr login? The user is `admin`, and the password is the value of `KELLNR_SETUP__ADMIN_PWD`, or Kellnr's default, `admin`, when it is unset, as in the run. Kellnr creates the user on its first start with no users and has no sign-up page. Settings has a User Management page for more users, which the run did not use. ### How much memory does self-hosted Kellnr use? After the run's reboot the whole server used the memory the facts show, counting Kellnr, its staging copy, Postgres, Caddy and the ox agent. Memory during the build, which compiles Rust and runs Vite on the server, was not measured. ox takes any server from 1 GB up and says so when memory is why an app stopped. New to running apps on your own server? [How ox self-hosts your apps](https://deploywithox.com/self-hosting) shows what ox sets up on your server. On this page - [What you need](https://deploywithox.com/blog/self-host-kellnr#what-you-need) - [The steps to install Kellnr on Ubuntu](https://deploywithox.com/blog/self-host-kellnr#steps) - [The ox.toml, line by line](https://deploywithox.com/blog/self-host-kellnr#config) - [Postgres and the data folder](https://deploywithox.com/blog/self-host-kellnr#services) - [Updates and backups](https://deploywithox.com/blog/self-host-kellnr#updates) - [Frequently asked questions](https://deploywithox.com/blog/self-host-kellnr#faq) - [Do I need Docker to self-host Kellnr?](https://deploywithox.com/blog/self-host-kellnr#faq-docker) - [Does Kellnr need Postgres?](https://deploywithox.com/blog/self-host-kellnr#faq-database) - [What is the first Kellnr login?](https://deploywithox.com/blog/self-host-kellnr#faq-login) - [How much memory does self-hosted Kellnr use?](https://deploywithox.com/blog/self-host-kellnr#faq-memory) Written by Saurav Sharma Builds ox. Writes about running apps on servers you own, without Docker and without a platform bill. [Older post How to self-host the Kener status page on your own VPS](https://deploywithox.com/blog/self-host-kener) [Newer post How to self-host Kavita reading server on your own VPS](https://deploywithox.com/blog/self-host-kavita) ## Keep reading - Guides [Self-Hosted Open-Source Apps Deployed with ox: All 85](https://deploywithox.com/blog/self-hosted-open-source-apps-deployed-with-ox) ox deployed 85 open-source apps from pinned commits on fresh servers, with no Docker. The stacks, services, deploy times and a table of every app. Saurav Sharma Oct 17, 2026 16 min read - Guides [How to self-host AFFiNE on your own VPS without Docker](https://deploywithox.com/blog/self-host-affine) Run AFFiNE v0.27.4 on your own Ubuntu server with ox: Postgres with pgvector, Redis, a Rust and Node build, and an admin made from two variables. Saurav Sharma Oct 17, 2026 12 min read - Guides [How to self-host Akaunting on your own VPS without Docker](https://deploywithox.com/blog/self-host-akaunting) Run Akaunting 3.2.4 on your own Ubuntu server with ox: PHP, MariaDB, a scheduler and the first company and admin made on deploy, from the config that ran. Saurav Sharma Oct 17, 2026 10 min read ## Deploy to a server you own ox sets up systemd, Caddy and PostgreSQL on your Ubuntu server and deploys on every push. Free for your first project. [Sign up with GitHub](https://deploywithox.com/login/github) [Read the docs](https://deploywithox.com/docs)