- 1. Introduction to
miniserve
- 2. Prerequisites
- 3. Phase 1: RK3588 Debian Bullseye Preparation
- 4. Phase 2:
netbird
Installation and Configuration - 5. Phase 3:
miniserve
Installation on ARM64 - 6. Phase 4: Running
miniserve
- 7. Phase 5: Accessing
miniserve
and Other Services vianetbird
- 8. Phase 6: Advanced
miniserve
Configuration & 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.
netbird
Account: You’ll need anetbird.io
account.
#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 up
This will provide a URL. Open it in a browser on any device, log in to your
netbird
account, and authorize the RK3588. - Method 2: Setup Key (Recommended for headless servers):
- In your
netbird
admin 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 miniserve
The binary will be in
$HOME/.cargo/bin/miniserve
. Ensure this is in yourPATH
or move the binary to/usr/local/bin/
. - Verify:
$HOME/.cargo/bin/miniserve --version
(orminiserve --version
if 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 after
Alternatively, 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:ro
for uploads.-p <YOUR_NETBIRD_IP>:<PORT>:8080
: Bindsminiserve
’s port8080
inside the container to a specific<PORT>
on your RK3588’s<YOUR_NETBIRD_IP>
.--restart unless-stopped
: For persistence./data -p 8080
: Tellsminiserve
inside the container to serve/data
on port8080
.- Note on Volume Permissions: If
miniserve
inside 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 IDminiserve
runs 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
systemd
Unit File: Create/etc/systemd/system/miniserve@.service
(ensureminiserve
binary 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=yes
is 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-runner
Then, in your systemd override (next step), you’ll add
User=miniserve-runner
andGroup=miniserve-runner
. - Determine and Escape the Path to Serve:
Example: For
/srv/miniserve_data
:systemd-escape /srv/miniserve_data
This might output
srv-miniserve_data
. This is your<escaped-path>
. - Create
systemd
Override 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" -- %I
Ensure
/usr/local/bin/miniserve
is the correct absolute path to yourminiserve
binary. - File System Permissions for the Served Directory:
The user
miniserve
runs as (either dynamic orminiserve-runner
) needs read access to/srv/miniserve_data
and 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/group
If
DynamicUser=yes
and serving from outside standard system paths (like/srv
), you might needsetfacl
for more granular permissions ifchown
is 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:password
or--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:
-u
or-u /allowed/subdir
. Use with caution regarding permissions. - Directory Creation:
--mkdir
(requires uploads). - WebDAV:
--enable-webdav
for 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
miniserve
runs 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
ExecStart
with:--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
miniserve
Service Issues:sudo systemctl status miniserve@<escaped-path>.service
sudo journalctl -u miniserve@<escaped-path>.service -n 100 --no-pager --follow
- Check
miniserve
binary path and permissions. - Manually run the
ExecStart
command from the systemd unit (as the correct user if specified) to see direct errors.
netbird
Connectivity:sudo netbird status
on all relevant peers.- Ping
netbird
IPs between peers. - Check
netbird
admin dashboard for peer status and access rules.
- Firewall:
- Temporarily
sudo ufw disable
to 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
miniserve
runs as has read (and write, if uploads enabled) permissions for the target directories.