Setting up a fresh development machine should not take half a day.
This project gives you a portable “developer desktop in a container” with:
- LinuxServer Webtop (Ubuntu XFCE)
- VS Code CLI
- OpenAI Codex CLI
- Tailscale daemon auto-start
- XRDP for RDP/Guacamole clients
- Pluggable installer scripts so you can extend the image your way
Repo: https://github.com/jcianci12/developer-webtop-docker-vm
Why this setup is useful
If you juggle multiple machines, client environments, or short-lived projects, this pattern is a big win:
- Reproducible: rebuild the same environment consistently
- Fast recovery: persistent config is stored in
./data - Easy sharing: publish-safe template with no real secrets committed
- Remote-ready: connect over RDP or through Tailscale
What is in the stack
The Compose service builds a local image (dev-webtop:local) and runs a Webtop desktop container.
Key details:
- Selected installers run at image build time for deterministic startup
- Container publishes RDP on host
3389:3389 ./datais mounted to/configfor persistence- Custom init hooks start
tailscaledandxrdpautomatically
Quick start
- Clone and configure:
git clone https://github.com/jcianci12/developer-webtop-docker-vm.git
cd developer-webtop-docker-vm
cp .env.example .env
- Edit
.envand set:
RDP_PASSWORDto a strong valueTZto your timezoneINSTALL_SCRIPTSto the installers you want
- Build and run:
docker compose up -d --build
- Verify tools:
docker exec dev-webtop sh -lc "code --version | sed -n '1p'; codex --version; tailscale status || true"
- First-time Tailscale auth (inside container terminal):
tailscale up
RDP and Guacamole
RDP is available on host port 3389.
- Host:
127.0.0.1(or your Docker host IP) - Port:
3389 - Username:
${RDP_USER} - Password:
${RDP_PASSWORD}
If Guacamole runs on the same Docker network, point it at:
- Host:
dev-webtop - Port:
3389
If it is on a different network:
docker network connect <network-name> dev-webtop
Customize with installer scripts
The best part of this template is extensibility.
Add your own scripts in installers/, then include them in INSTALL_SCRIPTS.
Example:
chmod +x installers/python-tools.sh
Then in .env:
INSTALL_SCRIPTS=core-tools,tailscale,rdp,python-tools
Rebuild:
docker compose up -d --build
Notes from real usage
curlagainstlocalhost:3389will fail with HTTP reset, which is expected because 3389 is RDP, not HTTP.- Tailscale may show “Logged out” until
tailscale upis completed. - Desktop/container warnings around DBus components are common in containerized desktop environments and are often non-fatal.
Who this is for
- DevOps and platform engineers who need repeatable dev workspaces
- Consultants managing many client contexts
- Teams needing a “known-good” remote desktop baseline
- Homelab users building secure remote dev access
Final thoughts
You can treat this repo as:
- A daily driver remote dev box
- A template for team onboarding
- A base image for your own toolchain installers
If this saves you time, star the repo and share your installer combos:
Leave a Reply