Compare commits

...

2 Commits

Author SHA1 Message Date
b7ce160dc3 Allow setting username and id 2024-12-15 21:31:19 +01:00
9b2556f49a More different base builds 2024-12-15 17:22:52 +01:00
11 changed files with 224 additions and 71 deletions

View File

@ -1,13 +1,23 @@
# NOVNC-BASE # NOVNC-BASE
A desktop environment with sound in docker A desktop environment with sound in docker.
Can be used as a base file for application specific containers. Can be used as a base file for application specific containers.
- `thomasloven/novnc-ubuntu`
- `thomasloven/novnc-debuan`
- `thomasloven/novnc-alpine`
To just get a desktop environment at `http://localhost:8080`:
```bash
docker run --rm -p 8080:8080 thomasloven/novnc-ubuntu
```
Or used as a base for specific applications:
E.g:
```dockerfile ```dockerfile
FROM thomasloven/novnc-base FROM thomasloven/novnc-ubuntu
RUN sudo apt-get update \ RUN sudo apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
@ -16,6 +26,12 @@ RUN sudo apt-get update \
CMD ["blender"] CMD ["blender"]
``` ```
See more examples in `apps/`.
The container will run as user `$USERNAME` (default `novnc`) with uid `${UUID}` (default `1000`) and group id `${GUID}` (default `1000`).
The user has sudo privileges with no password(!).
### Bonus functionality - dotfiles installation. ### Bonus functionality - dotfiles installation.
If the environment variable `DOTFILES_REPO` is set, the container will `git If the environment variable `DOTFILES_REPO` is set, the container will `git
clone` that into `~/dotfiles` and then run `~/dotfiles/install.sh` if it clone` that into `~/dotfiles` and then run `~/dotfiles/install.sh` if it

61
alpine.Dockerfile Normal file
View File

@ -0,0 +1,61 @@
FROM alpine
RUN apk update \
&& apk add \
# Some basic helpers \
bash \
sudo \
git \
procps \
\
# X11 and XFCE \
&& apk add \
xvfb xauth dbus-x11 xfce4 xfce4-terminal \
\
# VNC \
&& apk add \
python3 py3-numpy \
tigervnc \
openssl \
\
# NoVNC \
&& mkdir -p /opt/noVNC \
&& git clone --single-branch https://github.com/novnc/noVNC.git /opt/noVNC \
&& git clone --single-branch https://github.com/novnc/websockify.git /opt/noVNC/utils/websockify \
&& ln -s /opt/noVNC/vnc.html /opt/noVNC/index.html \
&& openssl req -batch -new -x509 -days 365 -nodes -out self.pem -keyout /opt/noVNC/utils/websockify/self.pem \
# Audio requirements \
&& apk add \
pulseaudio \
pavucontrol \
ucspi-tcp6 \
gstreamer \
gstreamer-tools \
gst-plugins-good \
xfce4-pulseaudio-plugin
COPY pulse/ /etc/pulse
COPY novnc /opt/noVNC/
RUN sed -i "/import RFB/a \
import '../webaudio.js'" \
/opt/noVNC/app/ui.js
# Base applications
RUN apk update \
&& apk add \
firefox-esr neovim
COPY entrypoint.sh /opt/noVNC/entrypoint.sh
ENTRYPOINT ["/opt/noVNC/entrypoint.sh"]
EXPOSE 8080
# Add a custom version of vncserver which discards all arguments but the display
RUN mv /usr/bin/vncserver /usr/bin/vncserver-orig \
&& echo -e "#!/bin/bash \n \
/usr/bin/vncserver-orig \$1" > /usr/bin/vncserver \
&& chmod +x /usr/bin/vncserver
RUN mkdir -p /etc/skel/.vnc/ \
&& echo -e "-Securitytypes=none" > /etc/skel/.vnc/config \
&& touch /etc/skel/.vnc/passwd && chmod 0600 /etc/skel/.vnc/passwd

View File

