## Dockerfile cat >Dockerfile <<- 'Dockerfile' # syntax = docker/dockerfile:1.2 FROM quay.io/archlinux/archlinux:base-devel USER root # Docker ENV variables # # Required # ENV MYVNC_VNCPASS # # Optional # ENV MYVNC_CUSTOM_TITLE # ENV MYVNC_PROXYPATH (eg, "/subpath/" or "/subpath") # ENV MYVNC_VNCSHARING (eg, "true" to allow sharing (defaults to "false")) # ENV MYVNC_VNCSERVER_HOST (eg, localhost or 192.168.1.1) # ENV MYVNC_VNCSERVER_PORT (eg, 5900) # Build ARG for additional pacman packages to install (eg, openssh) ARG pkg # Install packages COPY mirrorlist /etc/pacman.d/mirrorlist RUN pacman-key --init \ && sed -i '/ParallelDownloads/c ParallelDownloads = 10' /etc/pacman.conf \ && pacman -Sy --ask 4 archlinux-keyring \ && pacman -Su --ask 4 --needed \ sudo ${pkg} \ inetutils python-numpy python-setuptools \ nginx-mainline \ && pacman -Scc --ask 4 \ && useradd --create-home --gid users --shell /usr/bin/bash user \ && echo 'user ALL=(ALL:ALL) NOPASSWD: MISCELLANEOUS, /usr/bin/nginx' >/etc/sudoers.d/zz-DOCKER \ && echo 'Defaults lecture = never' >>/etc/sudoers.d/zz-DOCKER \ && passwd -l root >/dev/null 2>&1 \ && sed '/^http {/a\ \ include /app/nginx/\*.conf;\n\ \ types_hash_max_size 4096;\n\ \ server_names_hash_bucket_size 128;\n' -i /etc/nginx/nginx.conf \ && mkdir -p /app/init.d /app/nginx /app/logs # Install noVNC COPY novnc /app/novnc # Install all init scripts COPY docker-entrypoint.sh /docker-entrypoint.sh COPY 01-init.sh 10-novnc.sh 10-nginx.sh /app/init.d/ # Proper permissions RUN chmod +x /docker-entrypoint.sh /app/init.d/* \ && chown -R user:users /app # Default environment USER user WORKDIR /home/user ENV DISPLAY :0 ENV SHELL /usr/bin/bash # Expose nginx port for VNC webui EXPOSE 6900 # Docker entrypoint ENTRYPOINT ["/docker-entrypoint.sh"] Dockerfile ## Init script, always runs first cat >01-init.sh <<- '01-init.sh' #!/usr/bin/env bash # Create base directories for dir in vnc config ssh do [ -d ~/.${dir} ] || mkdir -p ~/.${dir} done ## OPTIONAL: More commands may be added below 01-init.sh ## NoVNC setup cat >10-novnc.sh <<- '10-novnc.sh' #!/usr/bin/env bash # Turn vnc sharing on/off if [[ ${MYVNC_VNCSHARING} == "true" ]] || [[ ${MYVNC_VNCSHARING} == "1" ]] then _MYVNC_VNCSHARING=true else _MYVNC_VNCSHARING=false fi # Always default to remote scaling sed -i "/UI.initSetting\|resize/ s/resize', '.*');/resize', 'scale');/" /app/novnc/app/ui.js # Always default to autoconnect=true sed -i "/let autoconnect/ s/autoconnect', .*);/autoconnect', true);/" /app/novnc/app/ui.js # Change vnc shared view settings (defaults to false/off) sed -i "/UI.initSetting\|shared/ s/shared', .*);/shared', ${_MYVNC_VNCSHARING});/" /app/novnc/app/ui.js # NoVNC custom title sed -i "/noVNC<\/title>/ s/noVNC/${MYVNC_CUSTOM_TITLE:-noVNC}/g" /app/novnc/*.html # Apply subpath to websocket if [[ ${MYVNC_PROXYPATH} == "/" ]] then unset _MYVNC_PROXYPATH elif [ ${MYVNC_PROXYPATH} ] then _MYVNC_PROXYPATH=$(echo ${MYVNC_PROXYPATH%/} | sed "s|^.*/||") sed -i "/UI.initSetting/ s|websockify|${_MYVNC_PROXYPATH}/&|" /app/novnc/app/ui.js fi # Start NoVNC /app/novnc/utils/novnc_proxy \ --listen 6080 \ --vnc ${MYVNC_VNCSERVER_HOST:-localhost}:${MYVNC_VNCSERVER_PORT:-5900} \ --file-only & 10-novnc.sh ## Nginx setup cat >10-nginx.sh <<- '10-nginx.sh' #!/usr/bin/env bash # Reformat path if [[ ${MYVNC_PROXYPATH} == "/" ]] then unset _MYVNC_PROXYPATH elif [ ${MYVNC_PROXYPATH} ] then _MYVNC_PROXYPATH=$(echo ${MYVNC_PROXYPATH%/} | sed "s|^.*/||;s|^|/|") fi # Add novnc virtual proxy conf cat >/app/nginx/novnc.conf <<- novnc upstream vnc_proxy { server 127.0.0.1:6080; } server { listen 6900; location ${_MYVNC_PROXYPATH}/websockify { proxy_http_version 1.1; proxy_pass http://vnc_proxy/; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; # VNC connection timeout proxy_read_timeout 3600s; proxy_send_timeout 3600s; # Disable cache proxy_buffering off; } location ${_MYVNC_PROXYPATH}/ { index vnc.html; alias /app/novnc/; try_files \$uri \$uri/ /vnc.html; # In the location block related to noVNC add_header Cache-Control no-cache; } } novnc # Start nginx sudo /usr/bin/nginx -g "daemon off;" & 10-nginx.sh ## Docker entrypoint cat >docker-entrypoint.sh <<- 'docker-entrypoint.sh' #!/usr/bin/env bash # Export all variables set -a # Abort if an error is encountered set -e # SSH config if [ -f ~/.ssh/id_ed25519 ] then chmod 0600 ~/.ssh/id_ed25519 fi # Run all scripts in init folder for file in /app/init.d/*.sh do /usr/bin/bash -c ${file} >>/app/logs/$(echo ${file} | sed 's|/app/init.d/||;s|\.sh$||').log done # Read cli parameters exec ${@} # Monitor log tail -f /app/logs/*.log docker-entrypoint.sh ## Fetch latest mirrorlist cat /etc/pacman.d/mirrorlist >mirrorlist ## Docker build # eg, ARCHPKG=openssh # eg, BUILDTAG=base DOCKER_BUILDKIT=1 docker build ./. \ --build-arg pkg=${ARCHPKG:-""} \ --tag myvnc/${BUILDTAG:-base} \ && rm -f Dockerfile *.sh