mirror of
https://github.com/linuxserver/docker-webtop.git
synced 2026-02-19 16:13:42 +08:00
Updated numbering for SSL configuration and modified volume entries for WSLg. Enhanced user image building process and improved README formatting.
601 lines
17 KiB
Bash
Executable File
601 lines
17 KiB
Bash
Executable File
#!/bin/bash
|
|
# Create VS Code .devcontainer configuration
|
|
# This script creates a devcontainer.json that works with the webtop KDE desktop container
|
|
|
|
set -e
|
|
|
|
echo "========================================"
|
|
echo "VS Code Dev Container Configuration"
|
|
echo "========================================"
|
|
echo "This script will create a .devcontainer configuration"
|
|
echo "for using this container with VS Code."
|
|
echo ""
|
|
|
|
# Check if .devcontainer already exists
|
|
if [ -d ".devcontainer" ]; then
|
|
echo "⚠️ .devcontainer directory already exists."
|
|
read -p "Overwrite existing configuration? (y/N): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Cancelled."
|
|
exit 0
|
|
fi
|
|
rm -rf .devcontainer
|
|
fi
|
|
|
|
# Default values
|
|
GPU_VENDOR="none"
|
|
GPU_ALL="false"
|
|
GPU_NUMS=""
|
|
UBUNTU_VERSION="24.04"
|
|
RESOLUTION="1920x1080"
|
|
DPI="96"
|
|
SSL_DIR=""
|
|
HOST_ARCH_RAW=$(uname -m)
|
|
case "${HOST_ARCH_RAW}" in
|
|
x86_64|amd64) DETECTED_ARCH="amd64" ;;
|
|
aarch64|arm64) DETECTED_ARCH="arm64" ;;
|
|
*) DETECTED_ARCH="${HOST_ARCH_RAW}" ;;
|
|
esac
|
|
TARGET_ARCH="${DETECTED_ARCH}"
|
|
|
|
# Interactive configuration
|
|
echo "========================================"
|
|
echo "Configuration Questions"
|
|
echo "========================================"
|
|
echo ""
|
|
|
|
# GPU configuration
|
|
echo "1. GPU Configuration"
|
|
echo "-------------------"
|
|
echo "Select GPU type:"
|
|
echo " 1) No GPU (software rendering)"
|
|
echo " 2) NVIDIA GPU"
|
|
echo " 3) NVIDIA WSL2"
|
|
echo " 4) Intel GPU"
|
|
echo " 5) AMD GPU"
|
|
read -p "Select [1-5] (default: 1): " gpu_choice
|
|
|
|
case "${gpu_choice}" in
|
|
2)
|
|
GPU_VENDOR="nvidia"
|
|
echo ""
|
|
echo "NVIDIA GPU selected."
|
|
read -p "Use all NVIDIA GPUs? (Y/n): " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
read -p "Enter GPU device numbers (comma-separated, e.g., 0,1): " GPU_NUMS
|
|
GPU_ALL="false"
|
|
else
|
|
GPU_ALL="true"
|
|
GPU_NUMS=""
|
|
fi
|
|
;;
|
|
3)
|
|
GPU_VENDOR="nvidia-wsl"
|
|
GPU_ALL="true"
|
|
echo "NVIDIA WSL2 selected."
|
|
;;
|
|
4)
|
|
GPU_VENDOR="intel"
|
|
echo "Intel GPU selected."
|
|
;;
|
|
5)
|
|
GPU_VENDOR="amd"
|
|
echo "AMD GPU selected."
|
|
;;
|
|
*)
|
|
GPU_VENDOR="none"
|
|
echo "No GPU selected (software rendering)."
|
|
;;
|
|
esac
|
|
echo ""
|
|
|
|
# Ubuntu version
|
|
echo "2. Ubuntu Version"
|
|
echo "----------------"
|
|
read -p "Ubuntu version (22.04 or 24.04, default: 24.04): " UBUNTU_VERSION
|
|
UBUNTU_VERSION="${UBUNTU_VERSION:-24.04}"
|
|
echo ""
|
|
|
|
# Architecture
|
|
echo "3. Architecture"
|
|
echo "---------------"
|
|
read -p "Target architecture (amd64 or arm64, default: ${DETECTED_ARCH}): " TARGET_ARCH_INPUT
|
|
TARGET_ARCH_INPUT="${TARGET_ARCH_INPUT:-${DETECTED_ARCH}}"
|
|
case "${TARGET_ARCH_INPUT}" in
|
|
amd64|x86_64) TARGET_ARCH="amd64" ;;
|
|
arm64|aarch64) TARGET_ARCH="arm64" ;;
|
|
*)
|
|
echo "Unsupported architecture: ${TARGET_ARCH_INPUT}" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
echo ""
|
|
|
|
# Display settings
|
|
echo "4. Display Settings"
|
|
echo "-------------------"
|
|
read -p "Display resolution (default: 1920x1080): " RESOLUTION
|
|
RESOLUTION="${RESOLUTION:-1920x1080}"
|
|
read -p "DPI (default: 96): " DPI
|
|
DPI="${DPI:-96}"
|
|
echo ""
|
|
|
|
# Language/Timezone settings
|
|
echo "5. Language/Timezone Settings"
|
|
echo "-----------------------------"
|
|
echo "Select language (affects timezone):"
|
|
echo " ja) Japanese (Asia/Tokyo)"
|
|
echo " en) English (UTC)"
|
|
read -p "Select language [ja/en] (default: en): " lang_choice
|
|
case "${lang_choice}" in
|
|
ja|JA|jp|JP)
|
|
TIMEZONE="Asia/Tokyo"
|
|
echo "Japanese selected. Timezone: Asia/Tokyo"
|
|
;;
|
|
*)
|
|
TIMEZONE="UTC"
|
|
echo "English selected. Timezone: UTC"
|
|
;;
|
|
esac
|
|
echo ""
|
|
|
|
# SSL directory (optional)
|
|
echo "6. SSL Configuration (Optional)"
|
|
echo "-------------------------------"
|
|
read -p "SSL directory path (leave empty to skip): " SSL_DIR
|
|
echo ""
|
|
|
|
# Default SSL dir fallback (same as start-container.sh)
|
|
if [ -z "${SSL_DIR}" ]; then
|
|
DEFAULT_SSL_DIR="$(pwd)/ssl"
|
|
if [ -d "${DEFAULT_SSL_DIR}" ]; then
|
|
SSL_DIR="${DEFAULT_SSL_DIR}"
|
|
echo "Using SSL dir: ${SSL_DIR}"
|
|
fi
|
|
fi
|
|
|
|
CURRENT_USER=$(whoami)
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
COMPOSE_ENV_SCRIPT="${SCRIPT_DIR}/compose-env.sh"
|
|
|
|
if [ ! -x "${COMPOSE_ENV_SCRIPT}" ]; then
|
|
echo "Error: ${COMPOSE_ENV_SCRIPT} not found. Run this script from the repository root." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Create .devcontainer directory
|
|
mkdir -p .devcontainer
|
|
|
|
# Build compose-env arguments
|
|
COMPOSE_ARGS=(--gpu "${GPU_VENDOR}" --ubuntu "${UBUNTU_VERSION}" --resolution "${RESOLUTION}" --dpi "${DPI}" --arch "${TARGET_ARCH}" --timezone "${TIMEZONE}")
|
|
if [ "${GPU_VENDOR}" = "nvidia" ]; then
|
|
if [ "${GPU_ALL}" = "true" ]; then
|
|
COMPOSE_ARGS+=(--all)
|
|
else
|
|
COMPOSE_ARGS+=(--num "${GPU_NUMS}")
|
|
fi
|
|
fi
|
|
if [ -n "${SSL_DIR}" ]; then
|
|
COMPOSE_ARGS+=(--ssl "${SSL_DIR}")
|
|
fi
|
|
|
|
# Generate environment variables
|
|
ENV_FILE=".devcontainer/.env"
|
|
"${COMPOSE_ENV_SCRIPT}" "${COMPOSE_ARGS[@]}" --env-file "${ENV_FILE}"
|
|
|
|
# Load generated environment values
|
|
set -a
|
|
# shellcheck disable=SC1090
|
|
source "${ENV_FILE}"
|
|
set +a
|
|
|
|
DEVCONTAINER_CONTAINER_NAME="${CONTAINER_NAME}"
|
|
{
|
|
echo ""
|
|
echo "# Dev Container specific"
|
|
echo "DEVCONTAINER_CONTAINER_NAME=${DEVCONTAINER_CONTAINER_NAME}"
|
|
} >> "${ENV_FILE}"
|
|
export DEVCONTAINER_CONTAINER_NAME
|
|
|
|
WORKSPACE_FOLDER="/home/${CURRENT_USER}/host_home"
|
|
|
|
GPU_DEVICES=""
|
|
case "${GPU_VENDOR}" in
|
|
intel)
|
|
if [ -d "/dev/dri" ]; then
|
|
GPU_DEVICES="/dev/dri:/dev/dri:rwm"
|
|
fi
|
|
;;
|
|
amd)
|
|
if [ -d "/dev/dri" ]; then
|
|
GPU_DEVICES="/dev/dri:/dev/dri:rwm"
|
|
fi
|
|
if [ -e "/dev/kfd" ]; then
|
|
GPU_DEVICES="${GPU_DEVICES:+${GPU_DEVICES},}/dev/kfd:/dev/kfd:rwm"
|
|
fi
|
|
;;
|
|
nvidia)
|
|
if [ -d "/dev/dri" ]; then
|
|
GPU_DEVICES="/dev/dri:/dev/dri:rwm"
|
|
fi
|
|
;;
|
|
nvidia-wsl)
|
|
if [ -e "/dev/dxg" ]; then
|
|
GPU_DEVICES="/dev/dxg:/dev/dxg:rwm"
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
# Build forward port list
|
|
FORWARD_PORTS=("${HOST_PORT_SSL}" "${HOST_PORT_HTTP}" "${HOST_PORT_TURN}")
|
|
|
|
FORWARD_PORTS_JSON=""
|
|
for PORT in "${FORWARD_PORTS[@]}"; do
|
|
if [ -n "${FORWARD_PORTS_JSON}" ]; then
|
|
FORWARD_PORTS_JSON="${FORWARD_PORTS_JSON},
|
|
"
|
|
fi
|
|
FORWARD_PORTS_JSON="${FORWARD_PORTS_JSON} ${PORT}"
|
|
done
|
|
|
|
PORT_ATTRIBUTES_JSON=" \"${HOST_PORT_SSL}\": {
|
|
\"label\": \"HTTPS Web UI\",
|
|
\"onAutoForward\": \"notify\"
|
|
},
|
|
\"${HOST_PORT_HTTP}\": {
|
|
\"label\": \"HTTP Web UI\",
|
|
\"onAutoForward\": \"silent\"
|
|
},
|
|
\"${HOST_PORT_TURN}\": {
|
|
\"label\": \"TURN Server\",
|
|
\"onAutoForward\": \"silent\"
|
|
}"
|
|
|
|
# devcontainer.json
|
|
cat > .devcontainer/devcontainer.json << EOF
|
|
{
|
|
"name": "KDE Desktop (${GPU_VENDOR})",
|
|
"dockerComposeFile": [
|
|
"docker-compose.base.yml",
|
|
"docker-compose.override.yml"
|
|
],
|
|
"service": "webtop",
|
|
"workspaceFolder": "${WORKSPACE_FOLDER}",
|
|
"runServices": ["webtop"],
|
|
"overrideCommand": false,
|
|
"shutdownAction": "none",
|
|
"initializeCommand": "cd \${localWorkspaceFolder:-${PWD}} && if [ -f .devcontainer/.env ]; then CN=\$(sed -n 's/^CONTAINER_NAME=//p' .devcontainer/.env | head -n1); fi; if [ -n \"\$CN\" ]; then docker rm -f \"\$CN\" >/dev/null 2>&1 || true; fi",
|
|
"forwardPorts": [
|
|
${FORWARD_PORTS_JSON}
|
|
],
|
|
"portsAttributes": {
|
|
${PORT_ATTRIBUTES_JSON}
|
|
},
|
|
"customizations": {
|
|
"vscode": {
|
|
"extensions": [
|
|
"ms-vscode-remote.remote-containers",
|
|
"ms-vscode.cpptools-extension-pack",
|
|
"ms-vscode.cmake-tools",
|
|
"ms-vscode.makefile-tools",
|
|
"redhat.vscode-yaml",
|
|
"redhat.vscode-xml",
|
|
"ms-vscode.hexeditor",
|
|
"ms-python.python",
|
|
"ms-python.vscode-pylance",
|
|
"vscode-icons-team.vscode-icons",
|
|
"donjayamanne.git-extension-pack"
|
|
],
|
|
"settings": {
|
|
"terminal.integrated.defaultProfile.linux": "bash"
|
|
}
|
|
}
|
|
},
|
|
"remoteUser": "${CURRENT_USER}",
|
|
"containerUser": "root",
|
|
"updateRemoteUserUID": false,
|
|
"remoteEnv": {
|
|
"USER": "${CURRENT_USER}",
|
|
"HOME": "/home/${CURRENT_USER}"
|
|
},
|
|
EOF
|
|
# Add GPU hostRequirements if applicable
|
|
if [ "${GPU_VENDOR}" = "nvidia" ] || [ "${GPU_VENDOR}" = "nvidia-wsl" ]; then
|
|
cat >> .devcontainer/devcontainer.json << 'EOF'
|
|
"hostRequirements": {
|
|
"gpu": "optional"
|
|
},
|
|
EOF
|
|
fi
|
|
|
|
cat >> .devcontainer/devcontainer.json << EOF
|
|
"postCreateCommand": "echo '===== Dev Container Ready =====' && echo 'Desktop access' && echo ' HTTPS: https://localhost:${HOST_PORT_SSL}' && echo ' HTTP : http://localhost:${HOST_PORT_HTTP}' && echo 'If HTTPS fails, confirm your SSL certs or use HTTP.' && echo '==============================='"
|
|
}
|
|
EOF
|
|
|
|
# docker-compose base (match start-container.sh)
|
|
cat > .devcontainer/docker-compose.base.yml << EOF
|
|
services:
|
|
webtop:
|
|
image: \${USER_IMAGE}
|
|
container_name: \${CONTAINER_NAME}
|
|
hostname: \${CONTAINER_HOSTNAME}
|
|
shm_size: \${SHM_SIZE:-4g}
|
|
privileged: true
|
|
security_opt:
|
|
- seccomp:unconfined
|
|
environment:
|
|
- HOSTNAME=\${CONTAINER_HOSTNAME}
|
|
- HOST_HOSTNAME=\${CONTAINER_HOSTNAME}
|
|
- SHELL=/bin/bash
|
|
- DISPLAY=:1
|
|
- DPI=\${DPI}
|
|
- SCALE_FACTOR=\${SCALE_FACTOR}
|
|
- FORCE_DEVICE_SCALE_FACTOR=\${FORCE_DEVICE_SCALE_FACTOR}
|
|
- CHROMIUM_FLAGS=\${CHROMIUM_FLAGS}
|
|
- DISPLAY_WIDTH=\${WIDTH}
|
|
- DISPLAY_HEIGHT=\${HEIGHT}
|
|
- CUSTOM_RESOLUTION=\${RESOLUTION}
|
|
- USER_UID=\${USER_UID}
|
|
- USER_GID=\${USER_GID}
|
|
- USER_NAME=\${USER_NAME}
|
|
- PUID=\${HOST_UID}
|
|
- PGID=\${HOST_GID}
|
|
- SELKIES_ENCODER=\${SELKIES_ENCODER}
|
|
- GPU_VENDOR=\${GPU_VENDOR}
|
|
- ENABLE_NVIDIA=\${ENABLE_NVIDIA}
|
|
- LIBVA_DRIVER_NAME=\${LIBVA_DRIVER_NAME}
|
|
- WSL_ENVIRONMENT=\${WSL_ENVIRONMENT}
|
|
- DISABLE_ZINK=\${DISABLE_ZINK}
|
|
- XDG_RUNTIME_DIR=\${XDG_RUNTIME_DIR}
|
|
- LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}
|
|
- SELKIES_TURN_HOST=\${SELKIES_TURN_HOST}
|
|
- SELKIES_TURN_PORT=\${SELKIES_TURN_PORT}
|
|
- SELKIES_TURN_USERNAME=\${SELKIES_TURN_USERNAME}
|
|
- SELKIES_TURN_PASSWORD=\${SELKIES_TURN_PASSWORD}
|
|
- SELKIES_TURN_PROTOCOL=\${SELKIES_TURN_PROTOCOL}
|
|
- TURN_RANDOM_PASSWORD=\${TURN_RANDOM_PASSWORD}
|
|
- TURN_EXTERNAL_IP=\${TURN_EXTERNAL_IP}
|
|
volumes:
|
|
- \${HOME}:\${HOST_HOME_MOUNT}:rw
|
|
ports:
|
|
- \${HOST_PORT_HTTP}:3000
|
|
- \${HOST_PORT_SSL}:3001
|
|
- \${HOST_PORT_TURN}:3478/tcp
|
|
- \${HOST_PORT_TURN}:3478/udp
|
|
restart: unless-stopped
|
|
EOF
|
|
|
|
# docker-compose override for devcontainer
|
|
cat > .devcontainer/docker-compose.override.yml << EOF
|
|
services:
|
|
webtop:
|
|
network_mode: bridge
|
|
EOF
|
|
|
|
DEVICE_ENTRIES=()
|
|
VOLUME_ENTRIES=()
|
|
GROUPS_TO_ADD=()
|
|
|
|
# Add host group mappings (match start-container.sh)
|
|
VIDEO_GID=$(getent group video 2>/dev/null | cut -d: -f3 || true)
|
|
RENDER_GID=$(getent group render 2>/dev/null | cut -d: -f3 || true)
|
|
if [ -n "${VIDEO_GID}" ]; then
|
|
GROUPS_TO_ADD+=("${VIDEO_GID}")
|
|
fi
|
|
if [ -n "${RENDER_GID}" ]; then
|
|
GROUPS_TO_ADD+=("${RENDER_GID}")
|
|
fi
|
|
|
|
if [ "${#GROUPS_TO_ADD[@]}" -gt 0 ]; then
|
|
{
|
|
echo " group_add:"
|
|
for GID in "${GROUPS_TO_ADD[@]}"; do
|
|
echo " - \"${GID}\""
|
|
done
|
|
} >> .devcontainer/docker-compose.override.yml
|
|
fi
|
|
|
|
if [ "${GPU_VENDOR}" = "nvidia" ] || [ "${GPU_VENDOR}" = "nvidia-wsl" ]; then
|
|
if [ "${GPU_VENDOR}" = "nvidia-wsl" ] || [ "${GPU_ALL}" = "true" ]; then
|
|
echo " gpus: all" >> .devcontainer/docker-compose.override.yml
|
|
elif [ -n "${GPU_NUMS}" ]; then
|
|
echo " gpus: \"device=${GPU_NUMS}\"" >> .devcontainer/docker-compose.override.yml
|
|
fi
|
|
fi
|
|
|
|
if [ "${GPU_VENDOR}" = "nvidia-wsl" ]; then
|
|
# Add WSL-specific devices if they exist
|
|
if [ -e "/dev/dxg" ]; then
|
|
DEVICE_ENTRIES+=("/dev/dxg:/dev/dxg:rwm")
|
|
fi
|
|
# Add WSL-specific volumes
|
|
if [ -d "/usr/lib/wsl/lib" ]; then
|
|
VOLUME_ENTRIES+=("/usr/lib/wsl/lib:/usr/lib/wsl/lib:ro")
|
|
fi
|
|
if [ -d "/mnt/wslg" ]; then
|
|
VOLUME_ENTRIES+=("/mnt/wslg:/mnt/wslg:rw")
|
|
VOLUME_ENTRIES+=("/mnt/wslg/.X11-unix:/tmp/.X11-unix:rw")
|
|
VOLUME_ENTRIES+=("/usr/lib/wsl/drivers:/usr/lib/wsl/drivers:ro")
|
|
fi
|
|
fi
|
|
|
|
if [ -n "${GPU_DEVICES}" ]; then
|
|
IFS=',' read -r -a GPU_DEVICE_LIST <<< "${GPU_DEVICES}"
|
|
for DEVICE in "${GPU_DEVICE_LIST[@]}"; do
|
|
DEVICE_ENTRIES+=("${DEVICE}")
|
|
done
|
|
fi
|
|
|
|
DEVICE_ENTRIES+=("/dev/bus/usb:/dev/bus/usb:rwm")
|
|
|
|
# Add SSL mount when available (match start-container.sh)
|
|
if [ -n "${SSL_DIR}" ] && [ -f "${SSL_DIR}/cert.pem" ] && [ -f "${SSL_DIR}/cert.key" ]; then
|
|
VOLUME_ENTRIES+=("\${SSL_DIR}:/config/ssl:ro")
|
|
fi
|
|
|
|
# Add /mnt mount on non-mac hosts (Docker Desktop for Mac does not share /mnt by default)
|
|
if [ "$(uname -s)" != "Darwin" ] && [ -d "/mnt" ]; then
|
|
VOLUME_ENTRIES+=("/mnt:\${HOST_MNT_MOUNT}:rw")
|
|
fi
|
|
|
|
if [ "${#DEVICE_ENTRIES[@]}" -gt 0 ]; then
|
|
{
|
|
echo " devices:"
|
|
for DEVICE in "${DEVICE_ENTRIES[@]}"; do
|
|
echo " - ${DEVICE}"
|
|
done
|
|
} >> .devcontainer/docker-compose.override.yml
|
|
fi
|
|
|
|
if [ "${#VOLUME_ENTRIES[@]}" -gt 0 ]; then
|
|
{
|
|
echo " volumes:"
|
|
for VOLUME in "${VOLUME_ENTRIES[@]}"; do
|
|
echo " - ${VOLUME}"
|
|
done
|
|
} >> .devcontainer/docker-compose.override.yml
|
|
fi
|
|
|
|
# Copy .env to workspace root for docker-compose
|
|
cp "${ENV_FILE}" .env
|
|
|
|
# README
|
|
cat > .devcontainer/README.md << EOF
|
|
# VS Code Dev Container Configuration
|
|
|
|
The files in this directory are generated by \`./create-devcontainer-config.sh\`. It writes the same environment variables as \`start-container.sh\` into \`.devcontainer/.env\` and the repository root \`.env\`.
|
|
|
|
## Generated settings
|
|
|
|
- **GPU**: ${GPU_VENDOR}
|
|
EOF
|
|
|
|
if [ "${GPU_VENDOR}" = "nvidia" ]; then
|
|
if [ "${GPU_ALL}" = "true" ]; then
|
|
cat >> .devcontainer/README.md << 'EOF'
|
|
- **NVIDIA GPUs**: all
|
|
EOF
|
|
else
|
|
cat >> .devcontainer/README.md << EOF
|
|
- **NVIDIA GPUs**: ${GPU_NUMS}
|
|
EOF
|
|
fi
|
|
fi
|
|
|
|
cat >> .devcontainer/README.md << EOF
|
|
- **Ubuntu Version**: ${UBUNTU_VERSION}
|
|
- **Resolution**: ${RESOLUTION}
|
|
- **DPI**: ${DPI}
|
|
- **Timezone**: ${TIMEZONE}
|
|
|
|
## Access URLs
|
|
|
|
- **HTTPS**: https://localhost:${HOST_PORT_SSL}
|
|
- **HTTP**: http://localhost:${HOST_PORT_HTTP}
|
|
- **TURN Port**: ${HOST_PORT_TURN}
|
|
|
|
## How to use in VS Code
|
|
1. Install the Dev Containers extension
|
|
2. Open the workspace and run \`F1\` → \`Dev Containers: Reopen in Container\`
|
|
3. VS Code reads \`.env\` and starts \`docker compose\`
|
|
|
|
## How to use in VS Code
|
|
1. Install the Dev Containers extension
|
|
2. Open the workspace and run \`F1\` → \`Dev Containers: Reopen in Container\`
|
|
3. VS Code reads \`.env\` and starts \`docker compose\`
|
|
EOF
|
|
|
|
# Copy .env to workspace root for docker-compose
|
|
cp "${ENV_FILE}" .env
|
|
|
|
echo ""
|
|
echo "========================================"
|
|
echo "Configuration Complete!"
|
|
echo "========================================"
|
|
echo ""
|
|
echo "Created files:"
|
|
echo " - .devcontainer/devcontainer.json"
|
|
echo " - .devcontainer/docker-compose.base.yml"
|
|
echo " - .devcontainer/docker-compose.override.yml"
|
|
echo " - .devcontainer/.env"
|
|
echo " - .devcontainer/README.md"
|
|
echo " - .env (for docker-compose)"
|
|
echo ""
|
|
echo "Configuration summary:"
|
|
echo " - GPU: ${GPU_VENDOR}"
|
|
if [ "${GPU_VENDOR}" = "nvidia" ]; then
|
|
if [ "${GPU_ALL}" = "true" ]; then
|
|
echo " NVIDIA GPUs: all"
|
|
else
|
|
echo " NVIDIA GPUs: ${GPU_NUMS}"
|
|
fi
|
|
fi
|
|
echo " - Ubuntu: ${UBUNTU_VERSION}"
|
|
echo " - Resolution: ${RESOLUTION}"
|
|
echo " - DPI: ${DPI}"
|
|
echo " - Timezone: ${TIMEZONE}"
|
|
echo " - HTTPS Port: ${HOST_PORT_SSL}"
|
|
echo " - HTTP Port: ${HOST_PORT_HTTP}"
|
|
echo " - TURN Port: ${HOST_PORT_TURN}"
|
|
echo ""
|
|
echo "========================================"
|
|
|
|
# Check if the user image exists
|
|
echo "Checking for user image: ${USER_IMAGE}..."
|
|
if ! docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "^${USER_IMAGE}$"; then
|
|
echo ""
|
|
echo "⚠️ User image not found: ${USER_IMAGE}"
|
|
echo "Building user image automatically..."
|
|
echo ""
|
|
|
|
# Prepare build-user-image.sh arguments
|
|
BUILD_ARGS=(--ubuntu "${UBUNTU_VERSION}" --arch "${TARGET_ARCH}")
|
|
|
|
# Determine language argument
|
|
case "${TIMEZONE}" in
|
|
Asia/Tokyo)
|
|
BUILD_ARGS+=(--language "ja")
|
|
;;
|
|
*)
|
|
BUILD_ARGS+=(--language "en")
|
|
;;
|
|
esac
|
|
|
|
# Execute build-user-image.sh
|
|
BUILD_SCRIPT="${SCRIPT_DIR}/build-user-image.sh"
|
|
if [ ! -x "${BUILD_SCRIPT}" ]; then
|
|
echo "Error: ${BUILD_SCRIPT} not found or not executable." >&2
|
|
echo "Please run: ./build-user-image.sh ${BUILD_ARGS[*]}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "Executing: ${BUILD_SCRIPT} ${BUILD_ARGS[*]}"
|
|
if "${BUILD_SCRIPT}" "${BUILD_ARGS[@]}"; then
|
|
echo ""
|
|
echo "✅ User image built successfully!"
|
|
echo ""
|
|
else
|
|
echo ""
|
|
echo "❌ Failed to build user image." >&2
|
|
echo "Please manually run: ./build-user-image.sh ${BUILD_ARGS[*]}" >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
echo "✅ User image found: ${USER_IMAGE}"
|
|
fi
|
|
echo ""
|
|
echo "========================================"
|
|
echo "Ready to use Dev Container!"
|
|
echo "========================================"
|
|
echo ""
|
|
echo "To start the devcontainer from VS Code:"
|
|
echo " 1) Open this workspace in VS Code."
|
|
echo " 2) Press F1 to open the Command Palette."
|
|
echo " 3) Type and run: Dev Containers: Reopen in Container"
|
|
echo " (or select 'Dev Containers: Reopen in Container')"
|
|
echo ""
|
|
echo "Tip: You can also click the green >< icon in the lower-left corner and choose 'Reopen in Container'."
|