Neko
Self-hosted virtual browser running in Docker
Neko is a self-hosted virtual browser that runs in a Docker container and is shared through WebRTC. It is used for watch parties, secure browsing, and collaborative sessions.
Key features
- Virtual browser in Docker
- WebRTC streaming
- Multi-user sessions
- Watch-party friendly
Pros & cons
Strengths
- Shared browser sessions
- Low-latency WebRTC
- Multi-user control
Trade-offs
- CPU intensive streaming
- WebRTC port setup
Neko replaces
Last reviewed Aug 26, 2026 · 840 words
Neko needs two things you probably haven't given a container before: a range of UDP ports forwarded straight through your router, and about 2 CPU cores per running browser. Get those right and you have a shared Firefox that 5 people can watch and take turns controlling with under a second of latency, which is the entire watch-party and "let me show you this" use case. Get them wrong and you get a black screen with a working chat, which is the most common Neko question by a wide margin.
The UDP range is the setup
The web UI and signalling go over one TCP port; the video and audio go over WebRTC, which means UDP, which means Docker port publishing and your router both need a range:
services:
neko:
image: ghcr.io/m1k1o/neko/firefox:latest
restart: unless-stopped
shm_size: 2gb
ports:
- "8080:8080"
- "52000-52100:52000-52100/udp"
environment:
NEKO_DESKTOP_SCREEN: 1920x1080@30
NEKO_MEMBER_MULTIUSER_USER_PASSWORD: watch
NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD: control
NEKO_WEBRTC_EPR: 52000-52100
NEKO_WEBRTC_NAT1TO1: 203.0.113.10
NEKO_WEBRTC_EPR is the ephemeral port range Neko will use, NEKO_WEBRTC_NAT1TO1 is the public IP it should advertise to peers, and the two must line up with a UDP forward for that same range on the router. Those are the version 3 variable names; older guides use NEKO_EPR, NEKO_NAT1TO1, NEKO_SCREEN, and NEKO_PASSWORD, and mixing the two sets is the second most common failure. Keep the range to about 100 ports; Docker publishes each one individually and a range of 10,000 takes minutes to start. Put Caddy in front of port 8080 for TLS, because browsers won't grant microphone or clipboard access to a plain-HTTP origin.
Budget 2 cores per session, not per viewer
Neko runs a real X server and a real browser inside the container, captures the screen, and encodes it in software as VP8 or H.264. That encoder is the cost, and it's paid once per session regardless of how many people are watching. At 1920x1080 and 30 fps, expect 2 cores fully busy and the catalogue's 2 GB of RAM; drop to 1280x720 and the CPU roughly halves. Viewers are cheap on the server and expensive on your uplink: each peer gets its own copy of the stream, at 3 to 5 Mbps for 1080p, so 5 viewers on a 20 Mbps home upload is the ceiling. Two simultaneous sessions means two containers and 4 cores, which is where a used office desktop with a proper CPU beats an ARM board.
Which image: Firefox, Chromium, VLC, or a whole desktop
The project publishes images for Firefox, Chromium, Google Chrome, Edge, Brave, Vivaldi, Tor Browser, VLC, and a few desktop environments. Firefox is the default and the one I'd start with; its profile survives restarts if you mount /home/neko/.mozilla/firefox. Chromium is the better kiosk. VLC is for the case where the "browser" only ever plays a file or a stream, and it uses noticeably less CPU because there's no page rendering. Expect DRM-protected streaming services to refuse to play; the images don't carry the content-decryption modules those platforms require. Anything you host yourself plays fine, and a Jellyfin tab inside Neko is a perfectly good way to watch your own library with people who don't have accounts.
Behind a VPN you can skip the NAT dance
If everyone who'll join is on your Tailscale network, set NEKO_WEBRTC_NAT1TO1 to the host's tailnet address, forward nothing on the router, and the UDP range only needs to be reachable inside the tunnel. That is the calmest setup for a family. For the general case where guests join from anywhere and some are behind carrier-grade NAT, add a TURN server such as coturn and give Neko its address via the ICE server settings; without one, a small percentage of guests will never connect and you'll never find out why.
What it is not
Neko is one shared session, not a workspace per user. If you want isolated browsers for several people, that's Kasm Workspaces. If you want to reach your own desktop remotely, that's RustDesk, not a container. And it isn't private in the way a VPN is: everyone in the room sees the same screen and whoever holds control drives it, so the admin password matters and a public URL with a guessable user password is an open browser on your network.
What I'd do
The Firefox image, 720p at 30 fps to keep the CPU sane, a 100-port UDP range forwarded on the router, Caddy in front for TLS, and the profile directory mounted so logins persist. For a family, the Tailscale variant with no forwarding at all. Treat it as a room you open for an evening rather than a service that stays up: docker compose up -d before the film, down afterwards, because an idle Neko still burns a core rendering a browser nobody is looking at.
Similar remote access & vpn apps
RustDesk
Remote Access & VPNOpen-source remote desktop alternative to TeamViewer
Replaces TeamViewer, AnyDesk
frp
Remote Access & VPNFast reverse proxy to expose local servers behind NAT
Replaces ngrok
Headscale
Remote Access & VPNOpen-source self-hosted Tailscale control server
Replaces Tailscale
Sunshine
Remote Access & VPNSelf-hosted game-stream host for Moonlight clients
Replaces NVIDIA GameStream, Parsec
Tailscale
Remote Access & VPNZero-config mesh VPN built on WireGuard
Replaces ZeroTier
JumpServer
Remote Access & VPNOpen-source bastion host and PAM platform
Replaces CyberArk, Teleport