Browser-based RDP to a Windows PC. Open a URL anywhere, sign in, and get the desktop in a browser tab. No VPN client, no port forwarding, and nothing installed on the device you are browsing from.
Windows 11 + Docker Desktop. Free — no domain required.
The goal is browser-only remote access from devices where installing an RDP or VPN client is not practical or permitted.
A VPN alone does not solve this. A VPN gives you a network connection — you would still need an RDP client on the far end, plus VPN software installed. That is not available on many managed or restricted devices.
This is a web gateway instead. Apache Guacamole renders RDP as HTML5, so the remote device only loads a web page. Tailscale Funnel publishes it at a real HTTPS hostname with no inbound ports opened.
[Windows PC] Docker: Guacamole + guacd + Postgres renders RDP as HTML5
| RDP -> host.docker.internal:3389
[Windows PC] Tailscale Funnel public HTTPS URL, outbound only
|
[Any browser, anywhere] -> https://<host>.tailXXXX.ts.net/guacamole
| File | Purpose |
|---|---|
| SETUP.md | Start here. Full build guide + troubleshooting. |
| CONFIG-REFERENCE.md | Where every setting lives; which password is which |
| BUILD.md | Source and recreation instructions for optional local BAT helpers |
docker-compose.yml |
Guacamole + guacd + Postgres |
docker-compose.override.yml.example |
Pattern for keeping real credentials untracked |
The optional .bat helpers are intentionally ignored by Git. Recreate them locally from
BUILD.md, or use the manual commands in SETUP.md.
# 1. Install Docker Desktop. If it says "WSL not installed":
wsl --install # in an Administrator PowerShell, then reboot
# 2. Clone to C:\guac-rdp, then set the Postgres password in docker-compose.yml
# (appears twice, both must match)
# 3. Generate the DB schema
New-Item -ItemType Directory -Force -Path .\initdb | Out-Null
docker run --rm guacamole/guacamole:1.5.5 /opt/guacamole/bin/initdb.sh --postgresql `
| Out-File -Encoding ascii .\initdb\01-schema.sql
# 4. Start
docker compose up -d
Start-Process "http://localhost:8080/guacamole"
# 5. Expose it after securing the Guacamole account
tailscale funnel --bg 8080Full detail, optional local helper scripts, and troubleshooting are in SETUP.md and BUILD.md.
There are three unrelated sets of credentials:
| Credential | Lives in | For |
|---|---|---|
| Postgres user/password | docker-compose.yml |
Containers talking to each other. Never typed in a browser. |
| Guacamole login | The web UI | Your actual website login. Starts guacadmin/guacadmin. |
| Windows RDP account | Windows | What Guacamole uses to open the RDP session |
Typing the docker-compose username into the Guacamole login page does not work. It is not a website account.
- Windows 11 Pro required — Home has no RDP host.
- One interactive session — two people connecting bump each other. Windows limit.
- Funnel always relays through Tailscale's servers. That is what provides browser-only access with no client on the far end. Expect latency; tune the display flags (SETUP.md, Step 5.5).
- Docker Desktop starts on user sign-in, not at boot — if the PC reboots unattended, the stack does not come back and the URL returns 502. Test this before relying on it.
.ts.netmay be blocked by some managed-network filters under "remote access."
This puts a login page for a remote desktop on the public internet.
- Use a long random password + TOTP on the Guacamole account. It is the primary gate.
- If the Windows RDP account is an Administrator, compromising that login means full control of the PC.
- Turn Funnel off when it is not needed.
- Using remote access from a managed device may violate its acceptable-use policy.
- Never commit
data/— it holds password hashes and stored RDP credentials. - Never commit
.env,docker-compose.override.yml, database backups, or generated BAT files. The supplied.gitignorecovers these paths.
Apache Guacamole (Apache-2.0) · Tailscale · PostgreSQL