2026-01-07 02:35:12 +09:00
2026-01-07 02:35:12 +09:00
2026-01-07 02:35:12 +09:00
2026-01-07 02:35:12 +09:00
2025-12-27 02:26:27 +09:00
2026-01-07 02:35:12 +09:00
2026-01-07 02:35:12 +09:00
2026-01-07 02:35:12 +09:00
2025-12-27 02:18:22 +09:00

devcontainer-ubuntu-kde-selkies-for-mac

日本語版 (README.md)

A containerized Kubuntu (KDE Plasma) desktop environment accessible via browser. Uses Selkies WebRTC streaming to provide a fully functional Linux desktop without VNC/RDP.


Quick Start

# 1. Build base image (first time only, 30-60 minutes)
./build-base-image.sh                         # Ubuntu 24.04 (default)
./build-base-image.sh -u 22.04                # Ubuntu 22.04

# 2. Build user image (1-2 minutes)
USER_PASSWORD=yourpassword ./build-user-image.sh              # English environment
USER_PASSWORD=yourpassword ./build-user-image.sh -l ja        # Japanese environment
USER_PASSWORD=yourpassword ./build-user-image.sh -u 22.04     # Ubuntu 22.04

# 3. Start container
./start-container.sh                                          # Software rendering
./start-container.sh --gpu nvidia --all                       # NVIDIA GPU (all GPUs)
./start-container.sh --gpu nvidia --num 0                     # NVIDIA GPU (GPU 0 only)
./start-container.sh --gpu intel                              # Intel GPU
./start-container.sh --gpu amd                                # AMD GPU
./start-container.sh --gpu nvidia-wsl --all                   # WSL2 + NVIDIA

# 4. Access via browser
# → https://localhost:<10000+UID> (e.g., UID=1000 → https://localhost:11000)
# → http://localhost:<20000+UID>  (e.g., UID=1000 → http://localhost:21000)

# 5. Save your changes (IMPORTANT! Always do this before removing container)
./commit-container.sh

# 6. Stop
./stop-container.sh                    # Stop (container persists, can restart)
./stop-container.sh --rm               # Stop and remove (only after commit!)

That's it! 🎉

Using VS Code Dev Container

# 1. Generate Dev Container configuration
./create-devcontainer-config.sh

# 2. Open in VS Code
# In VS Code, press "F1" → select "Dev Containers: Reopen in Container"

# 3. The workspace will automatically open inside the container
# Access the desktop via browser at https://localhost:<displayed-port>

🚀 Key Improvements in This Project

Architecture Improvements

  • 🏗️ Two-Stage Build System: Split into base (5-10 GB) and user images (~100 MB, 1-2 min build)

    • Base image contains all system packages and desktop environment
    • User image adds your specific user with matching UID/GID
    • No more 30-60 minute builds for every user!
  • 🔒 Non-Root Container Execution: Containers run with user privileges by default

    • Removed all fakeroot hacks and privilege escalation workarounds
    • Proper permission separation between system and user operations
    • Sudo access available when needed for specific operations
  • 📁 Automatic UID/GID Matching: File permissions work seamlessly

    • User image matches your host UID/GID automatically
    • Mounted host directories have correct ownership
    • No more "permission denied" errors on shared folders

User Experience Enhancements

  • 🔐 Secure Password Management: Environment variable for password input

    • No plain text passwords in commands
    • Passwords stored securely in the image
  • 💻 Ubuntu Desktop Standard Environment: Full .bashrc configuration

    • Colored prompt with Git branch detection
    • History optimization (ignoredups, append mode, timestamps)
    • Useful aliases (ll, la, grep colors, etc.)
  • 🎮 Flexible GPU Selection: Clear command arguments

    • --all - Use all available GPUs
    • --num 0,1 - Specific GPU devices
    • --gpu none - Software rendering

