From 5170afa9e8874c30b8aff4939ab3cbaf031690ed Mon Sep 17 00:00:00 2001 From: Davide Scaini Date: Fri, 10 Apr 2026 12:53:35 +0200 Subject: [PATCH] vps instructions --- docs/deployment/vps.md | 298 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 298 insertions(+) create mode 100644 docs/deployment/vps.md diff --git a/docs/deployment/vps.md b/docs/deployment/vps.md new file mode 100644 index 0000000..71719e2 --- /dev/null +++ b/docs/deployment/vps.md @@ -0,0 +1,298 @@ +# VPS deployment guide + +Concrete setup for a Debian VPS running a private multi-user bincio instance. +Code is deployed directly from your laptop via `git push` — no GitHub required. + +## Assumptions + +- Bare Debian 12 VPS with root SSH access +- You own a domain pointed at the VPS +- You have Strava API credentials +- Up to ~30 users + +--- + +## 1. Install system dependencies + +```bash +apt update && apt upgrade -y +apt install -y git curl nginx certbot python3-certbot-nginx sqlite3 +``` + +**Node.js 20 LTS** (the Debian package is too old): +```bash +curl -fsSL https://deb.nodesource.com/setup_20.x | bash - +apt install -y nodejs +``` + +**uv** (manages Python and all Python deps): +```bash +curl -LsSf https://astral.sh/uv/install.sh | sh +# add to PATH: +echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + +--- + +## 2. Set up the code directory + +```bash +mkdir -p /opt/bincio +git init --bare /opt/bincio-repo.git +``` + +Create the post-receive hook at `/opt/bincio-repo.git/hooks/post-receive`: + +```bash +#!/bin/bash +set -e + +REPO=/opt/bincio-repo.git +DEPLOY=/opt/bincio +DATA=/var/bincio/data + +echo "--- Checking out code ---" +git --work-tree=$DEPLOY --git-dir=$REPO checkout -f + +echo "--- Syncing Python deps ---" +cd $DEPLOY +~/.local/bin/uv sync + +echo "--- Syncing JS deps ---" +cd $DEPLOY/site +npm install --silent + +echo "--- Building site ---" +cd $DEPLOY +~/.local/bin/uv run bincio render --data-dir $DATA --site-dir $DEPLOY/site + +echo "--- Copying dist to webroot ---" +rsync -a --delete $DEPLOY/site/dist/ /var/www/bincio/ + +echo "--- Restarting API ---" +systemctl restart bincio + +echo "--- Done ---" +``` + +```bash +chmod +x /opt/bincio-repo.git/hooks/post-receive +mkdir -p /var/www/bincio +``` + +--- + +## 3. First deploy from your laptop + +Add the VPS as a git remote (run this locally, once): + +```bash +git remote add vps root@:/opt/bincio-repo.git +``` + +Push your code: + +```bash +git push vps main +``` + +The hook checks out the code, installs deps, and builds the site. +Subsequent pushes (including unpublished branches) work the same way: + +```bash +git push vps mobile_app # deploy any branch directly +``` + +--- + +## 4. Initialise the instance + +```bash +cd /opt/bincio + +uv run bincio init \ + --data-dir /var/bincio/data \ + --handle dave \ + --display-name "Dave" \ + --name "My Bincio" +# prompted for password; prints a first invite code +``` + +Set the user cap: + +```bash +sqlite3 /var/bincio/data/instance.db \ + "INSERT INTO settings VALUES ('max_users', '30');" +``` + +--- + +## 5. Prepare your own activities + +Source files (raw GPX/FIT) live separately from the BAS output: + +``` +/var/bincio/sources/dave/ ← raw activity files, rsync'd from laptop +/var/bincio/data/dave/ ← BAS JSON output (bincio extract writes here) +``` + +Configure `/opt/bincio/extract_config.yaml` on the server to point to your +source dir: + +```yaml +sources: + - path: /var/bincio/sources/dave/activities + type: strava_export + - path: /var/bincio/sources/dave/activities.csv + type: strava_csv + +output: + dir: /var/bincio/data +``` + +Sync and extract (run from your laptop or SSH in): + +```bash +# push raw files from laptop +rsync -avz ~/your-activity-data/ root@:/var/bincio/sources/dave/ + +# extract on server +ssh root@ "cd /opt/bincio && uv run bincio extract" + +# rebuild site +ssh root@ "cd /opt/bincio && \ + uv run bincio render --data-dir /var/bincio/data --site-dir site && \ + rsync -a --delete site/dist/ /var/www/bincio/" +``` + +--- + +## 6. systemd service + +Create `/etc/systemd/system/bincio.service`: + +```ini +[Unit] +Description=BincioActivity API +After=network.target + +[Service] +WorkingDirectory=/opt/bincio +ExecStart=/root/.local/bin/uv run bincio serve \ + --data-dir /var/bincio/data \ + --site-dir /opt/bincio/site \ + --host 127.0.0.1 \ + --port 4041 +EnvironmentFile=/etc/bincio/secrets.env +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +Create `/etc/bincio/secrets.env`: + +```bash +mkdir -p /etc/bincio +chmod 700 /etc/bincio +cat > /etc/bincio/secrets.env <:/var/bincio/sources/dave/` | +| Re-extract after sync | `ssh root@ "cd /opt/bincio && uv run bincio extract"` then push again to rebuild | +| View API logs | `journalctl -u bincio -f` | +| Restart API | `systemctl restart bincio` | +| Check nginx logs | `tail -f /var/log/nginx/error.log` | +| Renew SSL (auto) | `certbot renew --dry-run` | + +--- + +## See also + +- [Multi-user architecture](multi-user.md) +- [CLI reference](../reference/cli.md) +- [API reference](../reference/api.md)