This repository contains a Docker setup for a browser environment with VNC access, optimized for multi-architecture builds.
- Ubuntu 22.04 with XFCE4 desktop environment
- Chromium browser pre-installed and configured
- Python 3.13, Supervisor 4.3.0, Node.js 22, and Yarn
- TigerVNC (
Xvnc) server for remote desktop access - Screen lock/screensaver disabled for uninterrupted operation
- Multi-architecture support (AMD64 and ARM64)
- Optional
zhlocale tag with Chinese fonts installed and fcitx5 enabled (English keyboard stays default; toggle Chinese withCtrl+Space).
This project uses Docker BuildX to create images that run on both Intel/AMD (amd64) and Apple Silicon (arm64) architectures.
- Docker with BuildX: Ensure you have a recent version of Docker installed. Docker Desktop (Mac/Windows) includes BuildX by default. On Linux, you may need to install or enable it separately.
The included build-multi-arch.sh script automates the build process and can now produce both the default (English) image and a zh variant with Chinese fonts/input pre-configured.
-
Set the Version: Before building, update the
VERSIONfile in this directory with the desired semantic version (e.g.,1.2.0). This file is the single source of truth for versioning. -
Run the Build Script: The script will automatically read the
VERSIONfile and tag the image accordingly.For Local Development (Default): Running the script without any flags will build the image for your machine's architecture and load it directly into your local Docker daemon.
# Build for your local architecture and load into Docker ./build-multi-arch.shThe image will then be available in
docker images.For Publishing: To build the multi-architecture image and push it to Docker Hub, use the
--pushflag. This requires you to be logged in viadocker loginfirst.# Build for all supported architectures and push to Docker Hub ./build-multi-arch.sh --pushOther Options:
# Perform a clean build with no cache ./build-multi-arch.sh --no-cache
Pass --variant zh to the build script to install Chinese fonts, locales, and fcitx5. The script automatically tags the result as autobyteus/chrome-vnc:<version>-zh and autobyteus/chrome-vnc:zh.
# Build the zh variant for your local architecture and load it into Docker
./build-multi-arch.sh --variant zh
# Build multi-arch zh images and push them
./build-multi-arch.sh --variant zh --pushInside the zh image, English remains the default input method. Users can press Ctrl+Space (fcitx default) or click the fcitx tray icon to toggle Chinese Pinyin input and render Chinese websites with preinstalled fonts.
The build-multi-arch.sh script attempts to create and use a dedicated BuildX builder named multi-platform-builder. If you encounter issues, you may need to run these setup commands manually.
-
Create a builder (if it doesn't exist):
docker buildx create --name multi-platform-builder --use
-
Enable QEMU for cross-platform emulation (required for first-time setup):
docker run --privileged --rm tonistiigi/binfmt --install all
After pushing an image, you can verify that it supports multiple architectures with the following command:
docker buildx imagetools inspect autobyteus/chrome-vnc:latestThe output should list both linux/amd64 and linux/arm64 under "Manifests".
After building the image locally or pulling it from Docker Hub, you can easily start a standalone container for direct use or testing.
-
Use the Run Script: The included
run-container.shscript is the recommended way to start the container. It will automatically use your locally built image or pull from Docker Hub if a local version isn't found../run-container.sh
-
Accessing the Container: Once started, you can access the container's desktop environment:
- VNC (TigerVNC/Xvnc): Connect your VNC client to
localhost:5900(or your custom port). No password is required. - Chrome Debugging: The browser's remote debugging port is available at
localhost:9223(or your custom port). - Chinese Input (zh tag only): fcitx5 autostarts in the panel; press
Ctrl+Spaceto toggle between the default English keyboard and Chinese Pinyin, or click the fcitx icon to pick another layout.
The browser profile is persisted in a Docker volume mounted at
/home/vncuser/.config/chromium. This keeps Chromium cookies, local storage, preferences, and other profile state across container removal/recreation through the provided run script and Compose files. - VNC (TigerVNC/Xvnc): Connect your VNC client to
-
Customization and Troubleshooting:
Screen Resolution: The default screen resolution is
1920x1080x24. You can override this using the--resolutionflag. The format isWIDTHxHEIGHTxDEPTH.# Run with a custom resolution of 1366x768 ./run-container.sh --resolution 1366x768x24Port Conflicts: If you get a "port is already allocated" error, you can specify different host ports using flags:
# Run VNC on host port 5902 and the debug port on 9224 ./run-container.sh --vnc-port 5902 --debug-port 9224Other Customizations: You can also specify a custom tag or container name:
# Run a specific version and give the container a custom name ./run-container.sh --tag 1.2.0 --name my-custom-container # Use a specific persistent Chromium profile volume ./run-container.sh --name my-custom-container --profile-volume my-custom-container-chromium-profile # Run the Chinese-enabled image (built or pulled as autobyteus/chrome-vnc:zh) ./run-container.sh --tag zh
Google can still require password or two-factor re-authentication for account-security reasons. The persistent volume prevents local profile loss; it does not override Google's session policy.
Downstream images based on this image should also mount
/home/vncuser/.config/chromiumto persistent storage in their owndocker runor Compose entry points.
If a container is stopped abruptly (power loss, daemon crash), VNC can fail to come back with:
Server is already active for display 99
Root cause is usually stale X lock/socket files:
/tmp/.X99-lock/tmp/.X11-unix/X99
This image now starts TigerVNC via /usr/local/bin/start-vnc.sh, which removes stale lock/socket files when they are not owned by a live X server process.
For already-running older containers (built before this fix), recover manually:
docker exec <container> sh -lc 'rm -f /tmp/.X99-lock /tmp/.X11-unix/X99 && supervisorctl restart tigervnc xfce chrome copyq'To make recovery permanent, rebuild/pull the updated image and recreate containers.
Chromium can also leave profile lock files behind when a container is removed
and recreated while reusing the persistent profile volume. Current images clear
known stale Chromium lock artifacts during /entrypoint.sh startup before
Supervisor launches Chromium. The cleanup preserves the locks when they appear
to belong to a live Chromium/Chrome process in the current container, and it
does not delete browser profile data.
For already-running older containers that fail with "The profile appears to be in use", recover manually:
docker exec <container> sh -lc 'rm -f /home/vncuser/.config/chromium/SingletonLock /home/vncuser/.config/chromium/SingletonSocket /home/vncuser/.config/chromium/SingletonCookie /home/vncuser/.config/chromium/Default/LOCK /home/vncuser/.config/chromium/Default/.org.chromium.Chromium.* && supervisorctl restart chrome'