@ -1,4 +1,4 @@
FROM thomasloven/novnc-base FROM thomasloven/novnc-ubuntu
RUN sudo apt-get update \ RUN sudo apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \

View File

@ -1,4 +1,4 @@
FROM thomasloven/novnc-base FROM thomasloven/novnc-ubuntu
RUN sudo apt-get update \ RUN sudo apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \

View File

@ -1,4 +1,4 @@
FROM thomasloven/novnc-base FROM thomasloven/novnc-ubuntu
RUN sudo apt-get update \ RUN sudo apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \

View File

@ -1,12 +1,12 @@
FROM thomasloven/novnc-base FROM thomasloven/novnc-ubuntu
ARG APPIMAGE=PrusaSlicer-2.8.1+linux-x64-older-distros-GTK3-202409181354.AppImage ARG APPIMAGE=PrusaSlicer-2.8.1+linux-x64-newer-distros-GTK3-202409181416.AppImage
ARG URL=https://github.com/prusa3d/PrusaSlicer/releases/download/version_2.8.1/${APPIMAGE} ARG URL=https://github.com/prusa3d/PrusaSlicer/releases/download/version_2.8.1/${APPIMAGE}
RUN sudo apt-get update \ RUN sudo apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
sudo apt-get install -y \ sudo apt-get install -y \
libgtk-3-dev libglu1-mesa libwebkit2gtk-4.0-37 \ libgtk-3-dev libglu1-mesa libwebkit2gtk-4.1-0 \
locales curl \ locales curl \
&& sudo locale-gen en \ && sudo locale-gen en \
&& curl -sSL ${URL} > ${APPIMAGE} \ && curl -sSL ${URL} > ${APPIMAGE} \

3
build.sh Executable file
View File

@ -0,0 +1,3 @@
docker build $@ -t thomasloven/novnc-ubuntu -f ubuntu.Dockerfile .
docker build $@ -t thomasloven/novnc-debian -f debian.Dockerfile .
docker build $@ -t thomasloven/novnc-alpine -f alpine.Dockerfile .

59
debian.Dockerfile Normal file
View File

@ -0,0 +1,59 @@
FROM debian
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\
# Some basic helpers \
bash \
sudo \
git \
ca-certificates \
procps \
\
# X11 and XFCE \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\
xvfb xauth dbus-x11 xfce4 xfce4-terminal \
x11-xserver-utils \
\
# VNC \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\
python3 python3-numpy \
tigervnc-standalone-server tigervnc-common \
openssl \
\
# NoVNC \
&& mkdir -p /opt/noVNC \
&& git clone --single-branch https://github.com/novnc/noVNC.git /opt/noVNC \
&& git clone --single-branch https://github.com/novnc/websockify.git /opt/noVNC/utils/websockify \
&& ln -s /opt/noVNC/vnc.html /opt/noVNC/index.html \
&& openssl req -batch -new -x509 -days 365 -nodes -out self.pem -keyout /opt/noVNC/utils/websockify/self.pem \
\
# Audio requirements \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\
pulseaudio \
pavucontrol \
ucspi-tcp \
gstreamer1.0-plugins-good \
gstreamer1.0-pulseaudio \
gstreamer1.0-tools
COPY pulse/ /etc/pulse
COPY novnc /opt/noVNC/
RUN sed -i "/import RFB/a \
import '../webaudio.js'" \
/opt/noVNC/app/ui.js
# Base applications
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\
firefox-esr neovim
COPY entrypoint.sh /opt/noVNC/entrypoint.sh
ENTRYPOINT ["/opt/noVNC/entrypoint.sh"]
EXPOSE 8080

View File

