feat: Add Webtop container configuration and setup scripts

This commit is contained in:
2026-02-22 20:38:58 -05:00
parent c5d557ba2d
commit d802c80053
5 changed files with 201 additions and 0 deletions

26
webtop/RESEARCH.md Normal file
View File

@@ -0,0 +1,26 @@
# Remote Desktop / Browser Isolation Research: Webtop
## Conclusion
`linuxserver/webtop` is the recommended solution for providing a persistent, lightweight Linux desktop environment accessible directly through a web browser on a Synology NAS.
## Comparison Summary
### 1. `linuxserver/webtop`
* **Architecture**: A Docker container that runs a full Linux desktop environment (like Ubuntu with XFCE) and streams the display to the browser using KasmVNC technology.
* **Best For**: A persistent personal cloud desktop. It acts just like a regular computer; you log in, open apps, leave them running, and come back later.
* **Resource Usage**: Very lightweight compared to a full Virtual Machine, as it shares the NAS's Linux kernel.
* **Key Features**: Pixel-perfect rendering, audio support, clipboard integration, and you can easily install standard Linux applications (LibreOffice, VS Code, Firefox) inside of it.
### 2. Kasm Workspaces
* **Architecture**: An enterprise orchestration platform that spins up isolated Docker containers dynamically.
* **Best For**: Disposable, temporary sessions. You request a desktop, do your work securely, and when you are done, the container is destroyed entirely.
* **Pros/Cons**: Excellent for extreme security (zero-trust, anti-malware sandboxing) and multi-user scaling, but overkill for a simple personal persistent desktop. (Note: Webtop uses Kasm's display technology under the hood).
### 3. Apache Guacamole
* **Architecture**: A clientless remote desktop gateway.
* **Best For**: Connecting to *existing* physical machines or fully-virtualized VMs (via RDP, SSH, or VNC) over the web.
* **Pros/Cons**: Guacamole is just the viewing portal; it does not contain an operating system itself. You would need to run a separate heavy VM on the Synology NAS to connect to it. Webtop incorporates the OS directly into the container.
### 4. Standard Virtual Machines (Synology VMM)
* **Architecture**: Hardware-level virtualization allocating dedicated RAM, CPU threads, and virtual disks to a guest OS.
* **Pros/Cons**: While powerful, it requires high RAM utilization and takes minutes to boot. Webtop boots in seconds and only uses RAM when processes are actively running.

43
webtop/SETUP.md Normal file
View File

@@ -0,0 +1,43 @@
# Service Setup Guide: Webtop
Webtop provides a full Linux desktop environment (Ubuntu XFCE) directly in your web browser.
## 1. Pre-Setup (Manual)
### Create Service User
- [ ] **Manual**: Create a local user named `svc-webtop` in Synology DSM (Control Panel > User & Group).
- [ ] **Manual**: Give this user read/write access to the `docker` shared folder.
### Get User IDs
- [ ] **Manual**: SSH into your NAS and run `sudo synouser --get svc-webtop`.
- [ ] **Confirmed IDs**: Locate the `User ID` (PUID) and `Group ID` (PGID).
- [ ] **Action**: Open `create_webtop_folders.sh` and update the `USER_ID="[PUID]:[PGID]"` line.
- [ ] **Action**: Open `stack.env` and update the `PUID` and `PGID` variables.
## 2. Infrastructure Setup
### Run Setup Script
- [ ] **Action**: Run the setup script in Dry-Run mode to verify changes:
```bash
sudo bash create_webtop_folders.sh
```
- [ ] **Action**: Apply the folder creation and ownership settings:
```bash
sudo bash create_webtop_folders.sh --run
```
- **What it does**:
- Creates `/volume1/docker/webtop/config` which acts as the persistent home directory (`/config`) for your virtual desktop.
- Sets ownership securely to the `svc-webtop` user so the container process can write to it.
## 3. Portainer Deployment
### Environment Variables
- [ ] **Action**: Review `stack.env`. You can customize the browser tab name by editing `TITLE`.
### Deploy Stack
- [ ] **Action**: Create a new stack named `webtop-stack`.
- [ ] **Action**: Upload or paste the environment variables from `stack.env`.
- [ ] **Action**: Paste the content of `docker-compose.portainer.yml` and deploy.
- [ ] **Verification**: Access the Webtop desktop interface at `http://[NAS_IP]:3000`.
## 4. Post-Setup Notes
1. **Persistent Data**: Everything saved strictly within the virtual `~` or `/config` directory is retained. If you want to access your real NAS files (like your ebooks or movies) from inside this desktop, you can uncomment and map `/volume1/media` in the `docker-compose.portainer.yml` file.
2. **Security Opt**: The `seccomp:unconfined` flag is enabled. This is required to run multi-process modern browsers (like Google Chrome or Firefox) natively *inside* the container without crashing.
3. **Execution User**: Unlike some custom containers, Linuxserver.io images (like Webtop) handle user switching natively inside the container. Do not forcefully apply the `user:` directive in Docker Compose, as it will break the container's boot process which relies on root purely to set permissions before downgrading to the PUID/PGID.

View File

@@ -0,0 +1,94 @@
#!/bin/bash
# Default to dry-run mode
DRY_RUN=true
if [[ "$1" == "--run" || "$1" == "-r" ]]; then DRY_RUN=false; fi
if [ "$DRY_RUN" = "true" ]; then
echo "--- DRY RUN MODE ---"
echo "To apply changes, run: sudo bash $0 --run"
echo "--------------------"
fi
# Configuration
BASE="/volume1/docker/webtop"
# Replace with your actual Synology PUID/PGID for the svc-webtop user
USER_ID="1046:65538" # svc-webtop
# Helper functions
run_mkdir() {
local path=$1
if [ -d "$path" ]; then
echo "[OK] Folder exists, no changes will be made: $path"
else
if [ "$DRY_RUN" = "true" ]; then
echo "[WILL CREATE] Folder: $path"
else
echo "[EXECUTE] Creating folder: $path"
mkdir -p "$path"
fi
fi
}
run_chown_recursive() {
local owner=$1; local path=$2
local uid=${owner%%:*}; local gid=${owner#*:}
# Check if folder exists first
if [ ! -d "$path" ]; then
if [ "$DRY_RUN" = "true" ]; then
echo "[WILL SET] Owner to $owner upon creation: $path"
else
echo "[EXECUTE] Setting owner to $owner (recursive): $path"
chown -R "$owner" "$path"
fi
return
fi
# Check if any file/folder inside diverges from the target ownership
if find "$path" \( ! -uid "$uid" -o ! -gid "$gid" \) | grep -q .; then
if [ "$DRY_RUN" = "true" ]; then
echo "[WILL CHANGE] Owner to $owner (recursive): $path"
else
echo "[EXECUTE] Setting owner to $owner (recursive): $path"
chown -R "$owner" "$path"
fi
else
echo "[OK] Owner is $owner, no changes will be made: $path"
fi
}
run_chmod_recursive() {
local mode=$1; local path=$2
# Check if folder exists first
if [ ! -d "$path" ]; then
if [ "$DRY_RUN" = "true" ]; then
echo "[WILL SET] Permissions to $mode upon creation: $path"
else
echo "[EXECUTE] Setting permissions to $mode (recursive): $path"
chmod -R "$mode" "$path"
fi
return
fi
# Check if any file/folder inside diverges from the target permissions
if find "$path" ! -perm -"$mode" | grep -q .; then
if [ "$DRY_RUN" = "true" ]; then
echo "[WILL CHANGE] Permissions to $mode (recursive): $path"
else
echo "[EXECUTE] Setting permissions to $mode (recursive): $path"
chmod -R "$mode" "$path"
fi
else
echo "[OK] Permissions are $mode, no changes will be made: $path"
fi
}
# Run tasks
run_mkdir "${BASE}/config"
run_chown_recursive "$USER_ID" "${BASE}"
run_chmod_recursive 750 "${BASE}"
if [ "$DRY_RUN" = "false" ]; then
echo "Done."
fi

View File

@@ -0,0 +1,29 @@
version: '3.8'
services:
webtop:
# Using the Ubuntu base with XFCE desktop environment for a great balance of features and low resource usage
image: lscr.io/linuxserver/webtop:ubuntu-xfce
container_name: webtop
restart: always
# Note on Root Exception: Linuxserver.io images require root privileges at boot to run s6-overlay
# initialization scripts (like setting folder permissions). They internally drop privileges
# down to the ${PUID} and ${PGID} provided in the environment section to run the actual application.
# Therefore, we do NOT use the `user:` directive here.
security_opt:
- seccomp:unconfined # Required for some internal applications (e.g. Chrome inside the container) to function properly
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
- TITLE=${TITLE:-Webtop}
volumes:
# Maps the virtual desktop's /config (home directory) to persistent NAS storage
- /volume1/docker/webtop/config:/config:rw
# Optional: You can mount media folders here so you can access your NAS files from inside the virtual desktop
# - /volume1/media:/media:rw
ports:
- "3000:3000" # HTTP Access
# - "3001:3001" # HTTPS Access (Optional, usually handled by a reverse proxy instead)
# shm_size is important for web browsers (like Chrome/Firefox) running inside the container to prevent crashing
shm_size: "1gb"

9
webtop/stack.env Normal file
View File

@@ -0,0 +1,9 @@
# Synology Execution User
# Change these to match the svc-webtop user IDs
PUID=1046
PGID=65538
TZ=America/Toronto
# Webtop Customization
# The text that appears on the browser tab
TITLE=Personal Cloud Desktop