Developer Experience

  • 📦 Version Pinning: Reproducible builds guaranteed

    • VirtualGL 3.1.4, Selkies 1.6.2
    • No more "it worked yesterday" issues
  • 🛠️ Complete Management Scripts: Shell scripts for all operations

    • build-user-image.sh - Build with password
    • start-container.sh [--gpu <type>] - Start with GPU selection
    • stop/shell-container.sh - Lifecycle management
    • commit-container.sh - Save your changes
  • 🌐 Multi-Language Support: Japanese language environment available

    • Pass -l ja argument during build for Japanese input (Mozc)
    • Automatic timezone (Asia/Tokyo) and locale (ja_JP.UTF-8) configuration
    • fcitx input method framework included
    • English remains the default

Why This Project?

Original Projects This Project
Pull-ready image Local build (1-2 min)
Root container User-privilege container
Manual UID/GID setup Automatic matching
Password in command Environment variable
Generic bash Ubuntu Desktop bash
GPU auto-detected GPU explicitly selected
Version drift Version pinned
English only Multi-language (EN/JP)

Table of Contents


System Requirements

Required

  • Docker 20.10 or later (Docker Desktop 4.0+)
  • 8GB+ RAM (16GB recommended)
  • 20GB+ free disk space

GPU (Optional, for hardware acceleration)

  • NVIDIA GPU Tested
    • Driver version 470 or later
    • Maxwell generation or newer
    • NVIDIA Container Toolkit installed
  • Intel GPU Tested
    • Intel integrated graphics (HD Graphics, Iris, Arc)
    • Quick Sync Video support
    • VA-API drivers included in container
    • Host setup required (see below)
  • AMD GPU ⚠️ Partially Tested
    • Radeon graphics with VCE/VCN encoder
    • VA-API drivers included in container
    • Host setup required (see below)

Platform Support

Environment GPU Rendering WebGL/Vulkan Hardware Encoding Notes
Linux + NVIDIA GPU Full Native NVENC Best performance
Linux + Intel GPU Full Native VA-API (QSV) Integrated GPU OK
Linux + AMD GPU Full Native VA-API RDNA/GCN supported
WSL2 + NVIDIA GPU Supported Supported NVENC Windows integration
macOS (Docker) Not supported Software only Not supported VM limitation

Two-Stage Build System

This project uses a two-stage build approach for fast setup and proper file permissions:

┌─────────────────────────┐
│   Base Image (5-10 GB)  │  ← Build once (30-60 minutes)
│  • All system packages  │
│  • Desktop environment  │
│  • Pre-installed apps   │
└────────────┬────────────┘
             │
             ↓ builds from
┌────────────┴────────────┐
│ User Image (~100 MB)    │  ← You build this (1-2 minutes)
│  • Your username        │
│  • Your UID/GID         │
│  • Your password        │
└─────────────────────────┘

Benefits:

  • Fast Setup: No 30-60 minute build wait
  • Proper Permissions: Files match your host UID/GID
  • Easy Updates: Build new base image, rebuild user image

Why UID/GID Matching Matters:

  • When you mount host directories (like $HOME), files need matching ownership
  • Without matching UID/GID, you get permission errors
  • The user image automatically matches your host credentials

Intel/AMD GPU Host Setup

If you plan to use hardware encoding (VA-API) with Intel or AMD GPUs, host-side setup is required:

1. Add User to video/render Groups

