diff --git a/deepin-webtop/beige/Dockerfile b/deepin-webtop/beige/Dockerfile
index 8bd8ecd..238cebf 100644
--- a/deepin-webtop/beige/Dockerfile
+++ b/deepin-webtop/beige/Dockerfile
@@ -584,6 +584,15 @@ RUN \
# add local files
COPY /root /
+RUN \
+ systemctl enable kasmvnc-config && \
+ systemctl enable video && \
+ systemctl enable adduser && \
+ systemctl enable pulseaudio && \
+ systemctl enable kasmvnc && \
+ systemctl enable kclient && \
+ systemctl enable dde
+
# ports and volumes
EXPOSE 3000 3001
VOLUME /config
diff --git a/deepin-webtop/beige/docker-compose.yml b/deepin-webtop/beige/docker-compose.yml
index 5110ec0..bb7cfc7 100644
--- a/deepin-webtop/beige/docker-compose.yml
+++ b/deepin-webtop/beige/docker-compose.yml
@@ -1,18 +1,18 @@
version: '3.8'
services:
- systemd_test:
+ deepin-webtop:
+ image: chenchongbiao/deepin-webtop
build:
context: .
dockerfile: Dockerfile
- container_name: systemd_test
+ container_name: deepin-webtop
privileged: true
cap_add:
- SYS_ADMIN
security_opt:
- seccomp:unconfined
tmpfs:
- - /tmp
- /run
- /run/lock
ports:
@@ -24,37 +24,16 @@ services:
- SUBFOLDER=/ #optional
- TITLE=Webtop #optional
- https_proxy=http://10.20.42.187:7890
- - DOCKER_MODS=linuxserver/mods:universal-package-install
+ - DOCKER_MODS=linuxserver/mods:universal-package-install
- INSTALL_PACKAGES=fonts-noto-cjk
- LC_ALL=zh_CN.UTF-8
volumes:
- ./data:/config
+ # - ./startwm.sh:/defaults/startwm.sh
+ # - ./root/kasminit:/kasminit
- /var/run/docker.sock:/var/run/docker.sock #optional
devices:
- /dev/dri:/dev/dri #optional
shm_size: "1gb" #optional
cgroup_parent: docker.slice
restart: unless-stopped
-
- environment:
- - PUID=1000
- - PGID=1000
- - TZ=Asia/Shanghai
- - SUBFOLDER=/ #optional
- - TITLE=Webtop #optional
- - https_proxy=http://10.20.42.187:7890
- - DOCKER_MODS=linuxserver/mods:universal-package-install
- - INSTALL_PACKAGES=fonts-noto-cjk
- - LC_ALL=zh_CN.UTF-8
- - XDG_SESSION_TYPE=x11
- - XDG_SESSION_DESKTOP=dde-x11
- - XDG_CURRENT_DESKTOP=DDE
- volumes:
- - ./data:/config
- - ./startwm.sh:/defaults/startwm.sh
- - /var/run/docker.sock:/var/run/docker.sock #optional
- ports:
- - 3002:3000
- devices:
- - /dev/dri:/dev/dri #optional
- shm_size: "1gb" #optional
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/defaults/autostart b/deepin-webtop/beige/root/defaults/autostart
new file mode 100755
index 0000000..db0c341
--- /dev/null
+++ b/deepin-webtop/beige/root/defaults/autostart
@@ -0,0 +1 @@
+xterm
diff --git a/deepin-webtop/beige/root/defaults/default.conf b/deepin-webtop/beige/root/defaults/default.conf
new file mode 100644
index 0000000..1350d5f
--- /dev/null
+++ b/deepin-webtop/beige/root/defaults/default.conf
@@ -0,0 +1,102 @@
+server {
+ #auth_basic "Login";
+ #auth_basic_user_file /etc/nginx/.htpasswd;
+ listen 3000 default_server;
+ listen [::]:3000 default_server;
+ location / {
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Cookie "";
+ proxy_read_timeout 3600s;
+ proxy_send_timeout 3600s;
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+ add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
+ add_header 'Access-Control-Allow-Credentials' 'true';
+ add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
+ add_header 'Cross-Origin-Opener-Policy' 'same-origin';
+ add_header 'Cross-Origin-Resource-Policy' 'same-site';
+ proxy_pass http://127.0.0.1:6900;
+ proxy_buffering off;
+ }
+
+ location SUBFOLDERwebsockify {
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Cookie "";
+ proxy_read_timeout 3600s;
+ proxy_send_timeout 3600s;
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+ add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
+ add_header 'Access-Control-Allow-Credentials' 'true';
+ add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
+ add_header 'Cross-Origin-Opener-Policy' 'same-origin';
+ add_header 'Cross-Origin-Resource-Policy' 'same-site';
+ proxy_pass http://127.0.0.1:6901;
+ proxy_buffering off;
+ }
+}
+
+server {
+ #auth_basic "Login";
+ #auth_basic_user_file /etc/nginx/.htpasswd;
+ listen 3001 ssl;
+ listen [::]:3001 ssl;
+ ssl_certificate /config/ssl/cert.pem;
+ ssl_certificate_key /config/ssl/cert.key;
+ location / {
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Cookie "";
+ proxy_read_timeout 3600s;
+ proxy_send_timeout 3600s;
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+ add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
+ add_header 'Access-Control-Allow-Credentials' 'true';
+ add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
+ add_header 'Cross-Origin-Opener-Policy' 'same-origin';
+ add_header 'Cross-Origin-Resource-Policy' 'same-site';
+ proxy_pass http://127.0.0.1:6900;
+ proxy_buffering off;
+ }
+
+ location SUBFOLDERwebsockify {
+ proxy_http_version 1.1;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_set_header Cookie "";
+ proxy_read_timeout 3600s;
+ proxy_send_timeout 3600s;
+ add_header 'Access-Control-Allow-Origin' '*' always;
+ add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
+ add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since';
+ add_header 'Access-Control-Allow-Credentials' 'true';
+ add_header 'Cross-Origin-Embedder-Policy' 'require-corp';
+ add_header 'Cross-Origin-Opener-Policy' 'same-origin';
+ add_header 'Cross-Origin-Resource-Policy' 'same-site';
+ proxy_pass http://127.0.0.1:6901;
+ proxy_buffering off;
+ }
+}
+
diff --git a/deepin-webtop/beige/root/defaults/menu.xml b/deepin-webtop/beige/root/defaults/menu.xml
new file mode 100644
index 0000000..1333076
--- /dev/null
+++ b/deepin-webtop/beige/root/defaults/menu.xml
@@ -0,0 +1,6 @@
+
+
+
+
diff --git a/deepin-webtop/beige/root/defaults/startwm.sh b/deepin-webtop/beige/root/defaults/startwm.sh
index d282d0c..bc99a43 100755
--- a/deepin-webtop/beige/root/defaults/startwm.sh
+++ b/deepin-webtop/beige/root/defaults/startwm.sh
@@ -18,4 +18,6 @@ setterm blank 0
setterm powerdown 0
# Launch DE
-/usr/bin/dde-session > /dev/null 2>&1
+/usr/bin/dde-session & > /dev/null 2>&1
+/usr/bin/dde-desktop & > /dev/null 2>&1
+/usr/bin/dde-shell
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/kasminit b/deepin-webtop/beige/root/kasminit
new file mode 100755
index 0000000..370a075
--- /dev/null
+++ b/deepin-webtop/beige/root/kasminit
@@ -0,0 +1,207 @@
+#!/usr/bin/env bash
+set -e
+set -x
+
+# Purge temp files on init and exit
+function clean () {
+ rm -rf /tmp/{,.[!.],..?}* || :
+}
+trap clean SIGINT SIGTERM
+clean
+
+# Lang
+if [ ! -z ${LC_ALL+x} ]; then
+ export LANGUAGE="${LC_ALL%.UTF-8}"
+ export LANG="${LC_ALL}"
+fi
+
+# Environment
+export HOME=/home/kasm-user
+export KASM_VNC_PATH=/usr/share/kasmvnc
+export PULSE_RUNTIME_PATH=/var/run/pulse
+if [ -z ${DRINODE+x} ]; then
+ DRINODE="/dev/dri/renderD128"
+fi
+KASMNVC_HW3D=''
+if [ ! -z ${HW3D+x} ]; then
+ KASMVNC_HW3D="-hw3d"
+fi
+
+# Go URL translation
+if [ ! -z ${KASM_URL+x} ]; then
+ export BRAVE_CLI=$KASM_URL
+ export CHROME_CLI=$KASM_URL
+ export EDGE_CLI=$KASM_URL
+ export FIREFOX_CLI=$KASM_URL
+ export OPERA_CLI=$KASM_URL
+ export TOR_CLI=$KASM_URL
+ export VIVALDI_CLI=$KASM_URL
+fi
+
+# Notification daemon
+dunst &
+
+## Directory setup for home folder ##
+# Create folders for upload/download
+mkdir -p $HOME/Desktop $HOME/Downloads
+for FOLDER in Uploads Downloads; do
+ if [[ ! -L $HOME/Desktop/$FOLDER ]]; then
+ mkdir -p $HOME/$FOLDER
+ ln -sf $HOME/$FOLDER $HOME/Desktop/$FOLDER
+ fi
+done
+if [[ ! -L $KASM_VNC_PATH/www/Downloads/Downloads ]]; then
+ ln -sf $HOME/Downloads $KASM_VNC_PATH/www/Downloads/Downloads
+fi
+rm -rf $HOME/.config/pulse
+# Openbox config files
+if [[ ! -f $HOME/.config/openbox/autostart ]]; then
+ mkdir -p $HOME/.config/openbox
+ cp /defaults/autostart $HOME/.config/openbox/autostart
+fi
+if [[ ! -f $HOME/.config/openbox/menu.xml ]]; then
+ mkdir -p $HOME/.config/openbox
+ cp /defaults/menu.xml $HOME/.config/openbox/menu.xml
+fi
+# Startup Script for DE
+mkdir -p $HOME/.vnc
+cp \
+ /defaults/startwm.sh \
+ $HOME/.vnc/xstartup
+touch $HOME/.vnc/.de-was-selected
+# Add proot-apps
+if [ ! -f "${HOME}/.local/bin/proot-apps" ]; then
+ mkdir -p ${HOME}/.local/bin/
+ cp /proot-apps/* ${HOME}/.local/bin/
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc
+elif ! diff -q /proot-apps/pversion ${HOME}/.local/bin/pversion > /dev/null; then
+ cp /proot-apps/* ${HOME}/.local/bin/
+fi
+
+## Network egress wait ##
+while :; do
+ interfaces=$(ip link show type veth | awk -F: '/^[0-9]+: / {print $2}' | awk '{print $1}' | sed 's/@.*//')
+ if [ -z "$interfaces" ]; then
+ sleep 1
+ continue
+ fi
+ for interface in $interfaces; do
+ if [[ $interface == eth* ]]; then
+ break 2
+ fi
+ if [[ $interface == k-p-* ]]; then
+ egress_file="/dockerstartup/.egress_status"
+ while [ ! -f "$egress_file" ]; do
+ sleep 1
+ done
+ egress_status=$(cat $egress_file)
+ if [ "$egress_status" == "ready" ]; then
+ break 2
+ fi
+ if [ "$egress_status" == "error" ]; then
+ echo "Failed to establish egress gateway. Exiting..."
+ exit 1
+ fi
+ fi
+ done
+ sleep 1
+done
+
+## KasmVNC init ##
+# Password
+if [[ -f $HOME/.kasmpasswd ]]; then
+ rm -f $HOME/.kasmpasswd
+fi
+if [[ -z ${VNC_PW+x} ]]; then
+ VNC_PW="vncpassword"
+fi
+if [[ -z ${VNC_VIEW_ONLY_PW+x} ]]; then
+ VNC_VIEW_ONLY_PW="vncviewonlypassword"
+fi
+VNC_PW_HASH=$(python3 -c "import crypt; print(crypt.crypt('${VNC_PW}', '\$5\$kasm\$'));")
+VNC_VIEW_PW_HASH=$(python3 -c "import crypt; print(crypt.crypt('${VNC_VIEW_ONLY_PW}', '\$5\$kasm\$'));")
+echo "kasm_user:${VNC_PW_HASH}:ow" > $HOME/.kasmpasswd
+echo "kasm_viewer:${VNC_VIEW_PW_HASH}:" >> $HOME/.kasmpasswd
+chmod 600 $HOME/.kasmpasswd
+# SSL cert
+rm -f ${HOME}/.vnc/self.pem
+openssl req -x509 \
+ -nodes \
+ -days 3650 \
+ -newkey rsa:2048 \
+ -keyout ${HOME}/.vnc/self.pem \
+ -out ${HOME}/.vnc/self.pem \
+ -subj "/C=US/ST=VA/L=None/O=None/OU=DoFu/CN=kasm/emailAddress=none@none.none"
+# Start KasmVNC
+vncserver $DISPLAY \
+ $KASMVNC_HW3D \
+ -drinode $DRINODE \
+ -websocketPort 6901 \
+ -httpd ${KASM_VNC_PATH}/www \
+ -FrameRate=60 \
+ -interface 0.0.0.0 \
+ -BlacklistThreshold=0 \
+ -FreeKeyMappings \
+ -PreferBandwidth \
+ -DynamicQualityMin=4 \
+ -DynamicQualityMax=7 \
+ -DLP_ClipDelay=0 \
+ -sslOnly \
+ -UnixRelay printer:/tmp/printer
+
+## Microservice Init ##
+# Audio
+/kasmbins/kasm_websocket_relay/kasm_audio_out-linux \
+ kasmaudio \
+ 8081 \
+ 4901 \
+ ${HOME}/.vnc/self.pem \
+ ${HOME}/.vnc/self.pem \
+ "kasm_user:$VNC_PW" &
+HOME=/var/run/pulse pulseaudio --start
+HOME=/var/run/pulse no_proxy=127.0.0.1 ffmpeg \
+ -v verbose \
+ -f pulse \
+ -fragment_size ${PULSEAUDIO_FRAGMENT_SIZE:-2000} \
+ -ar 44100 \
+ -i default \
+ -f mpegts \
+ -correct_ts_overflow 0 \
+ -codec:a mp2 \
+ -b:a 128k \
+ -ac 1 \
+ -muxdelay 0.001 \
+ http://127.0.0.1:8081/kasmaudio > /dev/null 2>&1 &
+# Audio in
+/kasmbins/kasm_audio_input_server \
+ --ssl \
+ --auth-token "kasm_user:$VNC_PW" \
+ --cert ${HOME}/.vnc/self.pem \
+ --certkey ${HOME}/.vnc/self.pem &
+# Uploads
+/kasmbins/kasm_upload_server \
+ --ssl \
+ --auth-token "kasm_user:$VNC_PW" &
+# Gamepad
+if [[ ${KASM_SVC_GAMEPAD:-1} == 1 ]]; then
+ /kasmbins/kasm_gamepad_server \
+ --ssl \
+ --auth-token "kasm_user:$VNC_PW" \
+ --cert ${HOME}/.vnc/self.pem \
+ --certkey ${HOME}/.vnc/self.pem &
+fi
+# Webcam
+if [[ -e /dev/video0 ]]; then
+ /kasmbins/kasm_webcam_server \
+ --port 4905 \
+ --ssl \
+ --cert ${HOME}/.vnc/self.pem \
+ --certkey ${HOME}/.vnc/self.pem &
+fi
+# Printer
+/kasmbins/kasm_printer_service \
+ --directory $HOME/PDF \
+ --relay /tmp/printer &
+
+# Show KasmVNC Logs
+tail -f $HOME/.vnc/*$DISPLAY.log
diff --git a/deepin-webtop/beige/root/nginx b/deepin-webtop/beige/root/nginx
new file mode 100755
index 0000000..e175082
--- /dev/null
+++ b/deepin-webtop/beige/root/nginx
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+set -e
+set -x
+
+# nginx Path
+NGINX_CONFIG=/etc/nginx/sites-available/default
+
+# user passed env vars
+CPORT="${CUSTOM_PORT:-3000}"
+CHPORT="${CUSTOM_HTTPS_PORT:-3001}"
+CUSER="${CUSTOM_USER:-deepin}"
+SFOLDER="${SUBFOLDER:-/}"
+
+# create self signed cert
+if [ ! -f "/config/ssl/cert.pem" ]; then
+ mkdir -p /config/ssl
+ openssl req -new -x509 \
+ -days 3650 -nodes \
+ -out /config/ssl/cert.pem \
+ -keyout /config/ssl/cert.key \
+ -subj "/C=US/ST=CA/L=Carlsbad/O=Linuxserver.io/OU=LSIO Server/CN=*"
+ chmod 600 /config/ssl/cert.key
+ chown -R deepin:deepin /config/ssl
+fi
+
+# modify nginx config
+cp /defaults/default.conf ${NGINX_CONFIG}
+sed -i "s/3000/$CPORT/g" ${NGINX_CONFIG}
+sed -i "s/3001/$CHPORT/g" ${NGINX_CONFIG}
+sed -i "s|SUBFOLDER|$SFOLDER|g" ${NGINX_CONFIG}
+if [ ! -z ${DISABLE_IPV6+x} ]; then
+ sed -i '/listen \[::\]/d' ${NGINX_CONFIG}
+fi
+if [ ! -z ${PASSWORD+x} ]; then
+ printf "${CUSER}:$(openssl passwd -apr1 ${PASSWORD})\n" > /etc/nginx/.htpasswd
+ sed -i 's/#//g' ${NGINX_CONFIG}
+fi
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/adduser.service b/deepin-webtop/beige/root/usr/lib/systemd/system/adduser.service
new file mode 100644
index 0000000..9865096
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/adduser.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=adduser Service
+After=network.target
+Before=kasmvnc-config.service
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/init-adduser
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/dde.service b/deepin-webtop/beige/root/usr/lib/systemd/system/dde.service
new file mode 100644
index 0000000..f0fc516
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/dde.service
@@ -0,0 +1,16 @@
+[Unit]
+Description=dde Service
+After=network.target
+After=nginx.service
+
+[Service]
+Type=simple
+User=deepin
+Group=deepin
+Environment="TERM=xterm"
+Environment="DISPLAY=:0"
+Environment="HOME=/config"
+ExecStart=/defaults/startwm.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/kasminit.service b/deepin-webtop/beige/root/usr/lib/systemd/system/kasminit.service
new file mode 100644
index 0000000..2b76e89
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/kasminit.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Kasminit Service
+After=network.target
+
+[Service]
+User=root
+Group=root
+ExecStart=/kasminit &
+#ExecStart=/bin/bash -c "/kasminit &> /var/log/kasminit.log 2>&1"
+Restart=on-failure
+RestartSec=10s
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc-config.service b/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc-config.service
new file mode 100644
index 0000000..c7c52bf
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc-config.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Kasmvnc config Service
+After=network.target
+After=nginx.service
+
+[Service]
+Type=simple
+Environment="HOME=/config"
+ExecStart=/usr/local/bin/init-kasmvnc-config
+#ExecStart=/bin/bash -c "/kasminit &> /var/log/kasminit.log 2>&1"
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc.service b/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc.service
new file mode 100644
index 0000000..5ca8b55
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/kasmvnc.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=kasmvnc Service
+After=network.target
+After=pulseaudio.service
+
+[Service]
+User=root
+Group=root
+ExecStart=/usr/local/bin/kasmvnc
+Restart=on-failure
+RestartSec=10s
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/kclient.service b/deepin-webtop/beige/root/usr/lib/systemd/system/kclient.service
new file mode 100644
index 0000000..037d624
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/kclient.service
@@ -0,0 +1,15 @@
+[Unit]
+Description=kclient Service
+After=network.target
+After=kasmvnc.service
+
+[Service]
+User=deepin
+Group=deepin
+ExecStart=/usr/local/bin/kasmclient
+#ExecStart=/bin/bash -c "/kasmclient &> /var/log/kclient.log 2>&1"
+Restart=on-failure
+RestartSec=10s
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/nginx.service b/deepin-webtop/beige/root/usr/lib/systemd/system/nginx.service
new file mode 100644
index 0000000..5e27d10
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/nginx.service
@@ -0,0 +1,30 @@
+# Stop dance for nginx
+# =======================
+#
+# ExecStop sends SIGQUIT (graceful stop) to the nginx process.
+# If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control
+# and sends SIGTERM (fast shutdown) to the main process.
+# After another 5s (TimeoutStopSec=5), and if nginx is alive, systemd sends
+# SIGKILL to all the remaining processes in the process group (KillMode=mixed).
+#
+# nginx signals reference doc:
+# http://nginx.org/en/docs/control.html
+#
+[Unit]
+Description=A high performance web server and a reverse proxy server
+Documentation=man:nginx(8)
+After=network-online.target remote-fs.target nss-lookup.target
+Wants=network-online.target
+
+[Service]
+Type=forking
+PIDFile=/run/nginx.pid
+ExecStartPre=/nginx && /usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
+ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
+ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
+ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
+TimeoutStopSec=5
+KillMode=mixed
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/pulseaudio.service b/deepin-webtop/beige/root/usr/lib/systemd/system/pulseaudio.service
new file mode 100644
index 0000000..2224893
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/pulseaudio.service
@@ -0,0 +1,12 @@
+[Unit]
+Description=pulseaudio Service
+After=network.target
+
+[Service]
+Type=simple
+User=deepin
+Group=deepin
+ExecStart=/usr/local/bin/svc-pulseaudio
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deepin-webtop/beige/root/usr/lib/systemd/system/video.service b/deepin-webtop/beige/root/usr/lib/systemd/system/video.service
new file mode 100644
index 0000000..ba2edae
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/lib/systemd/system/video.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=init-video Service
+After=network.target
+After=kasmvnc-config.service
+
+[Service]
+Type=simple
+ExecStart=/usr/local/bin/init-video
+Restart=on-failure
+RestartSec=10s
+
+[Install]
+WantedBy=multi-user.target
diff --git a/deepin-webtop/beige/root/usr/local/bin/init-adduser b/deepin-webtop/beige/root/usr/local/bin/init-adduser
new file mode 100755
index 0000000..ff398a4
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/init-adduser
@@ -0,0 +1,34 @@
+#!/usr/bin/env bash
+
+set -x
+
+PUID=${PUID:-911}
+PGID=${PGID:-911}
+
+groupmod -o -g "$PGID" deepin
+usermod -o -u "$PUID" deepin
+
+if [[ -f /donate.txt ]]; then
+ echo '
+To support the app dev(s) visit:'
+ cat /donate.txt
+fi
+echo '
+
+───────────────────────────────────────
+GID/UID
+───────────────────────────────────────'
+echo "
+User UID: $(id -u deepin)
+User GID: $(id -g deepin)
+───────────────────────────────────────"
+if [[ -f /build_version ]]; then
+ cat /build_version
+ echo '
+───────────────────────────────────────
+ '
+fi
+
+lsiown deepin:deepin /app
+lsiown deepin:deepin /config
+lsiown deepin:deepin /defaults
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/local/bin/init-kasmvnc-config b/deepin-webtop/beige/root/usr/local/bin/init-kasmvnc-config
new file mode 100755
index 0000000..ba93105
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/init-kasmvnc-config
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+set -x
+
+# default file copies first run
+if [[ ! -f /config/.config/openbox/autostart ]]; then
+ mkdir -p /config/.config/openbox
+ cp /defaults/autostart /config/.config/openbox/autostart
+ chown -R deepin:deepin /config/.config/openbox
+fi
+if [[ ! -f /config/.config/openbox/menu.xml ]]; then
+ mkdir -p /config/.config/openbox && \
+ cp /defaults/menu.xml /config/.config/openbox/menu.xml && \
+ chown -R deepin:deepin /config/.config
+fi
+if [[ -f /usr/local/etc/kasmvnc/kasmvnc.yaml.lsio ]]; then
+ mv \
+ /usr/local/etc/kasmvnc/kasmvnc.yaml.lsio \
+ /usr/local/etc/kasmvnc/kasmvnc.yaml
+fi
+
+# XDG Home
+printf "${HOME}/.XDG" > /run/s6/container_environment/XDG_RUNTIME_DIR
+if [ ! -d "${HOME}/.XDG" ]; then
+ mkdir -p ${HOME}/.XDG
+ chown deepin:deepin ${HOME}/.XDG
+fi
+
+# Locale Support
+if [ ! -z ${LC_ALL+x} ]; then
+ printf "${LC_ALL%.UTF-8}" > /run/s6/container_environment/LANGUAGE
+ printf "${LC_ALL}" > /run/s6/container_environment/LANG
+fi
+
+# Remove window borders
+if [[ ! -z ${NO_DECOR+x} ]] && [[ ! -f /decorlock ]]; then
+ sed -i \
+ 's|| no \n|' \
+ /etc/xdg/openbox/rc.xml
+ touch /decorlock
+fi
+
+# Fullscreen everything in openbox unless the user explicitly disables it
+if [[ ! -z ${NO_FULL+x} ]] && [[ ! -f /fulllock ]]; then
+ sed -i \
+ '/yes<\/maximized><\/application>/d' \
+ /etc/xdg/openbox/rc.xml
+ touch /fulllock
+fi
+
+# Add proot-apps
+if [ ! -f "${HOME}/.local/bin/proot-apps" ]; then
+ mkdir -p ${HOME}/.local/bin/
+ cp /proot-apps/* ${HOME}/.local/bin/
+ echo 'export PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc
+ chown deepin:deepin \
+ ${HOME}/.bashrc \
+ ${HOME}/.local/ \
+ ${HOME}/.local/bin \
+ ${HOME}/.local/bin/{ncat,proot-apps,proot,jq,pversion} \
+ ${HOME}/.cache
+elif ! diff -q /proot-apps/pversion ${HOME}/.local/bin/pversion > /dev/null; then
+ cp /proot-apps/* ${HOME}/.local/bin/
+ chown deepin:deepin ${HOME}/.local/bin/{ncat,proot-apps,proot,jq,pversion}
+fi
diff --git a/deepin-webtop/beige/root/usr/local/bin/init-video b/deepin-webtop/beige/root/usr/local/bin/init-video
new file mode 100755
index 0000000..c3a92e2
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/init-video
@@ -0,0 +1,37 @@
+#!/usr/bin/env bash
+
+set -x
+
+FILES=$(find /dev/dri /dev/dvb -type c -print 2>/dev/null)
+
+for i in $FILES
+do
+ VIDEO_GID=$(stat -c '%g' "${i}")
+ VIDEO_UID=$(stat -c '%u' "${i}")
+ # check if user matches device
+ if id -u deepin | grep -qw "${VIDEO_UID}"; then
+ echo "**** permissions for ${i} are good ****"
+ else
+ # check if group matches and that device has group rw
+ if id -G deepin | grep -qw "${VIDEO_GID}" && [ $(stat -c '%A' "${i}" | cut -b 5,6) = "rw" ]; then
+ echo "**** permissions for ${i} are good ****"
+ # check if device needs to be added to video group
+ elif ! id -G deepin | grep -qw "${VIDEO_GID}"; then
+ # check if video group needs to be created
+ VIDEO_NAME=$(getent group "${VIDEO_GID}" | awk -F: '{print $1}')
+ if [ -z "${VIDEO_NAME}" ]; then
+ VIDEO_NAME="video$(head /dev/urandom | tr -dc 'a-z0-9' | head -c4)"
+ groupadd "${VIDEO_NAME}"
+ groupmod -g "${VIDEO_GID}" "${VIDEO_NAME}"
+ echo "**** creating video group ${VIDEO_NAME} with id ${VIDEO_GID} ****"
+ fi
+ echo "**** adding ${i} to video group ${VIDEO_NAME} with id ${VIDEO_GID} ****"
+ usermod -a -G "${VIDEO_NAME}" deepin
+ fi
+ # check if device has group rw
+ if [ $(stat -c '%A' "${i}" | cut -b 5,6) != "rw" ]; then
+ echo -e "**** The device ${i} does not have group read/write permissions, attempting to fix inside the container.If it doesn't work, you can run the following on your docker host: ****\nsudo chmod g+rw ${i}\n"
+ chmod g+rw "${i}"
+ fi
+ fi
+done
diff --git a/deepin-webtop/beige/root/usr/local/bin/kasmclient b/deepin-webtop/beige/root/usr/local/bin/kasmclient
new file mode 100755
index 0000000..cc9120b
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/kasmclient
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -x
+
+# Mic Setup
+if [ ! -f '/dev/shm/mic.lock' ]; then
+ # until [ -f /defaults/pid ]; do
+ # sleep .5
+ # done
+ pactl \
+ load-module module-pipe-source \
+ source_name=virtmic \
+ file=/defaults/mic.sock \
+ source_properties=device.description=LSIOMic \
+ format=s16le \
+ rate=44100 \
+ channels=1
+ pactl \
+ set-default-source virtmic
+ touch /dev/shm/mic.lock
+fi
+
+# NodeJS wrapper
+cd /kclient
+exec node index.js
+
diff --git a/deepin-webtop/beige/root/usr/local/bin/kasmvnc b/deepin-webtop/beige/root/usr/local/bin/kasmvnc
new file mode 100755
index 0000000..30a6f6f
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/kasmvnc
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+# Pass gpu flags if mounted
+if ls /dev/dri/renderD* 1> /dev/null 2>&1 && [ -z ${DISABLE_DRI+x} ] && ! which nvidia-smi; then
+ HW3D="-hw3d"
+fi
+if [ -z ${DRINODE+x} ]; then
+ DRINODE="/dev/dri/renderD128"
+fi
+
+exec \
+ /usr/local/bin/Xvnc $DISPLAY \
+ ${HW3D} \
+ -PublicIP 127.0.0.1 \
+ -drinode ${DRINODE} \
+ -disableBasicAuth \
+ -SecurityTypes None \
+ -AlwaysShared \
+ -http-header Cross-Origin-Embedder-Policy=require-corp \
+ -http-header Cross-Origin-Opener-Policy=same-origin \
+ -geometry 1024x768 \
+ -sslOnly 0 \
+ -RectThreads 0 \
+ -websocketPort 6901 \
+ -interface 0.0.0.0 \
+ -Log *:stdout:10
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/local/bin/lsiown b/deepin-webtop/beige/root/usr/local/bin/lsiown
new file mode 100755
index 0000000..3814739
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/lsiown
@@ -0,0 +1,30 @@
+#!/bin/bash
+
+# Version 1
+# 2024-06-08 - Initial Version
+
+LSIOWN_SCRIPT_VER="1.20240608"
+
+MAXDEPTH=("-maxdepth" "0")
+OPTIONS=()
+while getopts RcfvhHLP OPTION
+do
+ if [[ "${OPTION}" != "?" && "${OPTION}" != "R" ]]; then
+ OPTIONS+=("-${OPTION}")
+ fi
+ if [[ "${OPTION}" = "R" ]]; then
+ MAXDEPTH=()
+ fi
+done
+
+shift $((OPTIND - 1))
+OWNER=$1
+IFS=: read -r USER GROUP <<< "${OWNER}"
+if [[ -z "${GROUP}" ]]; then
+ printf '**** Permissions could not be set. Group is missing or incorrect, expecting user:group. ****\n'
+ exit 0
+fi
+
+ERROR='**** Permissions could not be set. This is probably because your volume mounts are remote or read-only. ****\n**** The app may not work properly and we will not provide support for it. ****\n'
+PATH=("${@:2}")
+/usr/bin/find "${PATH[@]}" "${MAXDEPTH[@]}" ! -xtype l \( ! -group "${GROUP}" -o ! -user "${USER}" \) -exec chown "${OPTIONS[@]}" "${USER}":"${GROUP}" {} + || printf "${ERROR}"
diff --git a/deepin-webtop/beige/root/usr/local/bin/svc-pulseaudio b/deepin-webtop/beige/root/usr/local/bin/svc-pulseaudio
new file mode 100755
index 0000000..aae6e7c
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/bin/svc-pulseaudio
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+
+set -x
+
+exec /usr/bin/pulseaudio \
+ --log-level=0 \
+ --log-target=stderr \
+ --exit-idle-time=-1 > /dev/null 2>&1
diff --git a/deepin-webtop/beige/root/usr/local/etc/kasmvnc/kasmvnc.yaml b/deepin-webtop/beige/root/usr/local/etc/kasmvnc/kasmvnc.yaml
new file mode 100644
index 0000000..b16a15c
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/etc/kasmvnc/kasmvnc.yaml
@@ -0,0 +1,22 @@
+network:
+ protocol: http
+ interface: 0.0.0.0
+ websocket_port: 6901
+ use_ipv4: true
+ use_ipv6: true
+ udp:
+ public_ip: auto
+ port: auto
+ stun_server: auto
+ ssl:
+ pem_certificate: /config/ssl/cert.pem
+ pem_key: /config/ssl/cert.key
+ require_ssl: false
+
+logging:
+ log_writer_name: all
+ log_dest: logfile
+ level: 1
+
+command_line:
+ prompt: false
\ No newline at end of file
diff --git a/deepin-webtop/beige/root/usr/local/etc/kasmvnc/systemd/system/multi-user.target.wants/kasminit.service b/deepin-webtop/beige/root/usr/local/etc/kasmvnc/systemd/system/multi-user.target.wants/kasminit.service
new file mode 120000
index 0000000..c6a1c3b
--- /dev/null
+++ b/deepin-webtop/beige/root/usr/local/etc/kasmvnc/systemd/system/multi-user.target.wants/kasminit.service
@@ -0,0 +1 @@
+../kasminit.service
\ No newline at end of file