Skip to main content
Version: 0.2.2

Single binary

The simplest way to run Openbeehive on your own machine is the single binary. In the selfhost profile, Openbeehive serves the web app and the API from one process, stores its data in a local SQLite file, and keeps uploaded photos on the filesystem. No Docker, no Postgres, no object store - just one executable.

This page walks you through building that binary from source and running it as a long-lived service.

:::tip In a hurry? If you would rather pull a prebuilt container image, see Docker. To compare both approaches first, start at the self-hosting overview. :::

Prerequisites

You will need a few build tools installed on the machine that compiles the binary:

ToolVersionPurpose
Go1.25+Compiles the server
Node.js20+Builds the SvelteKit web app
buflatestGenerates the Connect-RPC code from the protobuf definitions

Once built, the binary itself has no runtime dependencies - you can copy it to a server that has none of the above installed.

Get the code

git clone https://github.com/johnnycube/openbeehive-app.git
cd openbeehive

Configure

Copy the example environment file and pick the self-host profile:

cp .env.example .env

For a private, single-user instance the defaults are almost ready to go. Open .env and confirm these values:

BEEHIVE_DEPLOYMENT_PROFILE=selfhost
BEEHIVE_ADDR=:8080
BEEHIVE_PUBLIC_BASE_URL=http://localhost:8080
BEEHIVE_SERVE_WEB=true
BEEHIVE_DATABASE_DRIVER=sqlite
BEEHIVE_DATABASE_DSN=file:openbeehive.db?_pragma=journal_mode(WAL)
BEEHIVE_BLOB_BACKEND=fs
BEEHIVE_BLOB_DIR=./data/blobs
BEEHIVE_SESSION_SECRET=

Generate a session secret - never leave this blank in anything but a throwaway test:

openssl rand -base64 32

Paste the result into BEEHIVE_SESSION_SECRET=.

:::note No login by default Leave BEEHIVE_OIDC_PROVIDERS empty and BEEHIVE_WEBAUTHN_ENABLED=false to run as a single user with no sign-in step. When you are ready to add accounts or passkeys, see Authentication. :::

If you intend to reach the instance from another device on your network, set BEEHIVE_PUBLIC_BASE_URL to an address that device can actually resolve (for example http://192.168.1.20:8080 or your domain behind a reverse proxy). This value is also baked into the deep links used by QR labels.

Build

Generate the protobuf code, then compile:

make proto
make build

This produces a single executable:

./server/bin/openbeehive

The web app is bundled into the binary, so there is nothing else to deploy alongside it.

Run

From the repository root (so the relative paths in .env resolve as expected):

./server/bin/openbeehive

On first start the server:

  • creates the SQLite database file openbeehive.db and runs its migrations,
  • creates the ./data/ directory (with ./data/blobs for photos),
  • serves the web app and the Connect-RPC API on :8080.

Open http://localhost:8080 in your browser. The app loads, builds its local database in the browser, and you are ready to add your first apiary.

:::tip Working directory matters Relative paths like file:openbeehive.db and ./data/blobs are resolved against the directory the binary is launched from, not where the binary lives. Pick a working directory deliberately - the systemd unit below sets it explicitly with WorkingDirectory. :::

Run as a systemd service

For an always-on instance, run Openbeehive under systemd so it starts at boot and restarts on failure.

First, place the binary and a working directory somewhere sensible and create a dedicated user:

sudo useradd --system --home /opt/openbeehive --shell /usr/sbin/nologin openbeehive
sudo mkdir -p /opt/openbeehive
sudo cp server/bin/openbeehive /opt/openbeehive/
sudo cp .env /opt/openbeehive/
sudo chown -R openbeehive:openbeehive /opt/openbeehive

Then create the unit file at /etc/systemd/system/openbeehive.service:

[Unit]
Description=Openbeehive beekeeping records
After=network.target

[Service]
Type=simple
User=openbeehive
Group=openbeehive
WorkingDirectory=/opt/openbeehive
EnvironmentFile=/opt/openbeehive/.env
ExecStart=/opt/openbeehive/openbeehive
Restart=on-failure
RestartSec=5

# Hardening
NoNewPrivileges=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/opt/openbeehive
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Enable and start it:

sudo systemctl daemon-reload
sudo systemctl enable --now openbeehive

Check that it is healthy and watch the logs:

systemctl status openbeehive
journalctl -u openbeehive -f

:::caution Binding to port 80 or 443 The example binds to :8080, which an unprivileged user can use. Do not run the service as root to reach ports 80/443 - instead keep Openbeehive on :8080 and put a reverse proxy (such as Caddy or nginx) in front of it to handle TLS and the public port. :::

Where your data lives

In the selfhost profile everything is stored under the working directory you chose (above, /opt/openbeehive):

WhatDefault locationSet by
Records databaseopenbeehive.db (plus -wal / -shm files)BEEHIVE_DATABASE_DSN
Photos and attachments./data/blobsBEEHIVE_BLOB_DIR

The -wal and -shm files alongside the database are SQLite's write-ahead log; treat them as part of the database.

Moving or backing up your data

Because all state is files in one directory, relocating an instance is mostly a copy job:

  1. Stop the service so the database is at rest: sudo systemctl stop openbeehive.
  2. Copy the binary, .env, the database files, and the data/ directory to the new machine, preserving the layout.
  3. Start the service on the new host: sudo systemctl start openbeehive.

:::danger Always stop the service first Copying openbeehive.db while the server is running can capture a torn, inconsistent snapshot. Stop the service (or use a proper backup procedure) before copying database files. :::

For scheduled backups, retention, and safe live-backup techniques for SQLite, see Backups.

Upgrading

To move to a newer release, pull the latest code, rebuild, and replace the binary - your database and data/ directory stay where they are and migrations run on the next start. The full procedure, including how to roll back, is covered in Upgrading.