Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,57 @@ jobs:
DEBIAN_SECURITY_MIRROR=${{ env.DEBIAN_SECURITY_MIRROR }}
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}

build-desktop:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- stack: desktop
version: kde-focal
permissions:
contents: read
packages: write
env:
STACK: ${{ matrix.stack }}
VERSION: ${{ matrix.version }}
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ matrix.stack }}
tags: |
type=raw,value=${{ matrix.version }}
type=raw,value=${{ matrix.version }}-${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/heads/') && github.ref != 'refs/heads/main' }}
type=ref,event=tag
type=raw,value=${{ matrix.version }}-${{ github.ref_name }},enable=${{ startsWith(github.ref, 'refs/tags/') }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
if: github.event_name == 'push'
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build (no push on PR)
uses: docker/build-push-action@v5
with:
context: .
file: docker/${{ matrix.stack }}/${{ matrix.version }}/Dockerfile
platforms: linux/amd64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}

build-stacks:
needs: build-base
runs-on: ubuntu-latest
Expand Down
96 changes: 96 additions & 0 deletions docker/desktop/kde-focal/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
FROM ubuntu:focal

ARG S6_VER="2.0.0.1"
ARG NO_VNC_VER="1.1.0"
ARG WEB_SOCK_VER="0.9.0"

RUN mkdir /_install

## S6 Overlay
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_VER}/s6-overlay-amd64.tar.gz /_install
RUN tar xzf /_install/s6-overlay-amd64.tar.gz -C / --exclude="./bin" && \
tar xzf /_install/s6-overlay-amd64.tar.gz -C /usr ./bin
ENTRYPOINT ["/init"]


## KDE
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update && \
apt upgrade -y && \
apt install -y plasma-desktop
RUN apt install -y dbus-x11


## Other Applications
RUN apt install -y dolphin konsole screen

## Google Chrome
RUN apt install -y wget gnupg2 && \
wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - && \
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list && \
apt update && \
apt install -y google-chrome-stable && \
sed -i 's|Exec=/usr/bin/google-chrome-stable|Exec=/usr/bin/google-chrome-stable --no-sandbox|g' /usr/share/applications/google-chrome.desktop && \
update-alternatives --set x-www-browser /usr/bin/google-chrome-stable && \
update-alternatives --set gnome-www-browser /usr/bin/google-chrome-stable


## VNC
RUN apt install -y tigervnc-standalone-server tigervnc-xorg-extension
ENV DISPLAY=:0 \
SCR_WIDTH=1920 \
SCR_HEIGHT=1080
EXPOSE 5900


## NOVNC
ADD https://github.com/novnc/noVNC/archive/v${NO_VNC_VER}.zip /_install
ADD https://github.com/novnc/websockify/archive/v${WEB_SOCK_VER}.zip /_install
RUN cd /_install && \
apt install -y unzip python3 python3-pip nginx gettext-base vim && \
ln -s /usr/bin/python3 /usr/bin/python && \
pip3 install numpy && \
unzip v${NO_VNC_VER}.zip && \
unzip v${WEB_SOCK_VER}.zip && \
mv noVNC-${NO_VNC_VER} /novnc && \
mv websockify-${WEB_SOCK_VER} /novnc/utils/websockify
EXPOSE 8080
ENV PATH_PREFIX=/ \
VNC_RESIZE=scale \
RECON_DELAY=250 \
PAGE_TITLE=KDE


## Browser Harness (for AI agent browser control)
RUN apt install -y git curl && \
curl -LsSf https://astral.sh/uv/install.sh | sh && \
export PATH="/root/.local/bin:$PATH" && \
git clone https://github.com/browser-use/browser-harness /opt/browser-harness && \
cd /opt/browser-harness && \
uv tool install -e . && \
ln -sf /root/.local/bin/browser-harness /usr/local/bin/browser-harness
ENV BU_CDP_URL=http://127.0.0.1:9222 \
PATH="/root/.local/bin:${PATH}"


## USER
ENV PGID=0 \
PUID=0 \
ROOT_PASSWORD=password \
HOME=/config
RUN useradd -U -u 6006 -d "$HOME" kid && \
usermod -G users kid
WORKDIR /


## All Dependencies Satisfied
# RUN yes | unminimize
COPY docker/desktop/kde-focal/_root /
COPY docker/desktop/kde-focal/focal/root /


# Cleanup
RUN apt autoremove -y && \
apt clean && \
rm -r /_install

24 changes: 24 additions & 0 deletions docker/desktop/kde-focal/_root/etc/cont-init.d/00--init-user.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

groupmod -o -g "$PGID" kid
usermod -o -u "$PUID" kid
echo "kid:$ROOT_PASSWORD" | chpasswd
echo "root:$ROOT_PASSWORD" | chpasswd


