Flash a card. Plug in a drive. Run one command. Own your cloud forever.
curl -fsSL https://raw.githubusercontent.com/ishaanman7898/berryvault/main/install.sh | sudo bashBerryVault turns a Raspberry Pi into a personal cloud and NAS that you fully own. One command does every step: it preps the system, sets up storage that mounts on its own, installs the web interfaces, and configures encrypted global remote access. When it finishes you have a file manager and a live admin console you can open from any device you own, anywhere in the world.
It is the open source answer to a monthly Dropbox or Google One bill, or to paying hundreds up front for a proprietary NAS. There is no cloud middleman, so your files never leave your hardware.
- What is BerryVault
- Quick start
- The two web interfaces
- The admin console
- Features
- Hardware
- Remote access
- Apps
- Command line tools
- Why BerryVault
- Directory layout
- Contributing
- Troubleshooting
- License
BerryVault is a single installer that turns a Raspberry Pi 4 or 5 into a personal cloud and NAS. It is headless, so you never need a monitor, keyboard, or mouse.
You end up with two things you open in a browser from any device:
- A file manager and app store for everyday use.
- A live admin console for managing the Pi itself.
Your data stays on your own hardware. Nothing is relayed through a cloud service.
Start from a freshly flashed Raspberry Pi OS Lite image. The installer expects a clean system. If you have previously run
chownorchmodon system directories on this Pi, or reused a card from another setup, reflash first. A straychown -Ron/etccan breaksudoin a way the installer cannot recover. See TROUBLESHOOTING.md for the recovery recipe.
- Download Raspberry Pi Imager from raspberrypi.com/software.
- Choose Raspberry Pi OS Lite (64 bit), Bookworm or newer.
- Click the gear icon. Enable SSH, set your username and password, and configure Wi-Fi (Ethernet is recommended).
- Flash the card, insert it into your Pi, and power on.
ssh pi@raspberrypi.local # or ssh pi@192.168.1.XXX if mDNS is not up yetcurl -fsSL https://raw.githubusercontent.com/ishaanman7898/berryvault/main/install.sh | sudo bashThe installer is safe to rerun. Every step is idempotent. If it dies partway through (a network blip, an interrupted Tailscale sign in, a DNS hiccup), just run the same command again. It skips anything already done.
If you hit a
Fatal error on line Nbanner, confirm the Pi is online withping -c2 github.com, rerun the one liner, and if it still fails on the same line, grab the last 20 lines or so of/var/log/berryvault-install.logand check TROUBLESHOOTING.md.
The installer prompts you for three things upfront, then runs unattended:
- Admin username and password — what you use to log in to the console.
- Remote access provider — Tailscale, Cloudflare, NetBird, Nebula, or None.
- OTA console updates — whether the admin console can update itself over the air (recommended). Disable with
BERRYVAULT_OTA=falsefor unattended installs.
The installer runs local first. It gets http://berryvault.local working on your LAN before it brings up the VPN, so any problem is easier to pin down:
LOCAL ACCESS
[1] Pre-flight system checks 64 bit ARM, root, internet, disk space
[2] Update and prepare the system apt update plus upgrade
[3] Install storage utilities ntfs-3g, exfat, udisks2, udiskie
[4] Configure auto mount pipeline udev rules plus systemd service templates
[5] Configure mDNS hostname berryvault.local via Avahi
[6] Install Docker container runtime for CasaOS and apps
[7] Install CasaOS web interface app store and file manager on port 80
[8] Configure service isolation Caddy reverse proxy plus port allocator
[9] Install BerryVault admin console OTA updatable dashboard at /admin/
GLOBAL ACCESS
[10] Install remote access Tailscale · Cloudflare · NetBird · Nebula · or none
[11] Enable cluster mode multi Pi node discovery
TUNING
[12] Optimise resources low RAM tuning, swap, log retention
[13] Apply security hardening ufw firewall plus periodic SSD TRIM
- Open
http://berryvault.local. You land on CasaOS. Create your admin username and password on the first run screen. - Open
http://berryvault.local/admin/for the BerryVault admin console: drives, cluster, remote access, and Updates.
Once both work on your LAN, your Pi is set up. The remote access step gives you the same URLs from anywhere in the world.
The default login is
admin. You pick the password on the first run screen, and can change both later under Settings → Account.
BerryVault gives you two browser interfaces on the same device. They do different jobs.
| URL | Interface | What it is for |
|---|---|---|
http://berryvault.local/ |
CasaOS (third party) | The app store (install Immich or Jellyfin in two clicks), a generic file manager, and the Docker container UI |
http://berryvault.local/admin/ |
BerryVault admin console (ours) | Drives, services, cluster, remote access, system settings, and over the air updates for the console itself |
CasaOS handles the generic self hosted apps experience. The BerryVault console is the one this repo ships and updates over the air. It is where you manage the BerryVault specific parts of your Pi.
The admin console at /admin/ is a single self contained page served straight from the Pi. It is fully real time and fully real: every number is streamed live from the box and every button performs a real action. There is no mock data, no demo mode, and no placeholder values anywhere. Until a live reading arrives, a field simply stays blank.
Live, streamed from the Pi over Server-Sent Events with a polling fallback:
- CPU, RAM, SoC temperature, and network throughput in the top bar, plus a health pill that turns amber or red on its own when the Pi runs hot.
- Drive list, capacity, and SMART status; Docker container status; remote access state; cluster nodes.
Real controls, nothing cosmetic:
- Initialise, SMART check, format (LUKS2 encrypted), and safely eject drives.
- Restart services, manage SMB and Samba shares, toggle SSH and mDNS.
- Create and restore configuration snapshots.
- Set hostname, timezone, theme, and remote access, all applied on the Pi immediately.
- Command palette (
Ctrl+K) for instant navigation and actions. - Drag-and-drop file uploads with real progress bars, inline file search and filter.
- Notifications drawer with live system alerts pulled from the journal.
It looks the part: a refined, flat instrument panel design with crisp borders, restrained depth, tabular figures, keyboard focus rings, and a dark, light, or system theme picker (Settings → General). No gradients, no clutter.
The console ships as a versioned GitHub Release. Open the Updates page to see every published version with its full changelog, then install or roll back with one click. Each download is SHA-256 verified and swapped in atomically, so a failed update never breaks the running console.
Everything before v1.19.0 is legacy. Those builds predate the current backend and console contract, so many features will not work on them. They are still listed and installable, but they are labelled legacy and gated behind an explicit warning, and a downgrade may force you to rerun the installer to recover. Stay on v1.19.0 or newer unless you have a very specific reason not to. Versions below v1.10.0 cannot be installed at all.
If you opted out of OTA updates during install, the Updates page is hidden from the console. To re-enable: sudo rm /etc/berryvault/no-ota && sudo systemctl restart berryvault-cluster-daemon.
From a shell you get the same operations via the berryvault-update command.
| Capability | Details |
|---|---|
| True plug and play USB | NTFS, exFAT, ext4, ext3, FAT32, Btrfs, XFS, and F2FS drives mount the instant they are plugged in, with no terminal needed |
| Native file browser | Built into the admin console — browse, search, upload (with progress), download, rename, delete, and create folders |
| Drag and drop uploads | Drop files anywhere on the Files page; real per-file progress bars |
| SMB and Samba shares | Expose any folder to Windows, macOS, and Linux from the console |
| Drive health | On demand and nightly SMART self checks, plus periodic TRIM for SSDs |
| Encrypted drives | Format any USB drive as LUKS2 encrypted — auto-unlocks on this Pi, exportable passphrase for use elsewhere |
| No storage limit | Attach external drives of any capacity and combine multiple drives |
| Capability | Details |
|---|---|
| Four provider choices | Tailscale (default, deepest integration), Cloudflare Tunnel (no app needed on client), NetBird (open source alternative), Nebula (fully self hosted) |
| WireGuard encrypted | Every mesh option (Tailscale, NetBird, Nebula) uses WireGuard — no port forwarding, no dynamic DNS |
| Cloudflare public link | Cloudflare Tunnel gives a public HTTPS URL without requiring a VPN app on the client |
| LAN access via mDNS | http://berryvault.local works on any device on your home network |
| Zero trust by default | Only authenticated devices on your mesh can reach your data remotely |
| Optional public Funnel | Tailscale Funnel publishes an HTTPS login URL for clients with no VPN app |
| Reach me from anywhere | The dashboard leads with your exact address — public, mesh-only, or LAN — with a one-click copy; berryvault-remote status prints every route from the shell |
| Encryption at rest | AES-256-GCM for the settings store and an optional on-disk file vault; the daemon degrades gracefully if the crypto library is missing |
| Force HTTPS on LAN | Opt-in self-signed TLS for local clients (berryvault-tls); remote access is always encrypted |
| Console security | HTTP Basic Auth on the admin console, bcrypt-hashed credentials, CSP headers, rate-limited password endpoint |
| Capability | Details |
|---|---|
| One click app store | The CasaOS Docker app store: Immich, Jellyfin, Nextcloud, and more |
| Real time admin console | Live metrics and real controls, updatable over the air (see above) |
| Multi Pi cluster | Other BerryVault Pis on your mesh are discovered automatically and aggregate into one view |
| Lite Mode | One tap on the dashboard stops the heaviest optional services (CasaOS, Docker, mDNS) to hand RAM and CPU back to a low-spec Pi; the console, Samba, and remote access keep running, and it survives a reboot |
| Headless first | No monitor, keyboard, or mouse is ever required |
| Tiny power draw | A Pi 4 idles around 3 W |
| Component | Recommendation | Notes |
|---|---|---|
| Board | Raspberry Pi 4 (2 GB) | A Pi 5 is recommended for 4K photo transcoding |
| SD card | 16 GB Class 10 or A1 | Holds the OS only; your data lives on the USB drive |
| USB storage | Any USB 3.0 drive | An SSD is faster; HDDs work well with a powered hub |
| Power | Official Pi 4 USB-C (3A) | Underpowering is the top cause of drive corruption |
| Component | Recommendation |
|---|---|
| Board | Raspberry Pi 5 (4 GB or 8 GB) |
| Boot drive | NVMe SSD on a Pi 5 HAT |
| Storage | 2 TB USB 3.0 SSD (Samsung T7, WD My Passport) |
| Power | Official Pi 5 27W USB-C PD supply |
| Network | Gigabit Ethernet, always preferred over Wi-Fi for NAS use |
Spinning drives: use a powered USB 3.0 hub for any 2.5 inch or 3.5 inch HDD. Unpowered spinning drives draw more current than the Pi ports provide, which causes random disconnects and corruption.
During install you choose how to reach BerryVault from outside your home, or you can preset it with the BERRYVAULT_VPN= environment variable.
| Option | Best for | How it works | Notes |
|---|---|---|---|
| Tailscale (default) | Almost everyone | WireGuard mesh, free hosted control plane | Deepest integration — Serve, Funnel, the guided Remote Access page in the console; deepest free tier for personal use |
| Cloudflare Tunnel | Anyone who wants a public link with no app | Your Pi opens an outbound tunnel to Cloudflare's edge; visitors hit a public https://...trycloudflare.com URL |
No VPN app needed on the client at all; the Pi is the only thing that needs the cloudflared agent; free forever with no device limit |
| NetBird | Open source preference | WireGuard mesh, free cloud plan or fully self-hosted control plane | netbird up links the Pi to your account; 5 users / 100 machines on the free cloud plan; self-hosted removes the cap |
| Nebula | Fully self hosted, advanced | You run your own lighthouse and CA; the installer prints the next steps | No free tier limit; requires a server for the lighthouse; fastest raw throughput since there is no central relay |
| None | LAN only for now | No external access configured | Add a provider later from the console or by rerunning the installer |
The one thing people miss: a mesh VPN is per account, not per device. Installing the app is not enough. On every device (phone, laptop, tablet) you must sign in with the same account you used on the Pi. Different accounts cannot see each other.
How many devices each provider lets you connect on its free tier (2026).
| Provider | Free tier | Paid or self hosted |
|---|---|---|
| Tailscale | Unlimited personal devices (Personal plan) + 50 tagged infra devices, up to 6 users | Starter / Premium per user; Enterprise custom |
| Cloudflare Tunnel | No device cap (up to 1,000 tunnels per free Zero Trust account) | Free for the tunnel itself |
| NetBird (cloud) | 5 users or 100 machines | Team $6/user · Business $12/user · Self-hosted: no cap |
| Nebula (Defined Networking managed) | 100 hosts | Higher tiers; plain self-hosted Nebula has no cap |
A brand new Tailscale account has every advanced feature off. BerryVault works without them, but enabling them unlocks friendlier URLs and HTTPS. Open login.tailscale.com/admin and set the following.
| Setting | Where | Why |
|---|---|---|
| MagicDNS | DNS → Enable MagicDNS | Reach the Pi at http://berryvault from anywhere on your tailnet |
| HTTPS Certificates | DNS → Enable HTTPS | Issues a real Let's Encrypt cert so https://berryvault.<tailnet>.ts.net just works |
| Disable key expiry (optional) | Machines → berryvault → Disable key expiry |
Without it the Pi drops off your tailnet roughly every 90 days |
The console Remote Access page walks you through these as a live checklist that rechecks itself.
HTTPS not working even with MagicDNS on? Toggle MagicDNS off then on (forces a config reissue), enable HTTPS Certificates, then on the Pi run
sudo tailscale serve reset && sudo systemctl restart tailscaledand reopen the console.
Want a link with no app at all? Turn on Public Funnel (Settings → Remote Access, or
sudo berryvault-public on). It publishes a publichttps://...ts.netURL that opens the login page in any browser. Leave it off unless you need it, and use a strong password.
The installer runs cloudflared as a systemd service that opens a persistent outbound tunnel to Cloudflare's edge. No inbound firewall holes, no port forwarding, no sign-in required on the client.
- During install, pick option 2 (Cloudflare).
- The Pi dials out to Cloudflare and logs the public URL to the journal. Open the Remote Access page in the console — it surfaces the live URL automatically by scanning the journal.
- Share that URL with anyone. They open it in a browser, no app required. Your admin password gates everything.
The free quick-tunnel URL changes every time
cloudflaredrestarts. For a permanent URL, set up a Cloudflare Zero Trust tunnel with a custom domain on your Cloudflare account and configurecloudflaredwith a tunnel token instead.
- During install, pick option 3 (NetBird). The installer runs
netbird upand prints a URL to approve the device in your NetBird dashboard. - Open the URL, approve, and the Pi joins your NetBird network.
- On every other device: install the NetBird app, sign in with the same account, and the Pi appears as a peer.
- Reach BerryVault at the Pi's NetBird IP shown in the Remote Access page, or by hostname if you enable NetBird's built-in DNS.
Self-hosting the NetBird control plane (Management + Signal servers) removes the 100-machine free tier limit. See netbird.io/docs/selfhosted.
Nebula is a fully self-hosted WireGuard mesh. You run your own Certificate Authority and lighthouse server.
- During install, pick option 4 (Nebula). The installer installs the
nebulabinary and prints the next steps. - On a server you control (a cheap VPS works), install and run the Nebula lighthouse following nebula.defined.net/docs.
- Generate a CA, sign a certificate for the Pi and each client device, and distribute config files.
- Start
nebulaon the Pi:sudo systemctl start nebula. - Nebula peers discover each other via the lighthouse. The BerryVault console Cluster page detects Nebula peers automatically.
Nebula has the highest raw throughput of any option since traffic travels directly between peers without a central relay once the connection is established.
The CasaOS app store installs self hosted Docker apps in two clicks. See APP_RECIPE_BOOK.md for step by step guides.
| App | What it does |
|---|---|
| Immich | A Google Photos replacement with iOS and Android backup, facial recognition, and albums |
| Jellyfin | An open source media server that streams movies, TV, and music from your drives |
| Nextcloud | Calendar, contacts, documents, and file sync across all devices |
| Vaultwarden | A self hosted Bitwarden password manager |
| Home Assistant | A smart home automation hub |
| Uptime Kuma | A self hosted uptime monitor |
| Pi-hole / AdGuard Home | Network-wide DNS ad blocker — point your router at the Pi |
These are installed to /usr/local/bin for shell access to the same operations the console exposes.
| Command | What it does |
|---|---|
sudo berryvault-update current |
Show the installed console version (JSON) |
sudo berryvault-update list |
List every release on GitHub |
sudo berryvault-update check |
Print the latest available version tag |
sudo berryvault-update install <v|latest> |
Download, SHA-256 verify, and atomically switch the console |
sudo berryvault-update rollback |
Switch back to the previous version |
sudo berryvault-update history |
Show install history (JSON) |
sudo berryvault-public on|off |
Toggle the public Tailscale Funnel URL |
berryvault-remote status |
Print every way to reach this Pi (LAN, tailnet, public Funnel) |
sudo berryvault-lite on|off|status |
Lite Mode: stop heavy optional services (CasaOS, Docker, mDNS) to free RAM |
sudo berryvault-tls on|off|status |
Force HTTPS for LAN clients (self-signed); remote access is always TLS |
Legacy guard:
berryvault-update installrefuses pre-v1.10.0 demo builds outright and warns before installing any pre-v1.19.0 legacy build. SetBERRYVAULT_ALLOW_LEGACY=1to skip the interactive prompt in scripts.
| BerryVault | Raw Pi OS | OpenMediaVault | Synology | |
|---|---|---|---|---|
| Setup time | One command | Hours | 30–60 min | Plug and play |
| Web UI quality | Polished, real time | None (terminal) | Functional | Polished |
| USB auto mount | Automatic | Manual fstab | Semi auto | Automatic |
| Global access | 4 provider choices (free) | Manual port forward | Manual port forward | Cloud relay |
| Data stays private | Yes | Yes | Yes | No (cloud relay) |
| App ecosystem | Docker (CasaOS) | Anything | Plugins | Paid apps |
| Hardware cost | $35–$80 | $35–$80 | $35–$80 | $200–$1,000+ |
| Monthly cost | $0 | $0 | $0 | $0–$15 |
| Open source | Yes | Yes | Yes | No |
/
├── DATA/USB/ auto mounted USB drives appear here
├── usr/share/berryvault/console/ the OTA console (versions/ + current symlink)
├── usr/local/bin/
│ ├── berryvault-update OTA updater CLI
│ ├── berryvault-mount / -unmount auto mount helpers
│ ├── berryvault-public Tailscale Funnel toggle
│ ├── berryvault-remote show all access addresses
│ ├── berryvault-lite Lite Mode (free RAM/CPU) toggle
│ └── berryvault-tls force-HTTPS-on-LAN toggle
├── etc/
│ ├── berryvault/ settings, admin.passwd, no-ota flag, keys/
│ ├── udev/rules.d/99-berryvault-automount.rules
│ └── systemd/system/berryvault-automount@.service
├── var/lib/berryvault/ console-current.json + update-history.json
└── var/log/
├── berryvault-install.log
└── berryvault-automount.log
PRs are welcome. For major changes, open an issue first.
The installer and console are built, not hand edited.
install.shships as a singlecurl ... | sudo bashfile but is assembled from ordered fragments insrc/. The large embedded payload, the Python admin and cluster daemon, lives as a real, lintable file atsrc/lib/berryvault-cluster-daemon.pyand is inlined at build time. Editsrc/, then run./build.sh. Never hand editinstall.sh.- The admin console is
console/index.html, a single self contained file. It ships via GitHub Releases, not insideinstall.sh. To publish a new version, bumpconsole/VERSION, add a## [vX.Y.Z]section toconsole/CHANGELOG.md, then push a matchingvX.Y.Ztag. The Release Console workflow builds the tarball and SHA-256 and publishes the release the Pi pulls.
git clone https://github.com/ishaanman7898/berryvault.git
cd berryvault
# Installer changes:
./build.sh # reassemble install.sh (runs bash -n)
shellcheck src/*.sh # lint fragments
python3 -m py_compile src/lib/berryvault-cluster-daemon.py # lint the daemon
# Console release:
printf '1.20.0' > console/VERSION # match your tag
git tag v1.20.0 && git push origin v1.20.0 # triggers the release workflowHelp is especially valued on additional OS variants (Ubuntu Server), ZFS pools, richer SMART alerting, and deeper multi Pi cluster features.
See docs/TROUBLESHOOTING.md for solutions to the most common issues, including a crashed install, a Pi you cannot reach at berryvault.local, drives that do not appear, power related disconnects, and remote access problems for every supported provider.
MIT. See LICENSE.
Made with stubbornness, caffeine, and too many late nights. Your data belongs to you.