- 1. Introduction to
miniserve - 2. Prerequisites
- 3. Phase 1: RK3588 Debian Bullseye Preparation
- 4. Phase 2:
netbirdInstallation and Configuration - 5. Phase 3:
miniserveInstallation on ARM64 - 6. Phase 4: Running
miniserve - 7. Phase 5: Accessing
miniserveand Other Services vianetbird - 8. Phase 6: Advanced
miniserveConfiguration & Security - 9. Phase 7: Troubleshooting
#1. Introduction to miniserve
As detailed in its README.md, miniserve is a “CLI tool to serve files and dirs over HTTP.” It’s designed to be small, self-contained, and cross-platform, making it ideal for quickly sharing files. Built in Rust, it offers good performance. Key features include serving single files or entire directories, MIME type handling, authentication, folder downloads, file uploading, directory creation, themes, QR code support, TLS, and read-only WebDAV support.
#2. Prerequisites
- RK3588 Device: An ARM64 device (e.g., Orange Pi 5, Rock 5B).
- Operating System: Debian Bullseye (or compatible) installed.
- Basic Linux Knowledge: Command line, package installation, file editing.
- Root/Sudo Access.
- Internet Connectivity.
netbirdAccount: You’ll need anetbird.ioaccount.
#3. Phase 1: RK3588 Debian Bullseye Preparation
Ensure your Debian Bullseye system is ready.
#System Update
Log in via SSH and run:
sudo apt update
sudo apt full-upgrade -y
sudo apt autoremove -y
sudo apt clean
# Consider a reboot if kernel updates occurred: sudo reboot
#Essential Tools
Install common utilities if not already present:
sudo apt install -y curl wget git ca-certificates gnupg
#4. Phase 2: netbird Installation and Configuration
netbird creates a secure peer-to-peer VPN.
#Install netbird Client
The recommended way to install netbird on Linux is using their installation script:
curl -fsSL https://pkgs.netbird.io/install.sh | sudo bash
This script will typically detect your OS (Debian), add the necessary repository and GPG key, and install the netbird package.
Alternatively, for manual installation, refer to the official Netbird documentation, as steps can change.
#Log in to netbird
Once installed, connect your RK3588 to your netbird network:
- Method 1: Interactive Login (if you have easy browser access):
sudo netbird upThis will provide a URL. Open it in a browser on any device, log in to your
netbirdaccount, and authorize the RK3588. - Method 2: Setup Key (Recommended for headless servers):
- In your
netbirdadmin dashboard (app.netbird.io), go to “Setup Keys.” - Create a new key (reusable or one-time, as needed). Copy the generated key.
- On your RK3588, run:
sudo netbird up --setup-key YOUR_COPIED_SETUP_KEY
- In your
#Verify netbird Connection & Identify IP
Check the netbird status on your RK3588:
sudo netbird status
This command will show if the client is connected and will display its netbird IP address (e.g., 100.x.y.z). Note this IP.
You can also use:
ip addr show netbird0 # Or the interface name shown by 'netbird status'
#Enable netbird Service
Ensure netbird starts on boot:
sudo systemctl enable --now netbird
#5. Phase 3: miniserve Installation on ARM64
#Option A: Using Pre-compiled Binaries (Recommended)
miniserve provides pre-built aarch64-unknown-linux-musl (statically linked, good portability) or aarch64-unknown-linux-gnu binaries.
- Find the Latest Release: Go to
https://github.com/svenstaro/miniserve/releases. - Download the ARM64 Binary:
On your RK3588 (replace
<VERSION>and adjust binary name if needed):VERSION="0.29.0" # Check for the actual latest version! # Choose musl for static linking or gnu BINARY_FILENAME="miniserve-${VERSION}-aarch64-unknown-linux-musl" # BINARY_FILENAME="miniserve-${VERSION}-aarch64-unknown-linux-gnu" cd /tmp wget "https://github.com/svenstaro/miniserve/releases/download/v${VERSION}/${BINARY_FILENAME}" -O miniserve-arm64 - Make Executable and Install:
chmod +x miniserve-arm64 sudo mv miniserve-arm64 /usr/local/bin/miniserve - Verify:
miniserve --version
#Option B: Building from Source with cargo
- Install Rust & Build Tools:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh source "$HOME/.cargo/env" # Or re-login/open new terminal sudo apt install -y build-essential pkg-config libssl-dev # For GNU target - Install
miniserve:cargo install --locked miniserveThe binary will be in
$HOME/.cargo/bin/miniserve. Ensure this is in yourPATHor move the binary to/usr/local/bin/. - Verify:
$HOME/.cargo/bin/miniserve --version(orminiserve --versionif in PATH).
#Option C: Using Docker
miniserve offers multi-arch Docker images.
- Install Docker:
The simplest way is often the convenience script:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh sudo usermod -aG docker your_user # Add your user to docker group, re-login afterAlternatively, follow manual instructions from the Docker Debian documentation.
- Run
miniserve:# Replace /host/path/to/share with the actual path on your RK3588 docker run -d --name my-miniserve \ -v /host/path/to/share:/data:ro \ -p <YOUR_NETBIRD_IP>:<PORT>:8080 \ --restart unless-stopped \ docker.io/svenstaro/miniserve /data -p 8080-d: Run detached.--name my-miniserve: Name the container.-v /host/path/to/share:/data:ro: Mounts your host directory read-only (:ro) into the container. Remove:rofor uploads.-p <YOUR_NETBIRD_IP>:<PORT>:8080: Bindsminiserve’s port8080inside the container to a specific<PORT>on your RK3588’s<YOUR_NETBIRD_IP>.--restart unless-stopped: For persistence./data -p 8080: Tellsminiserveinside the container to serve/dataon port8080.- Note on Volume Permissions: If
miniserveinside Docker (often runs as non-root) can’t read/host/path/to/share, ensure the host path has appropriate read permissions for the user/group IDminiserveruns as in the container, or explore Docker’s user mapping options.
(The rest of this tutorial focuses on non-Docker systemd setup for miniserve)
#6. Phase 4: Running miniserve
#Create a Directory to Serve
mkdir -p /srv/miniserve_data # Or your preferred location
echo "Hello from miniserve on RK3588 via Netbird!" > /srv/miniserve_data/index.html
sudo chown -R your_user:your_user /srv/miniserve_data # Change 'your_user' if needed
#Manual Test Run (Binding to netbird IP)
Replace <YOUR_NETBIRD_IP> and <PORT> (e.g., 8080).
miniserve -i <YOUR_NETBIRD_IP> -p <PORT> /srv/miniserve_data
Test access from another netbird device: http://<YOUR_NETBIRD_IP>:<PORT>. Press CTRL+C to stop.
#Setting up miniserve as a systemd Service
- Obtain and Place the
systemdUnit File: Create/etc/systemd/system/miniserve@.service(ensureminiservebinary path is correct):[Unit] Description=miniserve for %i After=network-online.target netbird.service Wants=network-online.target netbird.service [Service] ExecStart=/usr/local/bin/miniserve -- %I # Verify this path to miniserve # Security Hardening IPAccounting=yes # IPAddressAllow/Deny are removed here as miniserve will bind to a specific IP. # If miniserve were to bind 0.0.0.0, you'd use IPAddressAllow for Netbird subnet. DynamicUser=yes PrivateTmp=yes PrivateUsers=yes PrivateDevices=yes NoNewPrivileges=true ProtectSystem=strict ProtectHome=read-only # Change to 'no' or use a dedicated user if serving from /home ProtectClock=yes ProtectControlGroups=yes ProtectKernelLogs=yes ProtectKernelModules=yes ProtectKernelTunables=yes ProtectProc=invisible CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_DAC_READ_SEARCH [Install] WantedBy=multi-user.target - Dedicated User for
miniserve(Optional but Recommended): IfDynamicUser=yesis problematic for permissions, or you prefer explicit control:sudo groupadd --system miniserve-runner sudo useradd --system -g miniserve-runner -d /var/empty -s /bin/false miniserve-runnerThen, in your systemd override (next step), you’ll add
User=miniserve-runnerandGroup=miniserve-runner. - Determine and Escape the Path to Serve:
Example: For
/srv/miniserve_data:systemd-escape /srv/miniserve_dataThis might output
srv-miniserve_data. This is your<escaped-path>. - Create
systemdOverride File for Custom Options: Usesudo systemctl edit miniserve@<escaped-path>.service. Add:[Service] # If using a dedicated user: # User=miniserve-runner # Group=miniserve-runner # Clear default ExecStart ExecStart= # Set our custom ExecStart. Replace <YOUR_NETBIRD_IP> and <PORT>. # Add other miniserve flags as needed (e.g., --auth, -u, --tls-cert). ExecStart=/usr/local/bin/miniserve -i <YOUR_NETBIRD_IP> -p <PORT> --title "RK3588 Files" -- %IEnsure
/usr/local/bin/miniserveis the correct absolute path to yourminiservebinary. - File System Permissions for the Served Directory:
The user
miniserveruns as (either dynamic orminiserve-runner) needs read access to/srv/miniserve_dataand its contents. If usingminiserve-runner:sudo chown -R miniserve-runner:miniserve-runner /srv/miniserve_data sudo chmod -R u=rX,g=rX,o-rwx /srv/miniserve_data # Read/execute for user/groupIf
DynamicUser=yesand serving from outside standard system paths (like/srv), you might needsetfaclfor more granular permissions ifchownis not desired, or ensure the path is world-readable (less secure). - Reload
systemd, Enable, and Start the Service:sudo systemctl daemon-reload sudo systemctl enable --now miniserve@<escaped-path>.service - Check Service Status:
sudo systemctl status miniserve@<escaped-path>.service sudo journalctl -u miniserve@<escaped-path>.service -f
#7. Phase 5: Accessing miniserve and Other Services via netbird
#Accessing miniserve
From another device on your netbird network, use your browser:
http://<YOUR_NETBIRD_IP>:<PORT> (or https:// if you configured TLS).
#Accessing SSH, FTP, etc.
Services like SSH on your RK3588 are now accessible via its netbird IP from other peers in your netbird network:
ssh your_rk3588_user@<YOUR_NETBIRD_IP>
Similarly for FTP or other services configured to listen on the netbird IP or 0.0.0.0.
#8. Phase 6: Advanced miniserve Configuration & Security
#Key miniserve Features
Consult miniserve --help and the README.md.
- Authentication:
--auth username:passwordor--auth-file /path/auth.txt. Highly recommended. Example for systemd override:ExecStart=... --auth "admin:$(openssl passwd -1 'securepass')" -- %I - TLS (HTTPS):
--tls-cert /path/cert.pem --tls-key /path/key.pem. See “TLS Certificate Generation with SAN” below. - File Uploads:
-uor-u /allowed/subdir. Use with caution regarding permissions. - Directory Creation:
--mkdir(requires uploads). - WebDAV:
--enable-webdavfor read-only WebDAV access. This can be a good alternative to FTP for file management over HTTP.
#TLS Certificate Generation with SAN
For self-signed certificates to work well with modern browsers (even over netbird), include a Subject Alternative Name (SAN) for the IP.
- Create a directory for certs:
sudo mkdir -p /etc/miniserve/tls; cd /etc/miniserve/tls - Generate key and cert (replace
<YOUR_NETBIRD_IP>):sudo openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -sha256 -days 3650 -nodes \ -subj "/CN=<YOUR_NETBIRD_IP>" \ -addext "subjectAltName = IP:<YOUR_NETBIRD_IP>" - Set permissions (if
miniserveruns asminiserve-runner):sudo chown -R miniserve-runner:miniserve-runner /etc/miniserve/tls sudo chmod 600 /etc/miniserve/tls/key.pem sudo chmod 644 /etc/miniserve/tls/cert.pem - Update your systemd override
ExecStartwith:--tls-cert /etc/miniserve/tls/cert.pem --tls-key /etc/miniserve/tls/key.pem - Access via
https://<YOUR_NETBIRD_IP>:<PORT>. You’ll need to accept the self-signed certificate warning in your browser.
#Firewall (UFW on RK3588)
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh # Essential for remote access
# Allow miniserve port ONLY from Netbird interface (e.g., netbird0)
sudo ufw allow in on netbird0 to any port <PORT> proto tcp
sudo ufw enable
sudo ufw status verbose
#netbird Access Controls
Utilize netbird’s dashboard to create access policies, restricting which peers can connect to your RK3588 and on which ports/protocols for fine-grained security.
#Regular Updates
Keep Debian, netbird, and miniserve updated.
sudo apt update && sudo apt full-upgrade -y
# For miniserve from cargo: cargo install --locked miniserve
# For Netbird: usually updates via apt if repo was added.
#9. Phase 7: Troubleshooting
miniserveService Issues:sudo systemctl status miniserve@<escaped-path>.servicesudo journalctl -u miniserve@<escaped-path>.service -n 100 --no-pager --follow- Check
miniservebinary path and permissions. - Manually run the
ExecStartcommand from the systemd unit (as the correct user if specified) to see direct errors.
netbirdConnectivity:sudo netbird statuson all relevant peers.- Ping
netbirdIPs between peers. - Check
netbirdadmin dashboard for peer status and access rules.
- Firewall:
- Temporarily
sudo ufw disableto isolate firewall issues. If it works, your UFW rules need adjustment. Re-enable UFW. - Check UFW logs:
sudo less /var/log/ufw.log.
- Temporarily
- Permissions: Double-check that the user
miniserveruns as has read (and write, if uploads enabled) permissions for the target directories.