From 2c260e23a76349b0fa4de11d5582f211b5addb9d Mon Sep 17 00:00:00 2001 From: Conner Turnbull Date: Mon, 26 Jan 2026 14:35:43 -0500 Subject: [PATCH] Restructure devcontainers with browser-gui, native-gui variants and shared config --- .devcontainer/browser-gui/devcontainer.json | 31 ++++++++ .devcontainer/common/.env.example | 11 +++ .devcontainer/{ => common}/docker-compose.yml | 5 +- .devcontainer/common/postCreateCommand.sh | 70 +++++++++++++++++++ .../{ => macos-xquartz}/devcontainer.json | 26 ++----- .../macos-xquartz/docker-compose.override.yml | 4 ++ .devcontainer/native-gui/devcontainer.json | 30 ++++++++ .devcontainer/native-gui/setup-x11.sh | 32 +++++++++ .devcontainer/postCreateCommand.sh | 26 ------- .gitignore | 4 ++ 10 files changed, 192 insertions(+), 47 deletions(-) create mode 100644 .devcontainer/browser-gui/devcontainer.json create mode 100644 .devcontainer/common/.env.example rename .devcontainer/{ => common}/docker-compose.yml (63%) create mode 100755 .devcontainer/common/postCreateCommand.sh rename .devcontainer/{ => macos-xquartz}/devcontainer.json (50%) create mode 100644 .devcontainer/macos-xquartz/docker-compose.override.yml create mode 100644 .devcontainer/native-gui/devcontainer.json create mode 100755 .devcontainer/native-gui/setup-x11.sh delete mode 100755 .devcontainer/postCreateCommand.sh diff --git a/.devcontainer/browser-gui/devcontainer.json b/.devcontainer/browser-gui/devcontainer.json new file mode 100644 index 00000000000..fe307b0b392 --- /dev/null +++ b/.devcontainer/browser-gui/devcontainer.json @@ -0,0 +1,31 @@ +{ + "name": "Bitwarden Clients (macOS / GitHub Codespaces)", + "dockerComposeFile": "../common/docker-compose.yml", + "service": "bitwarden_clients", + "workspaceFolder": "/workspace", + "features": { + "ghcr.io/devcontainers/features/rust:1": {}, + "ghcr.io/devcontainers/features/desktop-lite:1": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "angular.ng-template", + "orta.vscode-jest", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "nrwl.angular-console", + "bradlc.vscode-tailwindcss" + ] + } + }, + "postCreateCommand": "bash .devcontainer/common/postCreateCommand.sh", + "forwardPorts": [8080, 8081, 6006, 6080], + "portsAttributes": { + "default": { "onAutoForward": "ignore" }, + "8080": { "label": "Web Vault", "onAutoForward": "notify" }, + "8081": { "label": "Web Vault (Self-hosted)", "onAutoForward": "notify" }, + "6006": { "label": "Storybook", "onAutoForward": "notify" }, + "6080": { "label": "Desktop (noVNC)", "onAutoForward": "ignore" } + } +} diff --git a/.devcontainer/common/.env.example b/.devcontainer/common/.env.example new file mode 100644 index 00000000000..4d4384c3755 --- /dev/null +++ b/.devcontainer/common/.env.example @@ -0,0 +1,11 @@ +# Devcontainer setup configuration +# Copy to .env and modify as needed + +# Install Rust nightly toolchain and cargo tools for desktop native module +SETUP_DESKTOP_NATIVE=yes + +# Install mkcert and generate SSL certificates for localhost (needed for WebAuthn) +SETUP_MKCERT=yes + +# Run npm ci to install dependencies +RUN_NPM_CI=yes diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/common/docker-compose.yml similarity index 63% rename from .devcontainer/docker-compose.yml rename to .devcontainer/common/docker-compose.yml index f403c23c3b4..6c59972fe67 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/common/docker-compose.yml @@ -1,8 +1,9 @@ -name: bitwarden_common +name: bitwarden_clients services: bitwarden_clients: image: mcr.microsoft.com/devcontainers/typescript-node:22 volumes: - - ../:/workspace:cached + - ../../:/workspace:cached + shm_size: "1gb" command: sleep infinity diff --git a/.devcontainer/common/postCreateCommand.sh b/.devcontainer/common/postCreateCommand.sh new file mode 100755 index 00000000000..71898db4485 --- /dev/null +++ b/.devcontainer/common/postCreateCommand.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash + +echo "Running postCreateCommand.sh" + +# Load configuration (use .env.example as fallback for defaults) +if [ -f ".devcontainer/common/.env" ]; then + source .devcontainer/common/.env +else + source .devcontainer/common/.env.example +fi + +# Configure git safe directory +git config --global --add safe.directory /workspace + +echo "Installing system dependencies..." +# Packages needed: +# libnss3-tools: mkcert certificate installation +# build-essential, pkg-config: native module compilation +# libsecret-1-dev, libglib2.0-dev: desktop native module dependencies +# Remaining packages: Electron runtime dependencies +sudo apt-get update && sudo apt-get install -y \ + libnss3-tools \ + build-essential \ + pkg-config \ + libsecret-1-dev \ + libglib2.0-dev \ + libdbus-1-3 \ + libgtk-3-0 \ + libnss3 \ + libatk-bridge2.0-0 \ + libatk1.0-0 \ + libx11-xcb1 \ + libxcb-dri3-0 \ + libxtst6 \ + libxss1 \ + libasound2 \ + libgbm1 + +if [ "$SETUP_DESKTOP_NATIVE" = "yes" ]; then + # Install Rust nightly toolchain (required for desktop native module) + echo "Installing Rust nightly toolchain..." + rustup toolchain install nightly + + # Install cargo tools for pre-commit hooks (optional but recommended) + echo "Installing cargo tools for pre-commit hooks..." + cargo install cargo-sort cargo-udeps cargo-deny +fi + +if [ "$SETUP_MKCERT" = "yes" ]; then + # Install mkcert for SSL certificates (needed for WebAuthn) + echo "Installing mkcert..." + curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64" + chmod +x mkcert-v*-linux-amd64 + sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert + + # Generate SSL certificates for localhost + echo "Generating SSL certificates..." + mkcert -install + cd /workspace/apps/web + mkcert -cert-file dev-server.local.pem -key-file dev-server.local.pem localhost bitwarden.test + cd /workspace +fi + +if [ "$RUN_NPM_CI" = "yes" ]; then + # Install npm dependencies + echo "Running npm ci..." + npm ci +fi + +echo "postCreateCommand.sh completed" diff --git a/.devcontainer/devcontainer.json b/.devcontainer/macos-xquartz/devcontainer.json similarity index 50% rename from .devcontainer/devcontainer.json rename to .devcontainer/macos-xquartz/devcontainer.json index ab3930fa500..c933376d78a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/macos-xquartz/devcontainer.json @@ -1,6 +1,6 @@ { - "name": "Bitwarden Clients", - "dockerComposeFile": "docker-compose.yml", + "name": "Bitwarden Clients (macOS XQuartz)", + "dockerComposeFile": ["../common/docker-compose.yml", "docker-compose.override.yml"], "service": "bitwarden_clients", "workspaceFolder": "/workspace", "features": { @@ -8,7 +8,6 @@ }, "customizations": { "vscode": { - "settings": {}, "extensions": [ "angular.ng-template", "orta.vscode-jest", @@ -19,23 +18,12 @@ ] } }, - "postCreateCommand": "bash .devcontainer/postCreateCommand.sh", + "postCreateCommand": "bash .devcontainer/common/postCreateCommand.sh", "forwardPorts": [8080, 8081, 6006], "portsAttributes": { - "default": { - "onAutoForward": "ignore" - }, - "8080": { - "label": "Web Vault", - "onAutoForward": "notify" - }, - "8081": { - "label": "Web Vault (Self-hosted)", - "onAutoForward": "notify" - }, - "6006": { - "label": "Storybook", - "onAutoForward": "notify" - } + "default": { "onAutoForward": "ignore" }, + "8080": { "label": "Web Vault", "onAutoForward": "notify" }, + "8081": { "label": "Web Vault (Self-hosted)", "onAutoForward": "notify" }, + "6006": { "label": "Storybook", "onAutoForward": "notify" } } } diff --git a/.devcontainer/macos-xquartz/docker-compose.override.yml b/.devcontainer/macos-xquartz/docker-compose.override.yml new file mode 100644 index 00000000000..c0bac0db9c7 --- /dev/null +++ b/.devcontainer/macos-xquartz/docker-compose.override.yml @@ -0,0 +1,4 @@ +services: + bitwarden_clients: + environment: + - DISPLAY=host.docker.internal:0 diff --git a/.devcontainer/native-gui/devcontainer.json b/.devcontainer/native-gui/devcontainer.json new file mode 100644 index 00000000000..24ae258ef77 --- /dev/null +++ b/.devcontainer/native-gui/devcontainer.json @@ -0,0 +1,30 @@ +{ + "name": "Bitwarden Clients (Windows / Linux)", + "dockerComposeFile": ["../common/docker-compose.yml", "docker-compose.override.yml"], + "service": "bitwarden_clients", + "workspaceFolder": "/workspace", + "initializeCommand": "bash .devcontainer/native-gui/setup-x11.sh", + "features": { + "ghcr.io/devcontainers/features/rust:1": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "angular.ng-template", + "orta.vscode-jest", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "nrwl.angular-console", + "bradlc.vscode-tailwindcss" + ] + } + }, + "postCreateCommand": "bash .devcontainer/common/postCreateCommand.sh", + "forwardPorts": [8080, 8081, 6006], + "portsAttributes": { + "default": { "onAutoForward": "ignore" }, + "8080": { "label": "Web Vault", "onAutoForward": "notify" }, + "8081": { "label": "Web Vault (Self-hosted)", "onAutoForward": "notify" }, + "6006": { "label": "Storybook", "onAutoForward": "notify" } + } +} diff --git a/.devcontainer/native-gui/setup-x11.sh b/.devcontainer/native-gui/setup-x11.sh new file mode 100755 index 00000000000..becaa3aee71 --- /dev/null +++ b/.devcontainer/native-gui/setup-x11.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# Generates docker-compose.override.yml for X11 forwarding +# Detects Windows (WSL2) vs native Linux + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +OVERRIDE_FILE="$SCRIPT_DIR/docker-compose.override.yml" + +if grep -qi microsoft /proc/version 2>/dev/null; then + echo "Detected Windows (WSL2) - configuring WSLg..." + cat > "$OVERRIDE_FILE" << 'EOF' +services: + bitwarden_clients: + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix + - /mnt/wslg:/mnt/wslg + environment: + - DISPLAY=${DISPLAY:-:0} + - WAYLAND_DISPLAY=${WAYLAND_DISPLAY:-wayland-0} + - XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-/mnt/wslg/runtime-dir} + - PULSE_SERVER=${PULSE_SERVER:-/mnt/wslg/PulseServer} +EOF +else + echo "Detected Linux - configuring X11..." + cat > "$OVERRIDE_FILE" << 'EOF' +services: + bitwarden_clients: + volumes: + - /tmp/.X11-unix:/tmp/.X11-unix + environment: + - DISPLAY=${DISPLAY:-:0} +EOF +fi diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh deleted file mode 100755 index 5ef572f0f67..00000000000 --- a/.devcontainer/postCreateCommand.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env bash - -echo "Running postCreateCommand.sh" - -# Configure git safe directory -git config --global --add safe.directory /workspace - -# Install mkcert for SSL certificates (needed for WebAuthn) -echo "Installing mkcert..." -sudo apt-get update && sudo apt-get install -y libnss3-tools -curl -JLO "https://dl.filippo.io/mkcert/latest?for=linux/amd64" -chmod +x mkcert-v*-linux-amd64 -sudo mv mkcert-v*-linux-amd64 /usr/local/bin/mkcert - -# Generate SSL certificates for localhost -echo "Generating SSL certificates..." -mkcert -install -cd /workspace/apps/web -mkcert -cert-file dev-server.local.pem -key-file dev-server.local.pem localhost bitwarden.test -cd /workspace - -# Install npm dependencies -echo "Running npm ci..." -npm ci - -echo "postCreateCommand.sh completed" diff --git a/.gitignore b/.gitignore index a88c3bd133b..9c7f9684a77 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,7 @@ apps/**/config/local.json # Nx .nx + +# DevContainer generated files +.devcontainer/native-gui/docker-compose.override.yml +.devcontainer/common/.env