Skip to content

Commit

Permalink
Merge pull request #15 from vajonam/feature/virtualgl-support
Browse files Browse the repository at this point in the history
Add virutalgl for hardware acceleration.
  • Loading branch information
helfrichmichael authored May 17, 2024
2 parents 787aec2 + 8580dfc commit 9c6cddc
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 90 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
* text eol=lf
80 changes: 44 additions & 36 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
# Get and install Easy noVNC.
FROM golang:1.14-buster AS easy-novnc-build
WORKDIR /src
RUN go mod init build && \
go get github.com/geek1011/[email protected] && \
go build -o /bin/easy-novnc github.com/geek1011/easy-novnc
# ORIGINAL REPO https://github.com/damanikjosh/virtualgl-turbovnc-docker/blob/main/Dockerfile
ARG UBUNTU_VERSION=22.04

# Get TigerVNC and Supervisor for isolating the container.
FROM debian:buster
RUN apt-get update -y && \
apt-get install -y --no-install-recommends openbox tigervnc-standalone-server supervisor gosu && \
rm -rf /var/lib/apt/lists && \
mkdir -p /usr/share/desktop-directories
FROM nvidia/opengl:1.2-glvnd-runtime-ubuntu${UBUNTU_VERSION}
LABEL authors="vajonam, Michael Helfrich - helfrichmichael"

# Get all of the remaining dependencies for the OS, VNC, and Prusaslicer.
RUN apt-get update -y && \
apt-get install -y --no-install-recommends lxterminal nano wget openssh-client rsync ca-certificates xdg-utils htop tar xzip gzip bzip2 zip unzip && \
rm -rf /var/lib/apt/lists
ARG VIRTUALGL_VERSION=3.1.1-20240228
ARG TURBOVNC_VERSION=3.1.1-20240127
ENV DEBIAN_FRONTEND noninteractive