For the container to access GPU devices (/dev/dri/*), the host user must be a member of the video and render groups:

# Add user to video/render groups
sudo usermod -aG video,render $USER

# Logout and re-login or reboot to apply group changes
# Verify:
groups
# Confirm output includes "video" and "render"

2. Install VA-API Drivers (Intel)

For Intel GPU hardware encoding:

# Install VA-API tools and Intel driver
sudo apt update
sudo apt install vainfo intel-media-va-driver-non-free

# Verify installation (check for H.264 encoding support):
vainfo
# Confirm output includes "VAProfileH264Main : VAEntrypointEncSlice" etc.

3. Install VA-API Drivers (AMD)

For AMD GPU hardware encoding:

# Install VA-API tools and AMD driver
sudo apt update
sudo apt install vainfo mesa-va-drivers

# Verify installation:
vainfo
# Confirm output includes "VAProfileH264Main : VAEntrypointEncSlice" etc.

Notes:

  • NVIDIA GPUs do not require this setup
  • If VA-API works correctly on the host, it will automatically work in the container
  • Always logout/re-login or reboot after group changes

Installation

1. Build Base Image

The base image only needs to be built once (30-60 minutes):

# Auto-detect host architecture
./build-base-image.sh                         # Ubuntu 24.04 (default)
./build-base-image.sh -u 22.04                # Ubuntu 22.04

# Or specify explicitly
./build-base-image.sh -a amd64                # Intel/AMD 64-bit
./build-base-image.sh -a arm64                # Apple Silicon / ARM
./build-base-image.sh -a amd64 -u 22.04       # AMD64 + Ubuntu 22.04

# Build without cache (if having issues)
./build-base-image.sh --no-cache

2. Build User Image

Create your personal image with matching UID/GID (1-2 minutes):

# English (default)
USER_PASSWORD=yourpassword ./build-user-image.sh

# Japanese
USER_PASSWORD=yourpassword ./build-user-image.sh -l ja

Optional: Customization

# Use Ubuntu 22.04
USER_PASSWORD=yourpassword ./build-user-image.sh -u 22.04

# Different version
USER_PASSWORD=yourpassword ./build-user-image.sh -v 2.0.0

# Use a different base image
USER_PASSWORD=yourpassword ./build-user-image.sh -b my-custom-base:1.0.0

Usage

Starting the Container

The start-container.sh script uses GPU and optional arguments:

# Syntax: ./start-container.sh [--gpu <type>] [options]
# Default: Software rendering if no options specified

# NVIDIA GPU options:
./start-container.sh --gpu nvidia --all              # Use all available NVIDIA GPUs
./start-container.sh --gpu nvidia --num 0            # Use NVIDIA GPU 0 only
./start-container.sh --gpu nvidia --num 0,1          # Use NVIDIA GPU 0 and 1

# Intel/AMD GPU options:
./start-container.sh --gpu intel                     # Use Intel integrated GPU (Quick Sync Video)
./start-container.sh --gpu amd                       # Use AMD GPU (VCE/VCN)

# WSL2 NVIDIA:
./start-container.sh --gpu nvidia-wsl --all          # NVIDIA GPU on WSL2

# Software rendering:
./start-container.sh                                 # No GPU (default)
./start-container.sh --gpu none                      # Explicitly specify no GPU

# Resolution and DPI:
./start-container.sh --gpu nvidia --all -r 3840x2160 -d 192    # 4K HiDPI
./start-container.sh -r 2560x1440 -d 144                       # WQHD

UID-Based Port Assignment (Multi-User Support):

Ports are automatically assigned based on your user ID to enable multiple users on the same host:

  • HTTPS Port: 10000 + UID (e.g., UID 1000 → port 11000)
  • HTTP Port: 20000 + UID (e.g., UID 1000 → port 21000)
  • TURN Port: 3000 + UID (e.g., UID 1000 → port 4000)

Access via: https://localhost:${HTTPS_PORT} (e.g., https://localhost:11000 for UID 1000)

Remote Access (LAN/WAN):

TURN server is enabled by default for remote access without additional options:

  • TURN server relays WebRTC connections
  • Auto-detects LAN IP address
  • Access from remote PC: https://<host-ip>:<https-port>

Container Features:

  • Container persistence: Not removed when stopped (can restart or commit)
  • Hostname: Set to Docker-$(hostname)
  • Host home mount: Available at ~/host_home
  • Container name: linuxserver-kde-{username}

Saving Changes (Important!)

If you've installed software or made changes:

# Save container state to image
./commit-container.sh

Important Notes:

  • ⚠️ Always commit before ./stop-container.sh --rm - Changes are lost if you remove without committing
  • The image name format is webtop-kde-{username}-{arch}:{version}
  • Committed images persist even after container deletion
  • Next startup automatically uses the committed image

Workflow Example:

# 1. Work in container, install software, configure settings
./shell-container.sh
# ... install packages, configure environment ...
exit

# 2. Save your changes to the image
./commit-container.sh

# 3. Stop and remove container safely (changes are saved in image)
./stop-container.sh --rm

# 4. Next startup uses the committed image with all your changes
./start-container.sh --gpu intel

Stopping the Container

# Stop (persists for restart or commit)
./stop-container.sh

# Stop and remove
./stop-container.sh --rm
# or
./stop-container.sh -r

Scripts Reference

Core Scripts

Script Description Usage
build-base-image.sh Build the base image ./build-base-image.sh [-a arch]
build-user-image.sh Build user-specific image USER_PASSWORD=xxx ./build-user-image.sh [-l ja]
start-container.sh Start the desktop container ./start-container.sh [--gpu <type>]
stop-container.sh Stop the container ./stop-container.sh [--rm]

Management Scripts

Script Description Usage
shell-container.sh Access container shell ./shell-container.sh
commit-container.sh Save container changes to image ./commit-container.sh

GPU Options Details

./start-container.sh [options]

GPU Selection:
  -g, --gpu <vendor>    GPU vendor: none|nvidia|nvidia-wsl|intel|amd
  --all                 Use all GPUs (for nvidia/nvidia-wsl)
  --num <list>          Comma-separated GPU list (for nvidia, not supported on WSL)

GPU Examples:
  --gpu nvidia --all          # NVIDIA GPU - all available
  --gpu nvidia --num 0,1      # NVIDIA GPU - specific GPUs
  --gpu nvidia-wsl --all      # NVIDIA on WSL2
  --gpu intel                 # Intel integrated/discrete GPU (VA-API)
  --gpu amd                   # AMD GPU (VA-API + ROCm if available)
  --gpu none                  # Software rendering only

Other Options:
  -n <name>             Container name
  -r <WxH>              Resolution (e.g., 1920x1080)
  -d <dpi>              DPI (e.g., 96, 144, 192)
  -s <ssl_dir>          SSL certificate directory

Configuration

Display Settings

# Resolution and DPI
./start-container.sh -r 1920x1080 -d 96              # Standard
./start-container.sh -r 2560x1440 -d 144             # WQHD HiDPI
./start-container.sh -r 3840x2160 -d 192             # 4K HiDPI

Video Encoding

Available Encoders:

Encoder GPU Quality CPU Load
nvh264enc NVIDIA NVENC High Low
vah264enc Intel/AMD VA-API High Low
x264enc Software Medium High

Encoder is automatically selected based on --gpu option.

Audio Settings

Audio Support:

Feature Support Technology
Speaker output Built-in WebRTC (browser native)
Microphone input Built-in WebRTC (browser native)

Selkies streams bidirectional audio to the browser via WebRTC.


HTTPS/SSL

SSL Certificate Setup

# 1. Create ssl/ directory
mkdir -p ssl

# 2. Place certificates
cp /path/to/your/cert.pem ssl/
cp /path/to/your/key.pem ssl/cert.key

# 3. Start container (auto-detects ssl/ folder)
./start-container.sh --gpu nvidia --all

Self-Signed Certificate Generation

openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout ssl/cert.key -out ssl/cert.pem \
  -subj "/C=US/ST=State/L=City/O=Dev/CN=localhost"

Certificate Priority

The start-container.sh script auto-detects certificates in this order:

  1. ssl/cert.pem and ssl/cert.key
  2. Environment variable SSL_DIR
  3. Uses image default certificate if none found

Troubleshooting

Container Won't Start

# Check logs
docker logs linuxserver-kde-$(whoami)

# Check if image exists
docker images | grep webtop-kde

# Rebuild user image
USER_PASSWORD=yourpassword ./build-user-image.sh

# Check if port is in use
sudo netstat -tulpn | grep -E "11000|21000"

GPU Not Detected

# NVIDIA
./shell-container.sh
nvidia-smi

# Intel/AMD
./shell-container.sh
ls -la /dev/dri/
vainfo

# Check Docker GPU access
docker run --rm --gpus all nvidia/cuda:11.0-base nvidia-smi

Permission Issues

# Check UID match
id  # on host
./shell-container.sh
id  # inside container

# If UID/GID mismatch, rebuild user image
USER_PASSWORD=yourpassword ./build-user-image.sh

Black Screen / Desktop Not Showing

# Check logs
docker logs linuxserver-kde-$(whoami)

# Check plasmashell status
docker exec linuxserver-kde-$(whoami) pgrep -af plasmashell

# Check runtime directory
docker exec linuxserver-kde-$(whoami) ls -la /run/user/$(id -u)

Causes and Solutions:

  • /run/user/<uid> doesn't exist / wrong permissions → Restart container
  • plasmashell crashed → Restart container

WebGL/Vulkan Not Working

# OpenGL info
docker exec linuxserver-kde-$(whoami) glxinfo | head -30

# Vulkan info
docker exec linuxserver-kde-$(whoami) vulkaninfo | head -50

For macOS: Due to Docker VM limitations, GPU acceleration is not available. Works with software rendering.

No Audio

# Check PulseAudio server
docker exec linuxserver-kde-$(whoami) pactl info

# List sinks
docker exec linuxserver-kde-$(whoami) pactl list sinks short

Solutions:

  • Check browser audio permissions
  • Use HTTPS connection (some browsers block audio over HTTP)

Known Limitations

Vulkan Limitation

  • Xvfb does not support DRI3, so Vulkan applications cannot present frames
  • VirtualGL-based OpenGL applications work normally

macOS Limitation

  • Docker Desktop for Mac runs containers inside a Linux VM, so Apple GPU (Metal) access is not possible
  • WebGL/Vulkan runs via software rendering (llvmpipe)
  • Use Linux native or WSL2 if hardware acceleration is needed

WSL2 Intel/AMD GPU Limitation

  • WSL2 Intel/AMD GPUs do not support VA-API
  • Only NVIDIA GPUs are fully supported on WSL2

Advanced Topics

Environment Variables Reference

Click to expand environment variables list

Container Settings

Variable Description Default
CONTAINER_NAME Container name linuxserver-kde-$(whoami)
IMAGE_BASE Image base name webtop-kde
IMAGE_VERSION Image version 1.0.0

Display

Variable Description Default
RESOLUTION Resolution 1920x1080
DPI DPI setting 96

GPU

Variable Description Default
GPU_VENDOR GPU vendor none

Network

Variable Description Default
PORT_SSL_OVERRIDE HTTPS port override UID+10000
PORT_HTTP_OVERRIDE HTTP port override UID+20000
PORT_TURN_OVERRIDE TURN port override UID+3000
HOST_IP Host IP for TURN server Auto-detect

Project Structure

devcontainer-ubuntu-kde-selkies-for-mac/
├── build-base-image.sh           # Build base image
├── build-user-image.sh           # Build user image
├── start-container.sh            # Start container
├── stop-container.sh             # Stop container
├── shell-container.sh            # Shell access
├── commit-container.sh           # Save changes
├── ssl/                          # SSL certificates (auto-detected)
│   ├── cert.pem
│   └── cert.key
└── files/                        # System files
    ├── linuxserver-kde.base.dockerfile   # Base image definition
    ├── linuxserver-kde.user.dockerfile   # User image definition
    ├── alpine-root/              # s6-overlay configuration
    ├── kde-root/                 # KDE configuration
    └── ubuntu-root/              # Ubuntu configuration

Version Pinning

External dependencies are pinned to specific versions for reproducible builds:

  • VirtualGL: 3.1.4
  • Selkies GStreamer: 1.6.2

These are defined in files/linuxserver-kde.base.dockerfile as build arguments.


License

Main Project:

This project is based on multiple open source projects:

See each project's license for details.


Contributing

Issues and Pull Requests are welcome!

  1. Fork the repository
  2. Create a feature branch
  3. Submit a pull request


Credits

Original Projects

This Project

  • Enhancements: Two-stage build system, non-root execution, UID/GID matching, secure password management, management scripts, version pinning, multi-GPU support
  • Maintainer: @tatsuyai713
Description
No description provided
Readme GPL-3.0 56 MiB
Languages
Shell 58.9%
Dockerfile 41.1%