# Link /root -> $HOME
# for compatibility reasons
if [[ "$PGID" -eq 0 ]] && [[ "$PUID" -eq 0 ]]
then
if [[ ! -e "$HOME" ]]
then
ln -s /root "$HOME"
fi
else
mkdir -p "$HOME"
fi

chown kid:kid "$HOME"
8 changes: 8 additions & 0 deletions docker/desktop/kde-focal/_root/etc/cont-init.d/00-desktop.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-setuidgid kid mkdir -p "$HOME/Desktop"
mkdir -p /misc/desktop
mv /misc/desktop/* "$HOME/Desktop"
18 changes: 18 additions & 0 deletions docker/desktop/kde-focal/_root/etc/cont-init.d/00-envsubst.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

if [ "$PATH_PREFIX" = "/" ]
then
export SOCKET_PREFIX=""
else
export SOCKET_PREFIX="$PATH_PREFIX"
fi

TEMP="$(envsubst '${PATH_PREFIX},${SOCKET_PREFIX}' < /etc/nginx/nginx.conf)"
echo "$TEMP" > /etc/nginx/nginx.conf

export PAGE_PREFIX="${SOCKET_PREFIX:1}/"
TEMP="$(envsubst '${PAGE_PREFIX},${PAGE_TITLE},${RECON_DELAY},${VNC_RESIZE}' < /novnc/index.html)"
echo "$TEMP" > /novnc/index.html
33 changes: 33 additions & 0 deletions docker/desktop/kde-focal/_root/etc/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
daemon off;

events { }

http {

gzip on;
include /etc/nginx/mime.types;
default_type application/octet-stream;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 61s;
proxy_buffering off;

upstream vnc_proxy {
server 127.0.0.1:6080;
}

server {
listen 8080;
location ${SOCKET_PREFIX}/websockify {
proxy_pass http://vnc_proxy/;
}
location ${PATH_PREFIX} {
alias /novnc/;
index index.html;
try_files $uri $uri/ =404;
}
}

}
16 changes: 16 additions & 0 deletions docker/desktop/kde-focal/_root/etc/services.d/chrome/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-svwait /var/run/s6/services/kde

sleep 3

exec s6-setuidgid kid /usr/bin/google-chrome-stable \
--no-sandbox \
--remote-debugging-port=9222 \
--user-data-dir=/config/.chrome-debug-profile \
--no-first-run \
--window-position=0,0 \
--window-size=1920,1080
10 changes: 10 additions & 0 deletions docker/desktop/kde-focal/_root/etc/services.d/nginx/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-svwait /var/run/s6/services/novnc


exec /usr/sbin/nginx

10 changes: 10 additions & 0 deletions docker/desktop/kde-focal/_root/etc/services.d/novnc/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-svwait /var/run/s6/services/tigervnc


exec s6-setuidgid kid /novnc/utils/launch.sh

7 changes: 7 additions & 0 deletions docker/desktop/kde-focal/_root/etc/services.d/tigervnc/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

exec s6-setuidgid kid /usr/bin/Xvnc "$DISPLAY" -geometry "$SCR_WIDTH"x"$SCR_HEIGHT" -depth 24 -SecurityTypes none -AlwaysShared

10 changes: 10 additions & 0 deletions docker/desktop/kde-focal/_root/etc/services.d/vncconfig/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-svwait /var/run/s6/services/tigervnc


exec s6-setuidgid kid vncconfig -nowin

26 changes: 26 additions & 0 deletions docker/desktop/kde-focal/_root/novnc/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!doctype html>

<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>${PAGE_TITLE}</title>
<style>
body {
padding: 0;
margin: 0;
}
iframe {
width: 100vw;
height: 100vh;
border: none;
}
</style>
</head>

<body>
<iframe
src="vnc.html?path=${PAGE_PREFIX}websockify&resize=${VNC_RESIZE}&autoconnect=true&reconnect=true&reconnect_delay=${RECON_DELAY}">
</iframe>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

cat /usr/share/applications/org.kde.dolphin.desktop > "$HOME/Desktop/dolphin.desktop"
cat /usr/share/applications/org.kde.konsole.desktop > "$HOME/Desktop/konsole.desktop"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-setuidgid kid mkdir -p "$HOME/.config"
s6-setuidgid kid mv /misc/kscreenlockerrc "$HOME/.config/kscreenlockerrc"
9 changes: 9 additions & 0 deletions docker/desktop/kde-focal/focal/root/etc/services.d/kde/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bash

set -eu
set -o pipefail

s6-svwait /var/run/s6/services/tigervnc


exec s6-setuidgid kid /usr/bin/startplasma-x11
6 changes: 6 additions & 0 deletions docker/desktop/kde-focal/focal/root/misc/kscreenlockerrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[$Version]
update_info=kscreenlocker.upd:0.1-autolock

[Daemon]
Autolock=false
LockOnResume=false
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/with-contenv bash

echo FAKE start_kdeinit_wrapper FAKE
Loading