RUN apt update && apt install -y --no-install-recommends --allow-unauthenticated \
lxde gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \
freeglut3 libgtk2.0-dev libwxgtk3.0-gtk3-dev libwx-perl libxmu-dev libgl1-mesa-glx libgl1-mesa-dri \
xdg-utils locales locales-all pcmanfm jq curl git firefox-esr \
RUN
# Install some basic dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
wget xorg xauth gosu supervisor x11-xserver-utils libegl1-mesa libgl1-mesa-glx \
locales-all libpam0g libxt6 libxext6 dbus-x11 xauth x11-xkb-utils xkb-data python3 xterm novnc \
lxde gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \
freeglut3 libgtk2.0-dev libwxgtk3.0-gtk3-dev libwx-perl libxmu-dev libgl1-mesa-glx libgl1-mesa-dri \
xdg-utils locales locales-all pcmanfm jq curl git bzip2 gpg-agent software-properties-common \
&& mkdir -p /usr/share/desktop-directories \
# Install Firefox without Snap.
&& add-apt-repository ppa:mozillateam/ppa \
&& apt update \
&& apt install -y firefox-esr --no-install-recommends \
# Clean everything up.
&& apt autoclean -y \
&& apt autoremove -y \
&& rm -rf /var/lib/apt/lists/*

# Install Prusaslicer
# Many of the commands below were derived and pulled from previous work by dmagyar on GitHub.
# Here's their Dockerfile for reference https://github.com/dmagyar/prusaslicer-vnc-docker/blob/main/Dockerfile.amd64
# Install virtualgl and turbovnc
RUN wget -qO /tmp/virtualgl_${VIRTUALGL_VERSION}_amd64.deb https://packagecloud.io/dcommander/virtualgl/packages/any/any/virtualgl_${VIRTUALGL_VERSION}_amd64.deb/download.deb?distro_version_id=35\
&& wget -qO /tmp/turbovnc_${TURBOVNC_VERSION}_amd64.deb https://packagecloud.io/dcommander/turbovnc/packages/any/any/turbovnc_${TURBOVNC_VERSION}_amd64.deb/download.deb?distro_version_id=35 \
&& dpkg -i /tmp/virtualgl_${VIRTUALGL_VERSION}_amd64.deb \
&& dpkg -i /tmp/turbovnc_${TURBOVNC_VERSION}_amd64.deb \
&& rm -rf /tmp/*.deb

# Install prusaslicer
WORKDIR /slic3r
ADD get_latest_prusaslicer_release.sh /slic3r

RUN chmod +x /slic3r/get_latest_prusaslicer_release.sh \
&& latestSlic3r=$(/slic3r/get_latest_prusaslicer_release.sh url) \
&& slic3rReleaseName=$(/slic3r/get_latest_prusaslicer_release.sh name) \
Expand All @@ -52,23 +57,26 @@ RUN chmod +x /slic3r/get_latest_prusaslicer_release.sh \
&& mkdir -p /configs/.config/ \
&& ln -s /configs/.config/ /home/slic3r/ \
&& mkdir -p /home/slic3r/.config/ \
# We can now set the Download directory for Firefox and other browsers.
# We can also add /prints/ to the file explorer bookmarks for easy access.
&& echo "XDG_DOWNLOAD_DIR=\"/prints/\"" >> /home/slic3r/.config/user-dirs.dirs \
&& echo "file:///prints prints" >> /home/slic3r/.gtk-bookmarks
&& echo "file:///prints prints" >> /home/slic3r/.gtk-bookmarks

# Generate key for novnc and cleanup erros
RUN openssl req -x509 -nodes -newkey rsa:2048 -keyout /etc/novnc.pem -out /etc/novnc.pem -days 365 -subj "/C=US/ST=Denial/L=Springfield/O=Dis/CN=localhost" \
&& rm /etc/xdg/autostart/lxpolkit.desktop \
&& mv /usr/bin/lxpolkit /usr/bin/lxpolkit.ORIG

ENV PATH ${PATH}:/opt/VirtualGL/bin:/opt/TurboVNC/bin

COPY --from=easy-novnc-build /bin/easy-novnc /usr/local/bin/
COPY menu.xml /etc/xdg/openbox/
COPY supervisord.conf /etc/
ADD entrypoint.sh /entrypoint.sh
ADD supervisord.conf /etc/

# HTTP Port
EXPOSE 8080
# Add a default file to resize, etc for noVNC.
ADD vncresize.html /usr/share/novnc/index.html

# VNC Port
EXPOSE 5900
#Set firefox to run with hardware accel as if enabled.
RUN sed -i 's|exec $MOZ_LIBDIR/$MOZ_APP_NAME "$@"|if [ -n "$ENABLEHWGPU" ] \&\& [ "$ENABLEHWGPU" = "true" ]; then\n exec /usr/bin/vglrun $MOZ_LIBDIR/$MOZ_APP_NAME "$@"\nelse\n exec $MOZ_LIBDIR/$MOZ_APP_NAME "$@"\nfi|g' /usr/bin/firefox-esr

VOLUME /configs/
VOLUME /prints/

# It's time! Let's get to work! We use /configs/ as a bindable volume for Prusaslicers configurations. We use /prints/ to provide a location for STLs and GCODE files.
CMD ["bash", "-c", "chown -R slic3r:slic3r /home/slic3r/ /configs/ /prints/ /dev/stdout && exec gosu slic3r supervisord"]
ENTRYPOINT ["/entrypoint.sh"]
48 changes: 46 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,64 @@ To build a new image, clone this repository and run `docker compose up -f docker

### Using a VNC Viewer

To use a VNC viewer with the container, the default port for X TigerVNC is 5900. You can add this port by adding `-p 5900:5900` to your command to start the container to open this port for access.
To use a VNC viewer with the container, the default port for TurobVNC is 5900. You can add this port by adding `-p 5900:5900` to your command to start the container to open this port for access. See note below about ports related to `VNC_PORT` environment variable.


### GPU Acceleration/Passthrough

Like other Docker containers, you can pass your Nvidia GPU into the container using the `NVIDIA_VISIBLE_DEVICES` and `NVIDIA_DRIVER_CAPABILITIES` envs. You can define these using the value of `all` or by providing more narrow and specific values. This has only been tested on Nvidia GPUs.

In unraid you can set these values during set up. For containers outside of unraid, you can set this by adding the following params or similar `-e NVIDIA_DRIVER_CAPABILITIES="all" NVIDIA_VISIBLE_DEVICES="all"`. If using Docker Compose, uncomment the enviroment variables in the relevant docker-compose.yaml file.
In unraid you can set these values during set up. For containers outside of unraid, you can set this by adding the following params or similar `-e NVIDIA_DRIVER_CAPABILITIES="all" NVIDIA_VISIBLE_DEVICES="all"`. If using Docker Compose, uncomment the enviroment variables in the relevant docker-compose.yaml file.

In addition to the information above, to enable **Hardware 3D acceleration** (which helps with visualizing complex models and sliced layers), you must set an environment variable. You can do this by either adding `-e ENABLEHWGPU=true` to the `docker run` command or including `- ENABLEHWGPU=true` in your Docker Compose configuration.

Once enabled and started you can verify the GPU is being used by running `nvidia-smi -l` on the HOST machine and you should see `/slic3r/slic3r-dist/bin/prusa-slicer` as process using the GPU.

```
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.161.07 Driver Version: 535.161.07 CUDA Version: 12.2 |
|-----------------------------------------+----------------------+----------------------+
.. removed for brevity ..
+---------------------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=======================================================================================|
| 0 N/A N/A 4129827 G /slic3r/slic3r-dist/bin/prusa-slicer 262MiB |
+---------------------------------------------------------------------------------------+
*some information above was edited for privacy
```

The `GL Version` on the System Information screen inside the slicer should also show, the GPU model and driver version

<img src="https://github.com/vajonam/prusaslicer-novnc/assets/152501/250c93f5-e550-42f9-8cce-b942c93ef61e" width="300" />



### Other Environment Variables

Below are the default values for various environment variables:

- `DISPLAY=:0`: Sets the DISPLAY variable (usually left as 0).
- `SUPD_LOGLEVEL=INFO`: Specifies the log level for supervisord. Set to `TRACE` to see output for various commands helps if you are debugging something. See superviosrd manual for possible levels.
- `ENABLEHWGPU=`: Enables HW 3D acceleration. Default is `false` to maintain backward compatability.
- `VGL_DISPLAY=egl`: Advanced setting to target specific cards if you have multiple GPUs
- `NOVNC_PORT=8080`: Sets the port for the noVNC HTML5/web interface.
- `VNC_RESOLUTION=1280x800`: Defines the resolution of the VNC server.
- `VNC_PASSWORD=`: Defaults to no VNC password, but you can add one here.
- `VNC_PORT=5900`: Defines the port for the VNC server, allowing direct connections using a VNC client. Note that the `DISPLAY` number is added to the port number (e.g., if your display is :1, the VNC port accepting connections will be `5901`).

## Links

[Prusaslicer](https://www.prusa3d.com/prusaslicer/)

[TruboVNC](https://www.turbovnc.org/)

[VirtualGL](https://virtualgl.org/)

[Supervisor](http://supervisord.org/)

[GitHub Source](https://github.com/helfrichmichael/prusaslicer-novnc)
Expand Down
13 changes: 8 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ services:
image: mikeah/prusaslicer-novnc
container_name: prusaslicer-novnc
environment:
- SSL_CERT_FILE="/etc/ssl/certs/ca-certificates.crt"
#- NVIDIA_DRIVER_CAPABILITIES="all"
#- NVIDIA_VISIBLE_DEVICES="all"
- SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
- NVIDIA_VISIBLE_DEVICES=0
- NVIDIA_DRIVER_CAPABILITIES=all
- DISPLAY=:0
- VGL_DISPLAY=egl # needed to run without X server
- SUPD_LOGLEVEL=INFO
- ENABLEHWGPU=true
- VNC_RESOLUTION=1920x1080
volumes:
- ./prints:/prints/
- ./data:/configs/
ports:
- 8080:8080
restart: unless-stopped
29 changes: 29 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash
set -e
rm -f /tmp/.X*-lock
rm -f /tmp/.X11-unix/X*
export DISPLAY=${DISPLAY:-:0}
DISPLAY_NUMBER=$(echo $DISPLAY | cut -d: -f2)
export NOVNC_PORT=${NOVNC_PORT:-8080}
export VNC_PORT=${VNC_PORT:-5900}
export VNC_RESOLUTION=${VNC_RESOLUTION:-1280x800}
if [ -n "$VNC_PASSWORD" ]; then
mkdir -p /root/.vnc
echo "$VNC_PASSWORD" | vncpasswd -f > /root/.vnc/passwd
chmod 0600 /root/.vnc/passwd
export VNC_SEC=
else
export VNC_SEC="-securitytypes TLSNone,X509None,None"
fi
export LOCALFBPORT=$((${VNC_PORT} + DISPLAY_NUMBER))
if [ -n "$ENABLEHWGPU" ] && [ "$ENABLEHWGPU" = "true" ]; then
export VGLRUN="/usr/bin/vglrun"
else
export VGLRUN=
fi

export SUPD_LOGLEVEL="${SUPD_LOGLEVEL:-TRACE}"
export VGL_DISPLAY="${VGL_DISPLAY:-egl}"

# fix perms and launch supervisor with the above environment variables
chown -R slic3r:slic3r /home/slic3r/ /configs/ /prints/ /dev/stdout && exec gosu slic3r supervisord -e $SUPD_LOGLEVEL
4 changes: 2 additions & 2 deletions get_latest_prusaslicer_release.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ TMPDIR="$(mktemp -d)"

curl -SsL https://api.github.com/repos/prusa3d/PrusaSlicer/releases/latest > $TMPDIR/latest.json

url=$(jq -r '.assets[] | select(.browser_download_url|test("linux-x64-(?!GTK3).+.tar.bz2$"))| .browser_download_url' $TMPDIR/latest.json)
name=$(jq -r '.assets[] | select(.browser_download_url|test("linux-x64-(?!GTK3).+.tar.bz2$"))| .name' $TMPDIR/latest.json)
url=$(jq -r '.assets[] | select(.browser_download_url|test("linux-x64-(?!GTK2).+.tar.bz2$"))| .browser_download_url' $TMPDIR/latest.json)
name=$(jq -r '.assets[] | select(.browser_download_url|test("linux-x64-(?!GTK2).+.tar.bz2$"))| .name' $TMPDIR/latest.json)
version=$(jq -r .tag_name $TMPDIR/latest.json)

if [ $# -ne 1 ]; then
Expand Down
30 changes: 0 additions & 30 deletions menu.xml

This file was deleted.

21 changes: 7 additions & 14 deletions supervisord.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,21 @@
nodaemon=true
pidfile=/tmp/supervisord.pid

[program:x11]
[program:vnc]
priority=0
command=/usr/bin/Xtigervnc -desktop "Prusaslicer" -rfbport 5900 -SecurityTypes None -AlwaysShared -AcceptKeyEvents -AcceptPointerEvents -AcceptSetDesktopSize -SendCutText -AcceptCutText :0
command=/opt/TurboVNC/bin/vncserver %(ENV_DISPLAY)s -fg %(ENV_VNC_SEC)s -depth 24 -geometry %(ENV_VNC_RESOLUTION)s
autorestart=true
redirect_stderr=true

[program:easy-novnc]
[program:novnc]
priority=0
command=/usr/local/bin/easy-novnc --addr :8080 --host localhost --port 5900 --no-url-password --novnc-params "resize=remote"
autorestart=true
redirect_stderr=true

[program:openbox]
priority=1
command=/usr/bin/openbox
environment=DISPLAY=:0
command=websockify --web=/usr/share/novnc/ %(ENV_NOVNC_PORT)s localhost:%(ENV_LOCALFBPORT)s
autorestart=true
redirect_stderr=true

[program:prusaslicer]
priority=1
environment=DISPLAY=:0
command=/bin/bash -c '/slic3r/slic3r-dist/prusa-slicer --datadir /configs/.config/PrusaSlicer/'
environment=VGL_DISPLAY=%(ENV_VGL_DISPLAY)s
command=/bin/bash -c '%(ENV_VGLRUN)s /slic3r/slic3r-dist/prusa-slicer --datadir /configs/.config/PrusaSlicer/'
autorestart=true
redirect_stderr=true
redirect_stderr=true
7 changes: 7 additions & 0 deletions vncresize.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<head>
<script>
window.location.replace("./vnc.html?autoconnect=true&resize=remote&reconnect=true&show_dot=true");
</script>
</head>
</html>

0 comments on commit 9c6cddc

Please sign in to comment.