diff --git a/.dockerignore b/.dockerignore index 9bcce7a80897..862da21eb099 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,63 @@ -** -!release-packages -!ci +# Node +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# VSCode +.vscode + +# Build outputs +/out +/dist +/lib/*.js +/lib/*.d.ts +/lib/*.js.map + +# OS +.DS_Store +Thumbs.db + +# Project specific +/test/integration/node_modules + +# Logs +*.log + +# Git files +.git +.gitignore + +# Docs (keep essential docs) +docs/ +*.md +!README.md +!QBRAID_BUILD_README.md + +# Large directories we don't need +.github/ +ci/ +test/ +patches/ +.pc/ +.tours/ + +# Development files +.eslintrc.js +.prettierrc.yaml +.editorconfig +eslint.config.mjs +tsconfig.json +package-lock.json +renovate.json +.node-version +.nvmrc +flake.nix +flake.lock + +# Include our custom files +!extensions +!logo-square.png +!Dockerfile.qbraid +!build-qbraid-docker.sh +!install-qbraid-extensions.sh diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 000000000000..22513467ded5 --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,43 @@ +FROM node:20-bullseye AS builder + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + git \ + git-lfs \ + python3 \ + quilt \ + jq \ + rsync \ + curl \ + && rm -rf /var/lib/apt/lists/* + +# Install nfpm from GitHub releases (latest version) +RUN ARCH="$(dpkg --print-architecture)" && \ + case "$ARCH" in \ + "amd64") NFPM_ARCH="x86_64" ;; \ + "arm64") NFPM_ARCH="aarch64" ;; \ + *) NFPM_ARCH="$ARCH" ;; \ + esac && \ + echo "Installing nfpm for architecture: $NFPM_ARCH" && \ + curl -fsSL "https://github.com/goreleaser/nfpm/releases/download/v2.42.1/nfpm_2.42.1_linux_${NFPM_ARCH}.tar.gz" | \ + tar -xz -C /usr/local/bin && \ + chmod +x /usr/local/bin/nfpm && \ + nfpm --version + +WORKDIR /src +COPY . . + +# Initialize submodules and apply patches +RUN git submodule update --init && quilt push -a + +# Install dependencies and build +RUN npm install && \ + npm run build && \ + VERSION=${TAG} npm run build:vscode && \ + KEEP_MODULES=1 npm run release && \ + npm run package + +# Extract the packages +FROM scratch AS packages +COPY --from=builder /src/release-packages/ /packages/ \ No newline at end of file diff --git a/Dockerfile.custom b/Dockerfile.custom new file mode 100644 index 000000000000..793e01ffadf3 --- /dev/null +++ b/Dockerfile.custom @@ -0,0 +1,54 @@ +# Custom Code-Server Dockerfile with QBraid branding +FROM node:20-bullseye as builder + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + git \ + git-lfs \ + python3 \ + quilt \ + jq \ + rsync \ + && rm -rf /var/lib/apt/lists/* + +# Set working directory +WORKDIR /src + +# Copy source code +COPY . . + +# Initialize git submodules +RUN git submodule update --init + +# Apply patches +RUN quilt push -a || true + +# Install dependencies and build +RUN npm install && \ + npm run build && \ + VERSION=0.0.0 npm run build:vscode && \ + npm run release + +# Build packages +RUN npm run package + +# Production stage +FROM codercom/code-server:latest + +# Switch to root to install packages +USER root + +# Copy our custom build +COPY --from=builder /src/release-packages/*.deb /tmp/ + +# Install our custom build +RUN dpkg -i /tmp/*.deb || apt-get update && apt-get install -f -y + +# Copy custom favicon files (we'll add these in the next step) +# COPY logo-square.png /opt/code-server/lib/vscode/src/vs/workbench/browser/media/favicon.png + +USER 1000 + +EXPOSE 8080 +ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "."] \ No newline at end of file diff --git a/Dockerfile.qbraid b/Dockerfile.qbraid new file mode 100644 index 000000000000..d2f285ccb53f --- /dev/null +++ b/Dockerfile.qbraid @@ -0,0 +1,45 @@ +# syntax=docker/dockerfile:experimental +# QBraid customized Code-Server + +FROM codercom/code-server:latest + +ARG NB_USER="jovyan" +ARG NB_UID="1000" +ARG NB_GID="100" + +# Switch to root to make changes +USER root + +# Create jovyan user and group +RUN userdel coder && \ + groupadd -f -g ${NB_GID} ${NB_USER} && \ + useradd -u ${NB_UID} -g ${NB_GID} -m -s /bin/bash ${NB_USER} + +# Create extensions directory and copy extensions to permanent location +RUN mkdir -p /opt/qbraid-extensions +COPY ./extensions/ /opt/qbraid-extensions/ + +# Copy the extension installation script +COPY install-qbraid-extensions.sh /opt/install-qbraid-extensions.sh +RUN chmod +x /opt/install-qbraid-extensions.sh +# Set ownership for jovyan user +RUN chown -R ${NB_USER}:${NB_GID} /opt/qbraid-extensions + +# Allow users to have scripts run on container startup to prepare workspace. +ENV ENTRYPOINTD=/home/${NB_USER}/entrypoint.d + +# Disable authentication by setting empty password +ENV PASSWORD="" + +# Create entrypoint.d directory and add our extension installation script +RUN mkdir -p /home/${NB_USER}/entrypoint.d && \ + echo '#!/bin/bash' > /home/${NB_USER}/entrypoint.d/install-extensions.sh && \ + echo '/opt/install-qbraid-extensions.sh &' >> /home/${NB_USER}/entrypoint.d/install-extensions.sh && \ + chmod +x /home/${NB_USER}/entrypoint.d/install-extensions.sh && \ + chown -R ${NB_USER}:${NB_GID} /home/${NB_USER}/entrypoint.d + +EXPOSE 8080 +USER ${NB_USER} +ENV USER=${NB_USER} +WORKDIR /home/${NB_USER} +ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "--auth", "none", "."] \ No newline at end of file diff --git a/QBRAID_BUILD_README.md b/QBRAID_BUILD_README.md new file mode 100644 index 000000000000..feec4e75d6b8 --- /dev/null +++ b/QBRAID_BUILD_README.md @@ -0,0 +1,332 @@ +# QBraid Code-Server Custom Build + +This guide explains how to build a customized Code-Server Docker image with QBraid branding, pre-configured settings, and QBraid extensions. + +## Features + +### No Authentication Required +- **Direct access** - No password prompt when accessing code-server +- **Development-friendly** - Perfect for development environments and internal use +- **Optional security** - Can be easily re-enabled if needed for production + +### Multi-Platform Build Support +- Uses Docker buildx for cross-platform builds +- Targets `linux/amd64` architecture by default for maximum compatibility +- Works on Apple Silicon Macs, Intel Macs, and Linux development machines + +### Pre-installed QBraid Extensions +- Automatically installs all VSIX extension files from the `extensions/` directory +- Currently includes: + - QBraid Environment Manager (`environment-manager-0.1.0.vsix`) + - Quantum Console (`quantum-console-0.2.2.vsix`) +- Extensions are installed during the Docker build process and available immediately + +### Pre-configured Settings + +**User Settings** (stored in `~/.vscode/User/settings.json`): +- Dark theme by default +- Optimized editor settings (font size, tab settings, word wrap) +- Auto-save enabled +- Git integration configured +- Python development ready +- Modern icon theme + +**Machine Settings** (stored in `~/.vscode/Machine/settings.json`): +- Disabled automatic updates +- Telemetry turned off +- Reduced welcome page distractions + +### Difference Between User and Machine Settings + +- **User Settings**: Per-user preferences that can be overridden by workspace settings +- **Machine Settings**: System-wide settings that take precedence over user settings, typically used for administrative policies + +## Prerequisites + +1. **Docker with buildx support** (Docker Desktop 19.03+ or Docker CE 20.10+) +2. **Google Cloud CLI** (`gcloud`) installed and configured +3. **Git** with access to this repository +4. **QBraid extensions** as VSIX files in the `extensions/` directory + +## Quick Start + +### 1. Verify QBraid Extensions + +The `extensions/` directory should contain your VSIX files: + +```bash +extensions/ +├── environment-manager-0.1.0.vsix +└── quantum-console-0.2.2.vsix +``` + +**Extension Requirements:** +- Format: VSIX files (VS Code extension packages) +- Place all extension files in the `extensions/` directory +- Extensions will be automatically installed during the build + +### 2. Run the Build Script + +```bash +# Build and optionally push to Google Cloud Artifact Registry +./build-qbraid-docker.sh + +# Or build with a specific tag +./build-qbraid-docker.sh v1.0.0 +``` + +### 3. What the Script Does + +1. **Sets up Docker buildx** - Creates a multi-platform builder if needed +2. **Checks for QBraid extensions** - lists found VSIX files +3. **Builds for linux/amd64** - ensures compatibility with most cloud environments +4. **Creates custom Docker image** - applies your branding, settings, and extensions +5. **Optionally pushes to registry** - uploads to your Google Cloud Artifact Registry + +echo "Features included in your custom build:" +echo " • No authentication required - direct access to code-server" +echo " • Pre-configured VS Code settings optimized for development" +echo " • Pre-installed QBraid extensions (if VSIX files were provided)" +echo " • Python development environment" + +## Manual Build Process + +If you prefer to build manually: + +### Step 1: Set up Docker buildx + +```bash +# Create a builder instance for multi-platform builds +docker buildx create --name qbraid-builder --use +docker buildx use qbraid-builder +``` + +### Step 2: Build Custom Image + +```bash +# Build the custom QBraid image for linux/amd64 +docker buildx build \ + --platform=linux/amd64 \ + -f Dockerfile.qbraid \ + -t us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest \ + --load \ + . +``` + +### Step 3: Push to Registry + +```bash +# Authenticate with Google Cloud +gcloud auth login +gcloud auth configure-docker us-central1-docker.pkg.dev + +# Push the image +docker push us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest +``` + +## Testing Locally + +Run your custom image locally to test: + +```bash +docker run -it --rm -p 8080:8080 \ + us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest +``` + +Then open http://localhost:8080 in your browser. **No password required** - you'll go directly to VS Code! Your QBraid extensions should be automatically available in the Extensions panel. + +## Using in Kubernetes + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: qbraid-code-server +spec: + replicas: 1 + selector: + matchLabels: + app: qbraid-code-server + template: + metadata: + labels: + app: qbraid-code-server + spec: + containers: + - name: code-server + image: us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest + ports: + - containerPort: 8080 + # No PASSWORD environment variable needed - authentication is disabled +``` + +## Security Configuration + +### No Authentication (Default) + +By default, this build disables authentication for ease of development use: + +- **Environment**: `PASSWORD=""` +- **Startup flag**: `--auth none` +- **Access**: Direct access to VS Code interface + +### Enabling Authentication (Optional) + +If you need to enable authentication for production use, you can override the default behavior: + +#### Option 1: Set PASSWORD environment variable + +```bash +# Run with password authentication +docker run -it --rm -p 8080:8080 \ + -e PASSWORD="your-secure-password" \ + us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest \ + --auth password +``` + +#### Option 2: Modify the Dockerfile + +Edit `Dockerfile.qbraid` and change: + +```dockerfile +# Remove or comment out these lines: +ENV PASSWORD="" +ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "--auth", "none", "."] + +# Replace with: +ENV PASSWORD="your-default-password" +ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "."] +``` + + +## Advanced Configuration + +### Building for Different Platforms + +To build for a different platform, modify the `PLATFORM` variable in the build script: + +```bash +# Edit build-qbraid-docker.sh and change: +PLATFORM="linux/arm64" # For ARM64 servers +# or +PLATFORM="linux/amd64,linux/arm64" # For multi-arch builds +``` + +### Multi-Architecture Builds + +For true multi-architecture builds that support both AMD64 and ARM64: + +```bash +docker buildx build \ + --platform=linux/amd64,linux/arm64 \ + -f Dockerfile.qbraid \ + -t us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid/lab-code-server:latest \ + --push \ + . +``` + +## Customizing Settings + +You can modify the default settings by editing `Dockerfile.qbraid`: + +### User Settings Location +Lines 32-48 in `Dockerfile.qbraid` contain the user settings JSON. + +### Machine Settings Location +Lines 51-56 in `Dockerfile.qbraid` contain the machine settings JSON. + +### Adding More Extensions + +To add additional extensions, either: + +1. **Add VSIX files** to the `extensions/` directory (recommended) +2. **Install from marketplace** by adding to the Dockerfile: + +```dockerfile +RUN code-server --install-extension ms-python.python +RUN code-server --install-extension ms-vscode.vscode-json +``` + +### Creating VSIX Files + +If you have custom extensions to package: + +```bash +# Copy the generated .vsix file to the extensions directory +cp your-extension-1.0.0.vsix ../code-server/extensions/ +``` + +## Troubleshooting + +### Docker Buildx Issues +If you encounter buildx issues: + +```bash +# Reset buildx +docker buildx rm qbraid-builder +docker buildx create --name qbraid-builder --use + +# Or use default builder +docker buildx use default +``` + +### Platform Compatibility Issues +If the image doesn't work on your target platform: + +1. Verify the target platform: `docker inspect --format='{{.Architecture}}' your-image` +2. Check if your target supports the built architecture +3. Rebuild for the correct platform using the manual build process + +### Build Fails with Architecture Errors +On Apple Silicon Macs, if you see architecture warnings: + +1. The build script automatically handles this with `--platform=linux/amd64` +2. This ensures compatibility with most Kubernetes clusters +3. The image will work correctly even though built on ARM64 + +### Authentication Issues + +#### Can't Access Code-Server (Stuck on Login) +The image is configured with no authentication by default. If you're seeing a login screen: + +1. Check if you're overriding with environment variables +2. Verify the container is using the correct entrypoint +3. Check container logs: `docker logs ` + +#### Want to Add Authentication Back +Follow the [Security Configuration](#security-configuration) section above. + +### Extensions Not Loading +1. Verify VSIX files exist in the `extensions/` directory +2. Check that VSIX files are valid (not corrupted) +3. Ensure `.dockerignore` includes `!extensions` (already configured) +4. Look at container logs for extension installation errors +5. Ensure extensions are compatible with the code-server version + +### Settings Not Applied +Settings are baked into the image and will be the defaults for new users. Existing user settings in persistent volumes will override these defaults. + +## File Structure + +```bash +code-server/ +├── build-qbraid-docker.sh # Build script with buildx support +├── Dockerfile.qbraid # Custom Dockerfile (no auth by default) +├── .dockerignore # Updated to include extensions +├── extensions/ # QBraid extensions directory +│ ├── environment-manager-0.1.0.vsix +│ └── quantum-console-0.2.2.vsix +├── QBRAID_BUILD_README.md # This file +└── ... (other code-server files) +``` + +## Support + +For issues specific to the QBraid customizations, check: +1. Extension VSIX files exist and are valid +2. Docker buildx is properly installed and configured +3. Target platform compatibility +4. Authentication configuration (if login issues occur) +5. Network connectivity for registry push + +For general code-server issues, refer to the main code-server documentation. \ No newline at end of file diff --git a/build-qbraid-docker.sh b/build-qbraid-docker.sh new file mode 100644 index 000000000000..1a6d1bf934de --- /dev/null +++ b/build-qbraid-docker.sh @@ -0,0 +1,123 @@ +#!/bin/bash +set -euo pipefail + +# QBraid Code-Server Docker Build Script +echo "=== QBraid Code-Server Docker Build Script ===" + +# Configuration +REGISTRY="us-central1-docker.pkg.dev/qbraid-lab-gke/staging-qbraid" +IMAGE_NAME="lab-code-server" +TAG=${1:-latest} +FULL_IMAGE_NAME="${REGISTRY}/${IMAGE_NAME}:${TAG}" +PLATFORM="linux/amd64" + +echo "Building image: ${FULL_IMAGE_NAME}" +echo "Target platform: ${PLATFORM}" + +# Check if logo-square.png exists +if [ ! -f "logo-square.png" ]; then + echo "⚠️ Warning: logo-square.png not found!" + echo " Please add your QBraid logo file as 'logo-square.png' in this directory." + echo " The build will continue, but the default favicon will be used." + echo "" + + # Create a temporary placeholder file to avoid Docker COPY errors + touch logo-square.png.placeholder +fi + +# Check if extensions directory exists and has VSIX files +if [ ! -d "extensions" ] || [ -z "$(find extensions -name "*.vsix" -type f)" ]; then + echo "⚠️ Warning: No QBraid extensions found!" + echo " Expected VSIX files in the 'extensions/' directory." + echo " The build will continue, but QBraid extensions won't be pre-installed." + echo "" + + # Create placeholder extensions directory to avoid Docker COPY errors + mkdir -p extensions + touch extensions/.placeholder +else + echo "✅ Found QBraid extensions:" + find extensions -name "*.vsix" -type f -exec basename {} \; + echo "" +fi + +# Function to cleanup +cleanup() { + if [ -f "logo-square.png.placeholder" ]; then + rm -f logo-square.png.placeholder + fi + if [ -f "extensions/.placeholder" ]; then + rm -f extensions/.placeholder + if [ -d "extensions" ] && [ -z "$(ls -A extensions)" ]; then + rmdir extensions + fi + fi +} +trap cleanup EXIT + +echo "Step 1: Building custom QBraid Docker image..." +echo "Using simplified approach - layering customizations on existing code-server image" + +# Ensure buildx is available and create builder if needed +echo "Setting up Docker buildx..." +docker buildx inspect qbraid-builder >/dev/null 2>&1 || docker buildx create --name qbraid-builder --use +docker buildx use qbraid-builder + +# Build the custom Docker image with specific platform +echo "Building for platform: ${PLATFORM}" +docker buildx build --load \ + --platform="${PLATFORM}" \ + -f Dockerfile.qbraid \ + -t "${FULL_IMAGE_NAME}" \ + --load \ + . + +echo "✅ Docker image built successfully: ${FULL_IMAGE_NAME}" + +# Ask user if they want to push +read -p "Do you want to push the image to Google Cloud Artifact Registry? (y/N): " -n 1 -r +echo +if [[ $REPLY =~ ^[Yy]$ ]]; then + echo "Step 2: Pushing to Google Cloud Artifact Registry..." + + # Check if user is authenticated + if ! gcloud auth list --filter=status:ACTIVE --format="value(account)" | grep -q "@"; then + echo "❌ Error: Not authenticated with Google Cloud" + echo " Please run: gcloud auth login" + exit 1 + fi + + # Configure Docker for Artifact Registry + gcloud auth configure-docker us-central1-docker.pkg.dev --quiet + + # Push the image + docker push "${FULL_IMAGE_NAME}" + + echo "✅ Image pushed successfully!" + echo "🚀 Your custom QBraid Code-Server is now available at:" + echo " ${FULL_IMAGE_NAME}" +else + echo "Skipping push. You can push later with:" + echo " docker push ${FULL_IMAGE_NAME}" +fi + +echo "" +echo "=== Build Complete ===" +echo "To run the container locally (no password required):" +echo " docker run -it --rm -p 8080:8080 ${FULL_IMAGE_NAME}" +echo " Then open: http://localhost:8080" +echo "" +echo "To use in Kubernetes:" +echo " image: ${FULL_IMAGE_NAME}" +echo "" +echo "Platform built for: ${PLATFORM}" +echo "Features included in your custom build:" +echo " • No authentication required - direct access to code-server" +echo " • Custom QBraid favicon (if logo-square.png was provided)" +echo " • Pre-configured VS Code settings optimized for development" +echo " • Pre-installed QBraid extensions (if VSIX files were provided)" +echo " • Python development environment" +echo " • Disabled telemetry and auto-updates" +echo "" +echo "This build uses the official code-server image as a base and layers" +echo "your QBraid customizations on top for reliability and simplicity." \ No newline at end of file diff --git a/ci/release-image/Dockerfile b/ci/release-image/Dockerfile index fba7189e6999..c5cbf3e1eb2b 100644 --- a/ci/release-image/Dockerfile +++ b/ci/release-image/Dockerfile @@ -31,6 +31,10 @@ RUN sed -i "s/# en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen \ && locale-gen ENV LANG=en_US.UTF-8 +# Set environment variables for user and home directory +ENV NB_UID=1000 +ENV HOME=/home/coder + RUN if grep -q 1000 /etc/passwd; then \ userdel -r "$(id -un 1000)"; \ fi \ @@ -51,11 +55,14 @@ RUN --mount=from=packages,src=/tmp,dst=/tmp/packages dpkg -i /tmp/packages/code- # https://github.com/coder/code-server/issues/5177 ENV ENTRYPOINTD=${HOME}/entrypoint.d +# Disable authentication by setting empty password +ENV PASSWORD="" + EXPOSE 8080 # This way, if someone sets $DOCKER_USER, docker-exec will still work as # the uid will remain the same. note: only relevant if -u isn't passed to # docker-run. -USER 1000 +USER ${NB_UID} ENV USER=coder -WORKDIR /home/coder -ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "."] +WORKDIR ${HOME} +ENTRYPOINT ["/usr/bin/entrypoint.sh", "--bind-addr", "0.0.0.0:8080", "--auth", "none", "."] diff --git a/extensions/environment-manager-0.1.0.vsix b/extensions/environment-manager-0.1.0.vsix new file mode 100644 index 000000000000..8e6d6fc92b2c Binary files /dev/null and b/extensions/environment-manager-0.1.0.vsix differ diff --git a/extensions/quantum-console-0.2.2.vsix b/extensions/quantum-console-0.2.2.vsix new file mode 100644 index 000000000000..eb509ab52fc3 Binary files /dev/null and b/extensions/quantum-console-0.2.2.vsix differ diff --git a/install-qbraid-extensions.sh b/install-qbraid-extensions.sh new file mode 100644 index 000000000000..b7822aa62331 --- /dev/null +++ b/install-qbraid-extensions.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "Installing QBraid extensions..." + +# Wait a moment for code-server to be ready +sleep 2 + +# Install extensions if they exist +for ext in /opt/qbraid-extensions/*.vsix; do + if [ -f "$ext" ]; then + ext_name=$(basename "$ext") + echo "Installing extension: $ext_name" + + # Install the extension directly - code-server handles duplicates gracefully + if code-server --install-extension "$ext"; then + echo "Successfully installed $ext_name" + else + echo "Failed to install $ext_name" + fi + fi +done + +echo "QBraid extensions installation complete." \ No newline at end of file diff --git a/logo-square.png b/logo-square.png new file mode 100644 index 000000000000..f55dad8f69cd Binary files /dev/null and b/logo-square.png differ