Homelab
Plex FileBrowser Upload
Adding FileBrowser to Plex: Drag-and-Drop Media Uploads via Web UI
Overview
This article adds FileBrowser as a sidecar container to Plex for drag-and-drop media uploads. Instead of using kubectl cp or temporary pods, you get a web UI where you can drag files directly into your media library. FileBrowser runs alongside Plex in the same pod, sharing the media PVC with write access while Plex keeps read-only access.
Having trouble? See v1.12.0 for what your setup should look like after completing this article.
Before You Begin
Prerequisites
- Plex Hardening completed (Plex running on encrypted PVCs)
- Firewall Rules completed (VLAN segmentation with Trusted → Lab policies)
- Access to UniFi console for adding firewall rules
What We're Setting Up
| Component | Purpose |
|---|---|
| FileBrowser sidecar | Web UI for media uploads |
| LoadBalancer Service | Expose FileBrowser on port 80 |
| Firewall rule | Allow Trusted VLANs to access FileBrowser |
Why Sidecar Instead of Separate Deployment
The Plex media PVC uses ReadWriteOnce - only one pod can mount it at a time. A separate FileBrowser deployment would fail with Multi-Attach error.
By adding FileBrowser as a sidecar container via postRenderers, it runs in the same pod as Plex and shares the volume directly. This pattern matches how playit.gg agents are added to game servers1.
Why Firewall Rule Required
With VLAN segmentation (v3-01), your devices on Trusted VLANs can't reach the Lab VLAN by default. The existing Plex Streaming rule only allows port 32400. FileBrowser needs port 80 allowed from Trusted to Lab.
Configure FileBrowser Sidecar
HelmRelease: Add postRenderers
Add postRenderers to inject the FileBrowser container and an emptyDir volume for its database.
k8s/apps/plex/helmrelease.yaml:
# ... existing HelmRepository + HelmRelease header ...
# ... existing spec.interval, chart, valuesFrom, values ...
postRenderers:
- kustomize:
patches:
- target:
kind: StatefulSet
name: plex-plex-media-server
patch: |
- op: add
path: /spec/template/spec/volumes/-
value:
name: filebrowser-db
emptyDir: {}
- op: add
path: /spec/template/spec/containers/-
value:
name: filebrowser
image: filebrowser/filebrowser:v2.31.2
args:
- --noauth
- --root=/srv
- --database=/database/filebrowser.db
ports:
- containerPort: 80
volumeMounts:
- name: media
mountPath: /srv
- name: filebrowser-db
mountPath: /database
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 256Mi Using --noauth since FileBrowser is only accessible from Trusted VLANs behind the firewall. Add authentication if exposing externally.
Service: Expose FileBrowser
Create a LoadBalancer service targeting the Plex pod's FileBrowser container.
k8s/apps/plex/filebrowser-service.yaml:
---
apiVersion: v1
kind: Service
metadata:
name: filebrowser
namespace: plex
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: plex-media-server
app.kubernetes.io/instance: plex
ports:
- port: 80
targetPort: 80 Kustomization: Add Service
k8s/apps/plex/kustomization.yaml:
# ... existing header ...
resources:
- namespace.yaml
- configmap.yaml
- pvc.yaml
- secret.sops.yaml
- helmrelease.yaml
- networkpolicy.yaml
- filebrowser-service.yaml # ADD Create Firewall Rule
Navigate to Settings -> Security -> Zones in UniFi. Click the Trusted -> Lab cell and create a policy.
| Field | Value |
|---|---|
| Name | FileBrowser Upload |
| Action | Allow |
| Protocol | TCP |
| Source Zone | Trusted |
| Source | Any |
| Destination Zone | Lab |
| Destination | Any |
| Destination Port | 80 |
This allows devices on Trusted VLANs (Unrestricted-Trusted, Things-Trusted, Restricted-Trusted) to reach FileBrowser directly without Tailscale.
Without this rule, traffic routes through Tailscale's subnet router, reducing upload speeds from ~15 MB/s to ~1.7 MB/s.
Deploy FileBrowser
Git: Commit Changes
cd ~/homelab
git add k8s/apps/plex/helmrelease.yaml k8s/apps/plex/filebrowser-service.yaml k8s/apps/plex/kustomization.yaml
git commit -m "feat(plex): add filebrowser sidecar for media uploads"
git push Flux: Reconcile
flux reconcile source git flux-system
flux reconcile kustomization sync The Plex pod will restart with the FileBrowser sidecar (2/2 containers).
Verify FileBrowser
Verify: Pod Running
kubectl get pods -n plex Expected: plex-plex-media-server-0 shows 2/2 containers running.
Verify: Service IP
kubectl get svc filebrowser -n plex Expected: External IP assigned by MetalLB (e.g., 192.168.10.51).
Verify: FileBrowser Logs
kubectl logs -n plex plex-plex-media-server-0 -c filebrowser Expected: Listening on [::]:80
Verify: Web Access
Open http://<EXTERNAL-IP> in your browser. You should see the FileBrowser interface with your media directory.
Verify: Upload Speed
Drag a file into FileBrowser and verify upload speeds:
| Access Method | Expected Speed |
|---|---|
| Direct (firewall rule) | ~15+ MB/s |
| Via Tailscale subnet | ~1-2 MB/s |
Next Steps
With FileBrowser configured, you can drag and drop media files directly into your Plex library from any device on your Trusted VLANs.
Resources
Footnotes
L. Lopez, "Factorio playit.gg Public Access," lelopez.io. Accessed: Apr. 11, 2026. [Online]. Available: https://lelopez.io/blog/homelab-v2-11a-factorio-playit-public-access ↩