{"id":18373140,"url":"https://github.com/thanatisia/websocket-xorg-docker","last_synced_at":"2026-01-23T15:43:08.885Z","repository":{"id":214815035,"uuid":"737425331","full_name":"Thanatisia/websocket-xorg-docker","owner":"Thanatisia","description":"Base VNC + WebSocket server docker image that aims to simplify the initial setup of a containerized Graphical environment","archived":false,"fork":false,"pushed_at":"2024-03-14T00:06:24.000Z","size":113,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-11T02:15:38.902Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Thanatisia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOGS.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":"docs/supported.md","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-31T01:32:59.000Z","updated_at":"2024-07-29T05:05:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"1a5a4321-751e-4c0f-9c13-3f6da5d6048c","html_url":"https://github.com/Thanatisia/websocket-xorg-docker","commit_stats":null,"previous_names":["thanatisia/websocket-xorg-docker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Thanatisia/websocket-xorg-docker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thanatisia%2Fwebsocket-xorg-docker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thanatisia%2Fwebsocket-xorg-docker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thanatisia%2Fwebsocket-xorg-docker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thanatisia%2Fwebsocket-xorg-docker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Thanatisia","download_url":"https://codeload.github.com/Thanatisia/websocket-xorg-docker/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Thanatisia%2Fwebsocket-xorg-docker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28694830,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T14:15:13.573Z","status":"ssl_error","status_checked_at":"2026-01-23T14:09:05.534Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T00:09:02.165Z","updated_at":"2026-01-23T15:43:08.850Z","avatar_url":"https://github.com/Thanatisia.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Running Xorg Virtual Framebuffer, VNC Server, Websocket server and Web/browser-based VNC client from Docker\n\n## Information\n### Summary\n```\nBase VNC + WebSocket server docker image that aims to simplify the initial setup of a containerized Graphical environment\n```\n\n### Components\n- x11vnc : VNC server\n- websockify : WebSocket server\n- novnc : Web/Browser-based VNC client\n- Xorg : Display Server\n    - xauth : Xorg Authorization CLI utility\n    - Xvfb : Xorg Virtual Framebuffer; Used to create a virtual framebuffer in the memory to allow you to draw/render graphical applications in a virtual environment within the background as a process\n\n### Operational Flow\n- Image Build\n    - Setup\n        - Installs dependencies\n        - Creates a brand new Xauthority cookie file in the HOME directory (default = root, /root)\n        - Adds a randomly-generated number using the MAGIC-COOKIE-1 algorithm used by xauth into the xauth database\n    - Entry Point\n        - Set the DISPLAY environment variable that provides the virtual monitor display to be used by the DISPLAY server\n        - Startup Virtual Framebuffer environment pointing to the 'DISPLAY' monitor number environment variable\n        - Startup VNC server pointing to the Virtual Framebuffer environment variable and options\n        - Startup Websocket server mapping the Websocket server's listening port to the VNC server's host address and port number\n\n## Setup\n### Dependencies\n+ docker\n+ docker-compose\n+ git\n\n### Pre-Requisites\n- Select your base image distribution of choice\n    + alpine\n    + debian\n    + nix\n- Select your base image\n    - x11vnc (Recommended)\n    - tigervncserver (aka xtigervnc)\n- (Optional) Change permissions of script (if any)\n    ```bash\n    chmod -R u+x scripts/[base-image-distribution]/\n    ```\n\n### Build\n- Build (Base) Docker image\n    ```bash\n    docker build \\\n        -t thanatisia/websocket-x:latest \\\n        --build-arg VNC_SERVER_PASS=[VNC-server-password] \\\n        --build-arg \"FRAMEBUFFER_SCREEN_SPECS=-screen 0 1920x1080x16\" \\\n        -f docker/Dockerfiles/[distribution-name]/base/[vnc-server].Dockerfile \\\n        .\n    ```\n\n- (Optional) Build multi-stage examples\n    - Notes\n        + This is just an example, substitute this with your multi-stage Dockerfiles\n        + In this example, I will be using the 'docker/Dockerfiles/[distribution-name]/stage-2/examples/bspwm.Dockerfile' dockerfile\n    ```bash\n    docker build \\\n        -t thanatisia/websocket-x:latest \\\n        -f docker/Dockerfiles/[distribution-name]/stage-2/examples/bspwm.Dockerfile \\\n        .\n    ```\n\n### Startup\n- Startup Docker container\n    - Explanation\n        + `-e SHELL=${SHELL}`          : Default shell environment variable\n        + `-p 5900:5900`               : Websocket server port\n        + `-p 6080:6080`               : VNC server port\n        + `-v \"/dev/shm:/dev/shm\"`     : Mount the shm device driver\n        + `-v \"/run/dbus:/run/dbus\"`   : Mount the host system's device buses\n        + `--device /dev/snd:/dev/snd` : Passthrough the host system soundcard\n    ```bash\n    docker run -itd \\\n        --name=browser-x \\\n        --restart=unless-stopped \\\n        -e SHELL=${SHELL} \\\n        -p 5900:5900 \\\n        -p 6080:6080 \\\n        -v \"/dev/shm:/dev/shm\" \\\n        -v \"/run/dbus:/run/dbus\" \\\n        --device /dev/snd:/dev/snd \\\n        thanatisia/websocket-x:latest\n    ```\n\n### Teardown\n- Stop container\n    ```console\n    docker stop browser-x\n    ```\n\n- Remove container\n    ```console\n    docker rm browser-x\n    ```\n\n### Run all\n- Using make script\n    ```console\n    ./make.sh\n    ```\n\n- Command Line\n    ```bash\n    docker build -t thanatisia/websocket-x:latest --build-arg VNC_SERVER_PASS=[VNC-server-password] -f Dockerfile . \u0026\u0026 \\\n        docker stop browser-x \u0026\u0026 docker rm browser-x; \\\n        docker run -itd \\\n            --name=browser-x \\\n            -p 6080:6080 \\\n            -p 5900:5900 \\\n            thanatisia/websocket-x:latest\n    ```\n\n### Container use\n- Enter container TTY\n    ```console\n    docker exec -it browser-x /bin/bash\n    ```\n\n### Implementation\n- To use as a base image\n    + Build the image\n    - Include the following \n        - in your Dockerfile\n            ```\n            FROM thanatisia/websocket-x:latest AS new-image\n            ```\n        - in your docker-compose\n            ```yaml\n            image: thanatisia/websocket-x:latest\n            ```\n    - Multi-stage Build Example \n        - Dockerfiles\n            - Embedding as a reference (in stage-2.Dockerfile)\n                ```\n                FROM thanatisia/websocket-x:latest AS test-container\n\n                ## Copy files\n                COPY ./test.sh /tmp/test.sh\n\n                ## Run on startup\n                RUN /bin/bash -c \"/tmp/test.sh\"\n                ```\n            - Building using 'docker build'\n                ```bash\n                # Build Stage 1 image\n                docker build \\\n                    --tag thanatisia/websocket-x:latest \\\n                    --build-arg VNC_SERVER_PASS=[VNC-server-password] \\\n                    --build-arg \"FRAMEBUFFER_SCREEN_SPECS=-screen 0 1920x1080x16\" \\\n                    -f docker/Dockerfiles/[distribution-name]/base/[vnc-server].Dockerfile \\\n                    [context]\n\n                # Build Stage 2 image\n                docker build --tag thanatisia/websocket-x:latest -f stage-2.Dockerfile [context]\n\n                ...\n\n                # Build Stage N image\n                docker build --tag thanatisia/websocket-x:latest -f stage-N.Dockerfile [context]\n                ```\n            - Starting up container\n                - Explanation\n                    + `-e SHELL=${SHELL}`          : Default shell environment variable\n                    + `-p 5900:5900`               : Websocket server port\n                    + `-p 6080:6080`               : VNC server port\n                    + `-v \"/dev/shm:/dev/shm\"`     : Mount the shm device driver\n                    + `-v \"/run/dbus:/run/dbus\"`   : Mount the host system's device buses\n                    + `--device /dev/snd:/dev/snd` : Passthrough the host system soundcard\n                ```bash\n                docker run -itd \\\n                    --name=[container-name] \\\n                    --restart=unless-stopped \\\n                    -e SHELL=${SHELL} \\\n                    -p 5900:5900 \\\n                    -p 6080:6080 \\\n                    -v \"/dev/shm:/dev/shm\" \\\n                    -v \"/run/dbus:/run/dbus\" \\\n                    --device /dev/snd:/dev/snd \\\n                    thanatisia/websocket-x:latest\n                ```\n        - docker-compose\n            - Explanation\n                - The service application 'websocket-x-stage-1' is Stage 1 of the Multi-stage Build \n                    + which will build the image 'thanatisia/websocket-x:latest' using the specified dockerfile (in this case - docker/Dockerfiles/[distribution-name]/base/[vnc-server].Dockerfile)\n                    + The focus of the Dockerfile recipe is on installing dependencies and establishing the ENTRY POINT\n                - The service application 'websocket-x-stage-2' is Stage 2 of the Multi-stage Build, as well as any other additional stages you require when importing this framework as an image recipe\n                    - For example\n                        + websocket-x-stage-2 could be for installing additional dependencies to be ran and started after the container is built and started up\n                - The service application 'browser-x' is your main application after every previous build stages have been completed\n                    - In this service, you do not need to use the 'build' key-value and instead, call for the image directly\n                - Important Options\n                    - `tty: true` : The 'tty' key-value in docker-compose is equivalent to the '-t' option/flag in 'docker run', which basically tells docker to keep the TTY/terminal enabled even after the command has ended\n            ```yaml\n            # Docker compose recipe for running both x11vnc and tigervncserver\n            version: \"3.7\"\n            services:\n                websocket-x-stage-1:\n                  image: thanatisia/websocket-x:latest\n                  build:\n                    context: .\n                    args:\n                      - \"VNC_SERVER_SPECS=[additional-vnc-server-specifications]\"\n                      - VNC_SERVER_PASS=[your-vnc-server-password]\n                      - \"FRAMEBUFFER_SCREEN_SPECS=-screen 0 1920x1080x16\"\n                    dockerfile: docker/Dockerfiles/debian/base/[vnc-server].Dockerfile\n\n                websocket-x-stage-2:\n                  image: thanatisia/websocket-x:latest\n                  build:\n                    context: .\n                    dockerfile: docker/Dockerfiles/debian/stage-2.Dockerfile\n\n                #### ...\n\n                websocket-x-stage-N:\n                  image: thanatisia/websocket-x:latest\n                  build:\n                    context: .\n                    dockerfile: docker/Dockerfiles/debian/stage-N.Dockerfile\n\n                browser-x:\n                  image: thanatisia/websocket-x:latest\n                  container_name:  browser-x\n                  restart: unless-stopped\n                  environment:\n                    ## Environment Variables\n                    - SHELL=${SHELL}\n                  tty: true\n                  ports:\n                    ## Port Forward/Translate/Map host system port to container port\n                    ## [ip-address]:[host-system-port]:[container-port]\n                    - 5900:5900 # VNC Server listening port\n                    - 6080:6080 # Websocket server listening port\n                  volumes:\n                    ## Mount volumes from host system to container\n                    ## [host-system-volume]:[container-volume]\n                    - /dev/shm:/dev/shm # SHM device\n                    - /run/dbus:/run/dbus # Device Buses\n                  devices:\n                    - /dev/snd:/dev/snd # Passthrough soundcard for audio output\n            ```\n\n## Documentations\n\n### Build-time Arguments (Local Variables)\n- To invoke and specify: `docker build --build-arg [ARGUMENT_VARIABLE]=[ARGUMENT_VALUE]`\n\n#### Arguments\n- FRAMEBUFFER_OPTS=\"[DISPLAY-monitor-number] -screen [monitor-number] [width]x[height]x[color-depth/bitrate]\" : Set the X Virtual Framebuffer (Xvfb) startup options\n    - Positionals\n        - DISPLAY : Specify the $DISPLAY monitor number environment variable (i.e. :0, :1)\n    - Options\n        - screen\n            + monitor-number : Specify the virtual monitor number to display the window; i.e. :0 = 0, :1 = 1\n        - resolution\n            + width : Specify the width (horizontal length) of the Virtual Framebuffer's canvas window (i.e. 1920)\n            + height : Specify the height (vertical height) of the Virtual Framebuffer's canvas window (i.e. 1080)\n            + color-depth/bitrate : Specify the color density of the Virtual Framebuffer's canvas window (i.e. 16-bit, 32-bit)\n+ VNC_SERVER_PASS : Set the VNC server's password to use (Optional; Set '-nopw' in VNC_SERVER_OPTS to not use passwords)\n- VNC_SERVER_OPTS=\"-display :0 -rfbport 5900 -usepw -passwd ${VNC_SERVER_PASS} -xkb -forever -shared\" : Set the VNC server's options to startup with\n    - Notes\n        - '-bg' is not used to ensure that the ENTRY POINT has a foreground application to keep the container running\n        - In the case where you would like to use '-bg', \n            + you can add 'bash' to the last application within the ENTRY POINT block\n\n### Run-time Arguments (Environment Variables)\n- To invoke and specify: `[ENVIRONMENT_VARIABLE]=[VALUE] docker build`\n\n#### Arguments \n- System\n    + `DISPLAY=:0` : DISPLAY virtual monitor number used for Graphical application rendering by the display server (Xorg/Wayland)\n- VNC Server\n    + `VNC_SERVER_HOST=127.0.0.1` : Set the VNC server's Hostname/IP address\n    + `VNC_SERVER_PORT=5900`      : Set the VNC server's listening port number\n    + `VNC_SERVER_PASS=[your-vnc-server-password]` : Set the VNC server's password\n- Websocket server\n    + `WEBSOCKET_CLIENT_PATH=/usr/share/novnc` : Set the Web/Browser-based VNC client you wish to access in the websocket server\n    + `WEBSOCKET_SERVER_PORT=6080` : Set the WebSocket server's listening port number; This is the port number you access to view the Web/Browser-based VNC/SPICE client\n\n### Dockerfiles\n- x11vnc.Dockerfile : Recommended\n    + Base Image: docker\n    + Display Server: Xorg\n    + VNC server: x11vnc\n    + Websocket server: websockify\n\n- xtigervnc.Dockerfile\n    + Base Image: docker\n    + Display Server: Xorg\n    + VNC server: Xtigervnc (Package: tigervnc-standalone-server; aka tigervncserver)\n    + Websocket server: websockify\n\n### Networking\n- Ports to expose\n    + 5900 : Default VNC server listening port\n    + 6080 : Default WebSocket server listening port\n\n## Makefile\n### Environment Variables\n#### Images\n+ IMAGE_NAME : Specify the name of the image to build\n+ IMAGE_TAG  : Specify the tag/version of the image\n- BUILD_ARGS : Set the build arguments to parse into the build process\n    - Defaults \n        + --build-arg \"VNC_SERVER_PASS=[your-vnc-server-password]\"\n\t\t+ --build-arg \"FRAMEBUFFER_SCREEN_SPECS=-screen 0 1920x1080x16\"\n+ STAGE_1_DOCKERFILE : Specify the Stage 1 (Base) Dockerfile to build the image with\n- CONTEXT : Specify the context (working directory)\n    - Defaults\n        + . (Current Working Directory)\n\n#### Containers\n+ CONTAINER_IMAGE_NAME : Specify the name of the image to startup the container with\n+ CONTAINER_IMAGE_TAG  : Specify the tag/version of the image to startup the container with\n+ CONTAINER_NAME : Specify the name of the container to startup\n- CONTAINER_OPTS : Specify the options to startup the container with\n    - Defaults \n        + --restart=unless-stopped\n- CONTAINER_PORT_FORWARDING : Specify the ports to forward/translate/map from host system to the container; Format each port entry with '-p [ip-address]:[host-system-port]:[container-port]' and separate each entry with a space delimiter\n    - Defaults \n        + -p 5901:5900\n\t\t+ -p 6080:6080\n- CONTAINER_MOUNT_VOLUMES : Specify the volumes to mount from host system to the container; Format each mount point entry with '-v [host-system-volume]:[container-volume]:[permission]' and separate each entry with a space delimiter\n    - Defaults \n        + -v \"/dev/shm:/dev/shm\"\n\t\t+ -v \"/run/dbus:/run/dbus\"\n- CONTAINER_PASSTHROUGH_DEVICE : Specify the devices to passthrough from the host system to the container; Format each device entry with '--device [host-system-device]:[container-mount-point]' and separate each entry with a space delimiter\n    - Defaults \n        + --device \"/dev/snd:/dev/snd\"\n\n### Targets\n+ build-stage-1: Build image from Dockerfile\n+ run: Startup a container from an image\n+ start: Start the container if stopped and exists\n+ stop: Stop the container if running\n+ restart: Restart the container if running\n+ remove: Remove the container if exists\n+ logs: Display logs of the container\n+ gif: Make/generate the demo animation gif for the software documentations using VHS (by charmbracelet)\n\n### Usage Snippets\n- Full run\n    - Explanation\n        - Parameters\n            + -k : Continue and keep going even if errors are encountered\n        - Targets\n            + stop : Stop the container\n            + remove : Remove the container\n            + build-stage-1 : Build the stage 1 image\n            + run : Startup a container using the image\n            + logs : Display logs after running\n    ```bash\n    make -k stop remove build-stage-1 run logs\n    ```\n\n- Parse customized optional values\n    ```bash\n    ENVIRONMENT_VARIABLE=\"new_value\" ... make -k [targets]\n    ```\n\n- Restart container manually\n    ```bash\n    make restart\n    ```\n\n- Build a new image\n    ```bash\n    make -k stop remove build-stage-1\n    ```\n\n- Build a new image and run\n    ```bash\n    make stop remove build-stage-1 run\n    ```\n\n- Generate a demo animation gif for software documentations using the docker image of the 'vhs' CLI utility by charmbracelet\n    ```bash\n    make gif\n    ```\n\n### Customization\n- To change the base image support\n    - Notes\n        - The following is assuming that\n            1. You are using the repository in its current structure, you can change it according to your needs by following the structure/format\n            2. You are using the same naming (i.e. container name or image name), take note of your custom image/container names if you are changing it\n    - Open the Makefile\n        ```bash\n        $EDITOR Makefile\n        ```\n    - Edit the following\n        + IMAGE_TAG : Set this to the base image you wish to use\n        + CONTAINER_IMAGE_TAG : Same as 'IMAGE_TAG'\n        + STAGE_1_DOCKERFILE : Specifically change the base image directory name in 'docker/Dockerfiles/[base-image-directory]'\n\n## Wiki\n\n### Repository structure\n#### Folders\n- root/ : Project root directory\n    - docker/ : Contains all docker contents\n        - Dockerfiles/ : Contains all Dockerfile recipes\n            - debian/ : Contains debian-based base images for the websocket + VNC server project; You can use these as references and build your own\n            - stage-2/ : Contains all Stage-2 (aka Post-Installation) Dockerfiles that you use to build on top of the base images (in a multi-staged build); You can use these as references and build your own\n                - examples/ : This is the example directory containing example Dockerfiles for the multi-stage builds\n    - scripts/ : Place all your launcher/runner helper scripts that will be executed in the containers here\n        - alpine/ : Place all alpine-based helper scripts here\n        - debian/ : Place all debian-based helper scripts here\n        - nix/ : Place all nix-based helper scripts here\n        - '*' : All other remainder scripts\n\n#### Files\n- docker/Dockerfiles/[distribution-name]/base/\n    + x11vnc.Dockerfile : Stage-1 dockerfile that builds up a (Websocket Server + VNC Server + Xorg(11) headless backend via Xvfb) stack using (websockify + x11vnc + Xvfb)\n\n- docker/Dockerfiles/[distribution-name]/stage-2/examples/\n    + bspwm.Dockerfile : Stage-2 example dockerfile that installs and starts up BSPWM and SXHKD \n\n## Resources\n\n## References\n\n## Remarks\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthanatisia%2Fwebsocket-xorg-docker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthanatisia%2Fwebsocket-xorg-docker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthanatisia%2Fwebsocket-xorg-docker/lists"}