DEV Community

Cover image for Running Firefox in Docker? Yes, with a GUI and noVNC!
Daniel Pepuho
Daniel Pepuho

Posted on • Originally published at danielcristho.site

Running Firefox in Docker? Yes, with a GUI and noVNC!

Docker isn’t just for serve your code, appliactions. you can actually run a full desktop app inside it. In this project, I containerized Firefox with a virtual desktop and made it accessible through a browser using noVNC.

noVNC Docker meme

What this project does?

It creates a lightweight container that:

- Runs a minimal desktop environment (Fluxbox)
- Launches Firefox
- Serves a VNC display using x11vnc
- Exposes that desktop through noVNC (so you can open it in your web browser)

You can literally open Firefox running inside Docker, from your browser tab.
All using a single docker compose up.

How it works?

Here’s a quick breakdown of what happens inside the container:

Breakddown

Everything runs headlessly, there’s no physical display, but the combo of Xvfb + Fluxbox gives Firefox a virtual desktop.

🐋 Dockerfile Overview

FROM alpine:edge

RUN apk add --no-cache \
    faenza-icon-theme \
    firefox \
    fluxbox \
    xfce4 \
    xvfb \
    x11vnc \
    novnc \
    supervisor \
    bash \
    net-tools

# Install noVNC & websockify from source code
RUN apk add --no-cache git python3 py3-pip \
    && rm -rf /usr/share/novnc \
    && git clone https://github.com/novnc/noVNC.git /usr/share/novnc \
    && git clone https://github.com/novnc/websockify.git /usr/share/novnc/utils/websockify \
    && ln -sf /usr/share/novnc/vnc.html /usr/share/novnc/index.html

ENV DISPLAY=:1
ENV RESOLUTION=1920x1080x24

# Set vnc password
ARG VNC_PASS=dummypass

# Create vnc password file
RUN mkdir -p /root/.vnc && \
    x11vnc -storepasswd "$VNC_PASS" /root/.vnc/passwd

COPY supervisord.conf /etc/supervisord.conf

EXPOSE 5900 6080

CMD ["supervisord", "-c", "/etc/supervisord.conf", "-n"]
Enter fullscreen mode Exit fullscreen mode

📦 Docker Compose Setup

version: '3.8'
services:
  vnc_firefox:
    build: .
    container_name: vnc_firefox
    ports:
      - "5901:5900" # VNC
      - "6080:6080" # noVNC web UI
     healthcheck:
      test: ["CMD-SHELL", "netstat -tln | grep -q 6080 || exit 1"]
      interval: 1m30s
      timeout: 30s
      retries: 5
      start_period: 30s
Enter fullscreen mode Exit fullscreen mode

Under the Hood (process supervision)

Supervisor meme

Everything is managed by supervisord, which runs:

Xvfb - virtual framebuffer display

x11vnc - provides VNC access

fluxbox - lightweight window manager (WM)

firefox - your GUI browser

novnc_proxy - web socket bridge

Example supervisord.conf:

# Supervisor main config
[supervisord]
nodaemon=true
logfile=/var/log/supervisord.log
pidfile=/var/run/supervisord.pid
childlogdir=/var/log

# XVirtual Framebuffer (Xvfb)
# Creates a virtual display environment (:1)
[program:xvfb]
command=/usr/bin/Xvfb :1 -screen 0 1920x1080x24
autostart=true
autorestart=true
priority=10

# x11vnc, VNC server
[program:x11vnc]
command=/usr/bin/x11vnc -display :1 -rfbauth /root/.vnc/passwd -forever -shared -rfbport 5900
autostart=true
autorestart=true
priority=20

# fluxbox, lightweight window manager
[program:fluxbox]
command=/usr/bin/fluxbox
environment=DISPLAY=":1"
autostart=true
autorestart=true
priority=30

# Runs firefox inside the Xvfb + Fluxbox environment
[program:firefox]
command=/usr/bin/firefox
environment=DISPLAY=":1"
autostart=true
autorestart=true
priority=40

# noVNC, WebSocket VNC Proxy
# Bridges VNC (port 5900) to a web interface (port 6080)
[program:novnc]
command=/usr/share/novnc/utils/novnc_proxy --vnc localhost:5900 --listen 6080
autostart=true
autorestart=true
priority=50
Enter fullscreen mode Exit fullscreen mode

Our project structure should look likes this:

.
├── docker-compose.yml
├── Dockerfile
└── supervisord.conf
Enter fullscreen mode Exit fullscreen mode

How to Run It?

1. Build & start the container:

$ docker compose up --build -d
Enter fullscreen mode Exit fullscreen mode

Docker compose up

2 Access it by using your browser or VNC client. Using dummypass as password:

- Using noVNC Web: http://localhost:6080

noVNC Access

- Open any VNC viewer (e.g., RealVNC, TigerVNC, Remmina), then connect to: localhost:5901

VNC viewwer

What’s Next?

While this is mostly a fun experiment, it can be used for:

- Headless browser testing environments

- Remote browsing (isolated Firefox)

- Demonstrating GUI automation setups

NB: 😎 This post is part of my “Container Stuffs” open-source project on GitHub. Upcoming labs include:

- PostgreSQL master–replica setup

- Redis Sentinel cluster

- Multi-node Docker Swarm simulations

- and more to come!

Container Stuff

danielcristho/container-stuffs

Conclusion

Docker is more than backend services you can literally containerize entire user experiences.

Projects like this prove that containers aren’t limited to APIs, databases, and background workers. With a bit of creativity, you can run full desktops, interactive UIs, browsers, automation toolchains, and even full development environments inside isolated, reproducible containers.

Running Firefox inside Docker with noVNC shows how:

- system-level components (Xvfb, window managers, VNC)

- web technologies (WebSockets, noVNC)

- and container orchestration (Docker + Compose) can blend together to create something both useful and fun.

Cheers, feel free to give me a feedback, and happy containerizing! 🐳

Top comments (0)