@ -1,5 +1,6 @@
#! /bin/bash #! /bin/bash
shopt -s nullglob shopt -s nullglob
kill_pid() { kill_pid() {
@ -16,42 +17,64 @@ kill_pid ~/.pa-pid
kill_pid ~/.tcp-pid kill_pid ~/.tcp-pid
kill_pid ~/.ws-pid kill_pid ~/.ws-pid
# Clone and install dotfiles if DOTFILES_REPO is defined
if [ -n "$DOTFILES_REPO" ]; then user_entrypoint() {
if [ ! -d ~/dotfiles ]; then cd ~
git clone $DOTFILES_REPO ~/dotfiles
if [ -f ~/dotfiles/install.sh ]; then # Clone and install dotfiles if DOTFILES_REPO is defined
/bin/bash ~/dotfiles/install.sh if [ -n "$DOTFILES_REPO" ]; then
if [ ! -d ~/dotfiles ]; then
git clone --depth 1 --recurse-submodules --shallow-submodules $DOTFILES_REPO ~/dotfiles
if [ -f ~/dotfiles/install.sh ]; then
/bin/bash ~/dotfiles/install.sh
fi
fi fi
fi fi
# Launch VNC server - view :1 defaults to port 5901
vncserver :1 -SecurityTypes None -localhost no --I-KNOW-THIS-IS-INSECURE &
# vncserver :1 &
echo "$!" > ~/.vnc-pid
# Launch pulseaudio server
# /etc/pulse/client.conf and /etc/pulse/default.pa are setup to make a default
# audio sink which outputs to a socket at /tmp/pulseaudio.socket
DISPLAY=:0.0 pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1&
echo "$!" > ~/.pa-pid
# Use gstreamer to stream the pulseaudio source /tmp/pulseaudio.socket to stdout (fd=1)
# the tcpserver from ucspi-tcp pipes this to tcp port 6901
tcpserver localhost 6901 gst-launch-1.0 -q pulsesrc server=/tmp/pulseaudio.socket ! audio/x-raw, channels=2, rate=12000 ! cutter ! opusenc ! webmmux ! fdsink fd=1 &
echo "$!" > ~/.tcp-pid
# Websockify does three things:
# - publishes /opt/noVNC to http port 8080
# - proxies vnc port 5901 to 8080/websockify?token=vnc
# - proxies pulseaudio port 6901 to 8080/websockify?token=pulse
# The latter two are defined through the tokenfile
/opt/noVNC/utils/websockify/websockify.py --web /opt/noVNC 8080 --token-plugin=TokenFile --token-source=/opt/noVNC/tokenfile &
echo "$!" > ~/.ws-pid
if [ -n "$@" ]; then
DISPLAY=:1.0 exec "$@" &
fi
wait
}
uname=${USERNAME:-novnc}
uid=${UUID:-1000}
gid=${GUID:-1000}
if ! id -u ${uname} > /dev/null 2>&1; then
addgroup --gid ${gid} ${uname}
adduser --home /home/${uname} --shell /bin/bash --system --disabled-password --uid ${uid} --ingroup ${uname} ${uname}
echo "${uname} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
mkdir -p /home/${uname}
chown ${uname}:${uname} /home/${uname}
fi fi
# Launch VNC server - view :1 defaults to port 5901 export -f user_entrypoint
vncserver :1 -SecurityTypes None -localhost no --I-KNOW-THIS-IS-INSECURE & su ${uname} -c "bash -c user_entrypoint ${@}" &
echo "$!" > ~/.vnc-pid
# Launch pulseaudio server
# /etc/pulse/client.conf and /etc/pulse/default.pa are setup to make a default
# audio sink which outputs to a socket at /tmp/pulseaudio.socket
DISPLAY=:0.0 pulseaudio --disallow-module-loading --disallow-exit --exit-idle-time=-1&
echo "$!" > ~/.pa-pid
# Use gstreamer to stream the pulseaudio source /tmp/pulseaudio.socket to stdout (fd=1)
# the tcpserver from ucspi-tcp pipes this to tcp port 6901
tcpserver localhost 6901 gst-launch-1.0 -q pulsesrc server=/tmp/pulseaudio.socket ! audio/x-raw, channels=2, rate=12000 ! cutter ! opusenc ! webmmux ! fdsink fd=1 &
echo "$!" > ~/.tcp-pid
# Websockify does three things:
# - publishes /opt/noVNC to http port 8080
# - proxies vnc port 5901 to 8080/websockify?token=vnc
# - proxies pulseaudio port 6901 to 8080/websockify?token=pulse
# The latter two are defined through the tokenfile
/opt/noVNC/utils/websockify/websockify.py --web /opt/noVNC 8080 --token-plugin=TokenFile --token-source=/opt/noVNC/tokenfile &
echo "$!" > ~/.ws-pid
if [ -n "$@" ]; then
DISPLAY=:1.0 exec "$@" &
fi
wait wait

View File

@ -134,6 +134,7 @@ const wa = new WebAudio(null);
// Audio playback requires user interaction before being allowed by browsers // Audio playback requires user interaction before being allowed by browsers
const connect = () => { const connect = () => {
if (MediaSource === undefined) return;
if (!wa.connected) if (!wa.connected)
wa.start(); wa.start();
}; };

View File

@ -3,42 +3,34 @@ FROM ubuntu
RUN apt-get update \ RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\ apt-get install -y --no-install-recommends\
# Some basic helpers \
bash \ bash \
sudo \ sudo \
git \ git \
procps ca-certificates \
procps \
RUN mkdir -p /opt/noVNC \
# X11 and XFCE \
RUN adduser --home /home/novnc --shell /bin/bash --system --disabled-password novnc \
&& echo "novnc ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# X11 and xfce
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\ apt-get install -y --no-install-recommends\
xvfb xauth dbus-x11 xfce4 xfce4-terminal \ xvfb xauth dbus-x11 xfce4 xfce4-terminal \
x11-xserver-utils x11-xserver-utils \
\
# VNC # VNC \
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\ apt-get install -y --no-install-recommends\
python3 python3-pip \ python3 python3-numpy \
tigervnc-standalone-server tigervnc-common \ tigervnc-standalone-server tigervnc-common \
openssl \ openssl \
&& pip3 install numpy \
# NoVNC \
# NoVNC && mkdir -p /opt/noVNC \
RUN git clone --single-branch https://github.com/novnc/noVNC.git /opt/noVNC \ && git clone --single-branch https://github.com/novnc/noVNC.git /opt/noVNC \
&& git clone --single-branch https://github.com/novnc/websockify.git /opt/noVNC/utils/websockify \ && git clone --single-branch https://github.com/novnc/websockify.git /opt/noVNC/utils/websockify \
&& ln -s /opt/noVNC/vnc.html /opt/noVNC/index.html && ln -s /opt/noVNC/vnc.html /opt/noVNC/index.html \
&& openssl req -batch -new -x509 -days 365 -nodes -out self.pem -keyout /opt/noVNC/utils/websockify/self.pem \
RUN openssl req -batch -new -x509 -days 365 -nodes -out self.pem -keyout /opt/noVNC/utils/websockify/self.pem \
# Audio requirements \
# Audio
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\ apt-get install -y --no-install-recommends\
pulseaudio \ pulseaudio \
@ -48,13 +40,14 @@ RUN apt-get update \
gstreamer1.0-pulseaudio \ gstreamer1.0-pulseaudio \
gstreamer1.0-tools gstreamer1.0-tools
COPY pulse/ /etc/pulse COPY pulse/ /etc/pulse
COPY novnc /opt/noVNC/ COPY novnc /opt/noVNC/
RUN sed -i "/import RFB/a \ RUN sed -i "/import RFB/a \
import '../webaudio.js'" \ import '../webaudio.js'" \
/opt/noVNC/app/ui.js /opt/noVNC/app/ui.js
# Extra applications # Base applications
RUN apt-get update \ RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \ && DEBIAN_FRONTEND=noninteractive \
apt-get install -y --no-install-recommends\ apt-get install -y --no-install-recommends\
@ -64,6 +57,3 @@ COPY entrypoint.sh /opt/noVNC/entrypoint.sh
ENTRYPOINT ["/opt/noVNC/entrypoint.sh"] ENTRYPOINT ["/opt/noVNC/entrypoint.sh"]
EXPOSE 8080 EXPOSE 8080
USER novnc
WORKDIR /home/novnc