From 020ae8eea066f6ea4e8c2541aa7ed128b0e37d33 Mon Sep 17 00:00:00 2001 From: Karim Elmaaroufi Date: Mon, 2 Mar 2026 23:12:37 -0800 Subject: [PATCH] feat: Add Dev Containers support for all Ryzer containers - Enable VS Code Dev Containers extension attachment to any running Ryzer container - Add named containers with ryzer- prefix for consistent identification - Include Dev Containers labels for VS Code recognition - Auto-create /workspace directory for Dev Containers compatibility - Remove --rm flag to allow persistent containers for attachment - Add comprehensive documentation in docs/dev-containers.md - Provide .devcontainer/devcontainer.json reference configuration This allows developers to attach VS Code to any Ryzer container (LLM, Vision, Robotics, Graphics, etc.) using the Docker extension for full IDE experience inside the containerized environment. --- .devcontainer/devcontainer.json | 25 ++++ docs/dev-containers.md | 249 ++++++++++++++++++++++++++++++++ ryzers/runner.py | 30 +++- 3 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/devcontainer.json create mode 100644 docs/dev-containers.md diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..06d5292 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,25 @@ +{ + "name": "Ryzers Development Container", + "workspaceFolder": "/workspace", + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-azuretools.vscode-docker", + "ms-vscode.cmake-tools", + "twxs.cmake" + ], + "settings": { + "python.defaultInterpreterPath": "/opt/venv/bin/python", + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "terminal.integrated.defaultProfile.linux": "bash" + } + } + }, + "remoteUser": "root", + "mounts": [ + "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached" + ] +} diff --git a/docs/dev-containers.md b/docs/dev-containers.md new file mode 100644 index 0000000..776c7ae --- /dev/null +++ b/docs/dev-containers.md @@ -0,0 +1,249 @@ +# Dev Containers Support for Ryzers + +Ryzers now supports attaching to running containers using VS Code's Dev Containers extension or Docker extension. + +## Overview + +When you build a Ryzer container, the system automatically configures it to be compatible with VS Code's container attachment features. This allows you to: + +- Attach VS Code directly to running Ryzer containers +- Use the full IDE experience inside the container +- Access all container resources and mounted volumes +- Debug and develop directly in the containerized environment + +## How It Works + +### Automatic Configuration + +When you run `ryzers build`, the system generates a run script that: + +1. **Removes the `--rm` flag** - Containers persist after exit, allowing attachment +2. **Adds a named container** - Format: `ryzer-` +3. **Adds Dev Containers labels** - Helps VS Code identify the container +4. **Checks for existing containers** - Automatically removes old instances before starting new ones + +### Container Naming + +Containers are named with the prefix `ryzer-` followed by your image name: +- Image: `ryzerdocker` → Container: `ryzer-ryzerdocker` +- Image: `my-custom-build` → Container: `ryzer-my-custom-build` + +## Usage + +### Method 1: VS Code Docker Extension (Recommended) + +1. **Install the Docker extension**: + - Open VS Code Extensions (Ctrl+Shift+X) + - Search for "Docker" by Microsoft + - Install the extension + +2. **Start your Ryzer container**: + ```bash + ryzers build ros o3de rai ollama + ryzers run bash + ``` + +3. **Attach VS Code**: + - Open the Docker panel in VS Code (Ctrl+Shift+D or click Docker icon) + - Find your container under "Containers" (e.g., `ryzer-ryzerdocker`) + - Right-click → "Attach Visual Studio Code" + - A new VS Code window opens connected to the container + +4. **Start developing**: + - Open folders inside the container (e.g., `/ryzers/rai`) + - Edit files, run terminals, debug - all inside the container + - Access mounted volumes like `/ryzers/rai/src/rai_bench/rai_bench/experiments` + +### Method 2: Dev Containers Extension + +1. **Install the Dev Containers extension**: + - Open VS Code Extensions (Ctrl+Shift+X) + - Search for "Dev Containers" by Microsoft + - Install the extension + +2. **Start your Ryzer container**: + ```bash + ryzers run bash + ``` + +3. **Attach using Command Palette**: + - Press F1 or Ctrl+Shift+P + - Type "Dev Containers: Attach to Running Container" + - Select your container from the list (e.g., `ryzer-ryzerdocker`) + +### Method 3: Docker CLI + +For quick terminal access without VS Code: + +```bash +# List running containers +docker ps + +# Attach to your Ryzer container +docker exec -it ryzer-ryzerdocker bash + +# Or use the container name pattern +docker exec -it $(docker ps --filter "name=ryzer-" --format "{{.Names}}") bash +``` + +## Container Management + +### Viewing Running Containers + +```bash +# List all Ryzer containers +docker ps --filter "name=ryzer-" + +# List all containers (including stopped) +docker ps -a --filter "name=ryzer-" +``` + +### Stopping Containers + +```bash +# Stop a specific container +docker stop ryzer-ryzerdocker + +# Stop all Ryzer containers +docker stop $(docker ps --filter "name=ryzer-" --format "{{.Names}}") +``` + +### Removing Containers + +```bash +# Remove a specific container +docker rm ryzer-ryzerdocker + +# Remove all stopped Ryzer containers +docker rm $(docker ps -a --filter "name=ryzer-" --format "{{.Names}}") +``` + +The run script automatically removes existing containers with the same name before starting, so you typically don't need to manually clean up. + +## Configuration + +### Custom Dev Container Settings + +A default `.devcontainer/devcontainer.json` file is provided in the repository root. You can customize it for your workflow: + +```json +{ + "name": "Ryzers Development Container", + "workspaceFolder": "/workspace", + "customizations": { + "vscode": { + "extensions": [ + "ms-python.python", + "ms-azuretools.vscode-docker" + ], + "settings": { + "python.defaultInterpreterPath": "/opt/venv/bin/python" + } + } + } +} +``` + +### Package-Specific Configurations + +Each package's `config.yaml` can specify: +- Port mappings (accessible from host) +- Volume mappings (shared directories) +- Environment variables +- GPU/X11 support + +These are automatically included in the container configuration. + +## Troubleshooting + +### Container Not Appearing in VS Code + +1. Ensure the container is running: `docker ps --filter "name=ryzer-"` +2. Refresh the Docker extension view +3. Check container logs: `docker logs ryzer-ryzerdocker` + +### Permission Issues + +If you encounter permission errors: +```bash +# The container runs as root by default +# Files created in mounted volumes will be owned by root +# Use chown on the host if needed: +sudo chown -R $USER:$USER ./experiments +``` + +### X11 Display Issues + +If GUI applications don't work after attaching: +```bash +# Inside the container, ensure DISPLAY is set +echo $DISPLAY + +# On host, ensure X11 forwarding is enabled +xhost +local:docker +``` + +### Container Keeps Restarting + +If you run `ryzers run bash` and the container exits immediately: +- The `bash` command requires interactive mode (`-it` flag is included) +- Check if there are errors in the container logs +- Try running without the `bash` override to use the default CMD + +## Best Practices + +1. **Use named builds** for different projects: + ```bash + ryzers build --name my-project ros rai + ryzers run --name my-project bash + ``` + +2. **Mount your workspace** for persistent changes: + - Add volume mappings in package `config.yaml` + - Or use `docker run -v` flags in the generated script + +3. **Stop containers when done** to free resources: + ```bash + docker stop ryzer-ryzerdocker + ``` + +4. **Use the Docker extension** for visual container management + +## Examples + +### Attaching to RAI Benchmark Container + +```bash +# Build with all dependencies +ryzers build ros o3de rai ollama + +# Run with bash to keep container alive +ryzers run bash + +# In VS Code: +# 1. Open Docker panel +# 2. Right-click "ryzer-ryzerdocker" +# 3. Select "Attach Visual Studio Code" +# 4. Open folder: /ryzers/rai +# 5. Edit benchmark scripts, run tests, etc. +``` + +### Multiple Containers for Different Projects + +```bash +# Build different configurations +ryzers build --name rai-dev ros rai +ryzers build --name genesis-sim genesis + +# Run both +ryzers run --name rai-dev bash & +ryzers run --name genesis-sim bash & + +# Attach to each in separate VS Code windows +``` + +## See Also + +- [VS Code Dev Containers Documentation](https://code.visualstudio.com/docs/devcontainers/containers) +- [Docker Extension Documentation](https://code.visualstudio.com/docs/containers/overview) +- [Ryzers Build Documentation](../README.md) diff --git a/ryzers/runner.py b/ryzers/runner.py index 1acfefe..b89028b 100644 --- a/ryzers/runner.py +++ b/ryzers/runner.py @@ -58,14 +58,39 @@ def build_runscript(self, runflags, docker_cmd=""): Returns: str: The path to the generated bash script. """ + # Remove --rm flag to allow Dev Containers to attach + runflags_clean = ' '.join(flag for flag in runflags.split() if flag != '--rm') + + # Add Dev Containers compatible labels and named container + devcontainer_flags = ( + f"--name ryzer-{self.container_name} " + f"--label devcontainer.local_folder={os.getcwd()} " + f"--label devcontainer.config_file=.devcontainer/devcontainer.json" + ) + # Generate the bash script script_content = f"""#!/bin/bash # Auto-generated script to run Docker with combined flags +# Supports Dev Containers attachment # Enable X11 forwarding xhost +local:docker -docker run {runflags} {self.container_name} $1 +# Remove existing container if it exists +if docker ps -a --format '{{{{.Names}}}}' | grep -q "^ryzer-{self.container_name}$"; then + echo "Removing existing container: ryzer-{self.container_name}" + docker rm -f ryzer-{self.container_name} +fi + +# Start container with Dev Containers support +echo "Starting container: ryzer-{self.container_name}..." +if [ ! -z "$1" ]; then + # Interactive mode with command + docker run -it {devcontainer_flags} {runflags_clean} {self.container_name} bash -c "mkdir -p /workspace && exec $1" +else + # Daemon mode for Dev Containers attachment + docker run -d {devcontainer_flags} {runflags_clean} {self.container_name} bash -c "mkdir -p /workspace && tail -f /dev/null" +fi """ # Write the script to the specified file @@ -80,6 +105,9 @@ def build_runscript(self, runflags, docker_cmd=""): print(f"ryzers run [CMD_OVERRIDE] # will run last ryzer docker built.\n") print(f"# Run this ryzer docker by name:") print(f"ryzers run --name {self.container_name} [CMD_OVERRIDE]\n") + print(f"\n** Dev Containers Support Enabled **") + print(f"Container name: ryzer-{self.container_name}") + print(f"To attach with VS Code Docker extension: Right-click container → 'Attach Visual Studio Code'") print("\nTo inspect the docker run call, see contents of the script file: ") print(f"cat {self.script_name}")