diff --git a/.devcontainer/allowed-domains.txt.example b/.devcontainer/allowed-domains.txt.example index 6525014..f169a53 100644 --- a/.devcontainer/allowed-domains.txt.example +++ b/.devcontainer/allowed-domains.txt.example @@ -1,6 +1,13 @@ # Custom Allowed Domains and IP Ranges # Copy this file to 'allowed-domains.txt' in your project root to add custom allowed domains/IPs # +# Note: The following domains are already allowed by default: +# - GitHub (all necessary endpoints) +# - npm registry +# - Anthropic API +# - 1Password services (all regions: .com, .eu, .ca) +# - Docker Hub +# # Format: # - One entry per line # - Domain names will be resolved to IPs (e.g., example.com) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 0be647a..8f235cb 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -7,12 +7,8 @@ services: # Timezone - TZ=${TZ:-UTC} - # 1Password Configuration + # 1Password Configuration - only pass if set - OP_SERVICE_ACCOUNT_TOKEN=${OP_SERVICE_ACCOUNT_TOKEN:-} - - OP_CREATE_SERVICE_ACCOUNT=${OP_CREATE_SERVICE_ACCOUNT:-false} - - OP_SA_EXPIRES_IN=${OP_SA_EXPIRES_IN:-30d} - - OP_SA_VAULTS=${OP_SA_VAULTS:-} - - OP_SA_NAME=${OP_SA_NAME:-} - OP_CONNECT_HOST=${OP_CONNECT_HOST:-} - OP_CONNECT_TOKEN=${OP_CONNECT_TOKEN:-} diff --git a/.github/workflows/publish-templates.yml b/.github/workflows/publish-templates.yml new file mode 100644 index 0000000..7282690 --- /dev/null +++ b/.github/workflows/publish-templates.yml @@ -0,0 +1,47 @@ +name: Publish Dev Container Templates + +on: + push: + branches: + - main + paths: + - 'src/**' + workflow_dispatch: + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Install Dev Container CLI + run: npm install -g @devcontainers/cli + + - name: Publish Templates + run: | + # Publish the template to ghcr.io + devcontainer templates publish \ + --registry ghcr.io \ + --namespace ${{ github.repository_owner }}/templates \ + ./src + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Verify Published Template + run: | + echo "Template published to: ghcr.io/${{ github.repository_owner }}/templates/liquescent-devcontainer" + echo "" + echo "Users can now apply it with:" + echo " devcontainer templates apply --template-id ghcr.io/${{ github.repository_owner }}/templates/liquescent-devcontainer" \ No newline at end of file diff --git a/README.md b/README.md index 26e3f23..848c1a4 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,22 @@ A secure, polyglot development container with network isolation, comprehensive language support, and enterprise-grade secret management. +## 📦 Distribution Methods + +This repository provides two ways to use our development container: + +### 1. **Pre-built Docker Image** (Recommended for speed) +- Ready-to-use image from GitHub Container Registry +- No build time required +- Automatic updates when we publish new versions +- Image: `ghcr.io/liquescent-development/devcontainer:latest` + +### 2. **Dev Container Template** (Recommended for customization) +- Spec-compliant template you can add to any project +- Customize the configuration for your specific needs +- Located in `src/liquescent-devcontainer/` +- Can be distributed via OCI registry as a template + ## 🔒 Key Features ### Security & Network Isolation @@ -36,9 +52,9 @@ A secure, polyglot development container with network isolation, comprehensive l - VS Code with Dev Containers extension - Git -### Setup +### Option 1: Using Pre-built Image (Fastest) -1. **Clone this repository or copy `devcontainer.json`** to your project's `.devcontainer` folder +1. **Copy the `.devcontainer` folder** from this repository to your project 2. **Configure your environment**: ```bash @@ -54,6 +70,33 @@ A secure, polyglot development container with network isolation, comprehensive l The container will automatically pull from `ghcr.io/liquescent-development/devcontainer:latest`. +### Option 2: Using as a Template (Most Flexible) + +1. **Install the Dev Container CLI** (if not using VS Code): + ```bash + npm install -g @devcontainers/cli + ``` + +2. **Apply the template to your project**: + + From this repository: + ```bash + devcontainer templates apply \ + --workspace-folder . \ + --template-id ./src/liquescent-devcontainer + ``` + + Or from the published template (when available): + ```bash + devcontainer templates apply \ + --workspace-folder . \ + --template-id ghcr.io/liquescent-development/templates/liquescent-devcontainer + ``` + +3. **Configure and customize** as needed + +4. **Open in your preferred tool** (VS Code, CLI, etc.) + ## ⚙️ Configuration ### Environment Variables @@ -88,6 +131,7 @@ By default, only these domains are accessible: - npm registry (registry.npmjs.org) - Anthropic API (api.anthropic.com) - Docker Hub (hub.docker.com) +- 1Password (*.1password.com, *.1password.eu, *.1password.ca, *.1passwordservices.com) #### Adding Custom Domains diff --git a/TEMPLATE_USAGE.md b/TEMPLATE_USAGE.md deleted file mode 100644 index b6a19a3..0000000 --- a/TEMPLATE_USAGE.md +++ /dev/null @@ -1,190 +0,0 @@ -# Template Customization Guide - -This guide helps you customize the devcontainer template for your specific project needs after using it as a template. - -## Common Customizations - -### 1. Change Node.js Version -Edit `.devcontainer/Dockerfile`: -```dockerfile -# Change from Node 20 to another version -FROM node:18 # or node:22, node:16, etc. -``` - -### 2. Add Additional Allowed Domains -Edit `.devcontainer/init-firewall.sh` to add more domains to the allowed list: -```bash -# Add your domain to this list -for domain in \ - "registry.npmjs.org" \ - "api.anthropic.com" \ - "your-api.example.com" \ # Add your domain here - "sentry.io" \ - ... -``` - -### 3. Install Additional Development Tools -Edit `.devcontainer/Dockerfile` to add more tools: -```dockerfile -# Add to the apt-get install section -RUN apt-get update && apt-get install -y --no-install-recommends \ - ... existing packages ... \ - postgresql-client \ # Add database clients - redis-tools \ # Add Redis tools - && apt-get clean && rm -rf /var/lib/apt/lists/* -``` - -Note: Go, Rust, .NET, and Python are already included in the base template. - -### 4. Customize oh-my-zsh Plugins -Edit `.devcontainer/Dockerfile` in the zsh configuration section: -```bash -# The template includes language-specific plugins by default: -# plugins=(git docker docker-compose npm node golang rust python dotnet fzf ...) -# You can add additional plugins like kubectl, terraform, etc. -echo 'plugins=(git fzf npm docker golang rust python dotnet kubectl terraform)' >> ~/.zshrc -``` - -### 5. Add Project-Specific VS Code Extensions -Edit `.devcontainer/devcontainer.json`: -```json -"extensions": [ - "dbaeumer.vscode-eslint", - "esbenp.prettier-vscode", - "eamodio.gitlens", - "your.extension-id" // Add your extensions -] -``` - -### 6. Set Project-Specific Environment Variables -Edit `.devcontainer/devcontainer.json`: -```json -"containerEnv": { - "NODE_OPTIONS": "--max-old-space-size=4096", - "CLAUDE_CONFIG_DIR": "/home/node/.claude", - "YOUR_ENV_VAR": "value" // Add your variables -} -``` - -### 7. Customize the oh-my-posh Theme -Modify `.devcontainer/liquescent.omp.json` or create your own theme file and update the Dockerfile: -```bash -# Copy your theme in Dockerfile -COPY your-theme.omp.json /usr/local/share/ -# Then update the zshrc configuration to point to it -echo 'eval "$(oh-my-posh init zsh --config /usr/local/share/your-theme.omp.json)"' >> ~/.zshrc -``` - -### 8. Add Database or Service Containers -Create a `.devcontainer/docker-compose.yml`: -```yaml -version: '3.8' -services: - devcontainer: - build: - context: . - dockerfile: Dockerfile - # ... existing config ... - - postgres: - image: postgres:15 - environment: - POSTGRES_PASSWORD: postgres - # ... additional config ... -``` - -Then update `devcontainer.json`: -```json -{ - "dockerComposeFile": "docker-compose.yml", - "service": "devcontainer", - // ... rest of config -} -``` - -### For .NET Projects -- .NET SDK 8.0 is already installed with telemetry disabled -- Install C# and .NET-specific VS Code extensions -- Configure project templates and NuGet sources as needed -- DOTNET_ROOT is pre-configured at `/usr/local/dotnet` - -## Project-Specific Configurations - -### For React/Next.js Projects -- Add port forwarding in `devcontainer.json`: - ```json - "forwardPorts": [3000, 3001] - ``` -- Install React DevTools extension - -### For Python Projects -- Python 3 is already included with common tools (pipenv, poetry, black, pylint, pytest) -- Install Python-specific VS Code extensions -- Configure virtual environments as needed -- Add pip package caching if needed - -### For Go Projects -- Go 1.25.0 is already installed with GOPATH configured -- Install Go-specific VS Code extensions (Go extension by Google) -- Configure module proxy if needed for private modules -- GOPATH is pre-configured at `/home/node/go` - -### For Rust Projects -- Rust is already installed with common cargo tools (cargo-watch, cargo-edit, cargo-audit, cargo-outdated) -- Install Rust-specific VS Code extensions (rust-analyzer) -- Configure cargo caching if needed -- All Rust tools are available in PATH - -## Removing Features - -### Remove Network Isolation -If you don't need the firewall: -1. Remove `postCreateCommand` from `devcontainer.json` -2. Remove `runArgs` for NET_ADMIN and NET_RAW capabilities -3. Delete `init-firewall.sh` - -### Remove SOCKS5 Proxy Support -Remove the `--add-host=host.docker.internal:host-gateway` line from `runArgs` in `devcontainer.json` - -### Use Different Shell Configuration -Replace the oh-my-zsh/oh-my-posh setup in the Dockerfile with your preferred shell configuration. - -## Testing Your Customizations - -1. **Build locally first**: - ```bash - docker build -t my-devcontainer .devcontainer/ - ``` - -2. **Test in VS Code**: - - Open your project - - Run "Dev Containers: Rebuild Container" - -3. **Verify customizations**: - - Check installed tools - - Test network access - - Verify environment variables - -## Maintaining Your Fork - -If you want to stay updated with the upstream template: - -1. Add the original template as upstream: - ```bash - git remote add upstream https://github.com/original/devcontainer.git - ``` - -2. Fetch and merge updates: - ```bash - git fetch upstream - git merge upstream/main --allow-unrelated-histories - ``` - -3. Resolve any conflicts with your customizations - -## Getting Help - -- Check the main README.md for troubleshooting -- Review CLAUDE.md for architecture details -- Open an issue in your repository for project-specific problems -- Refer to the [VS Code Dev Containers documentation](https://code.visualstudio.com/docs/devcontainers/containers) \ No newline at end of file diff --git a/docker-image/scripts/init-firewall.sh b/docker-image/scripts/init-firewall.sh index ee6bb98..2ec015a 100644 --- a/docker-image/scripts/init-firewall.sh +++ b/docker-image/scripts/init-firewall.sh @@ -76,6 +76,47 @@ for domain in \ done < <(echo "$ips") done +# Resolve and add 1Password domains (required for 1Password CLI to function) +# Based on: https://support.1password.com/ports-domains/ +echo "Configuring 1Password domains..." +# Common 1Password subdomains across all regions (.com, .eu, .ca) +onepassword_subdomains="1password my.1password app.1password api.1password events.1password b5n.1password" +onepassword_tlds="com eu ca" + +for subdomain in $onepassword_subdomains; do + for tld in $onepassword_tlds; do + domain="${subdomain}.${tld}" + echo "Resolving $domain..." + # Use timeout and don't fail if a regional domain doesn't exist + ips=$(timeout 2 dig +noall +answer A "$domain" 2>/dev/null | awk '$4 == "A" {print $5}') + if [ -n "$ips" ]; then + while read -r ip; do + if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + echo " Adding $ip" + ipset add allowed-domains "$ip" 2>/dev/null || true + fi + done < <(echo "$ips") + fi + done +done + +# Additional 1Password service domains +for domain in \ + "cache.agilebits.com" \ + "c.1passwordservices.com" \ + "app.1passwordusercontent.com"; do + echo "Resolving $domain..." + ips=$(timeout 2 dig +noall +answer A "$domain" 2>/dev/null | awk '$4 == "A" {print $5}') + if [ -n "$ips" ]; then + while read -r ip; do + if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then + echo " Adding $ip" + ipset add allowed-domains "$ip" 2>/dev/null || true + fi + done < <(echo "$ips") + fi +done + # Process environment variable domains (from .env file via Docker Compose) if [ -n "${CUSTOM_ALLOWED_DOMAINS:-}" ]; then echo "Processing custom allowed domains from CUSTOM_ALLOWED_DOMAINS environment variable..." diff --git a/docker-image/scripts/setup-1password.sh b/docker-image/scripts/setup-1password.sh index 278e80f..2ca0f63 100644 --- a/docker-image/scripts/setup-1password.sh +++ b/docker-image/scripts/setup-1password.sh @@ -6,6 +6,25 @@ set -e echo "🔐 Checking 1Password CLI authentication..." +# Unset empty Connect variables to prevent interference with service account token +# The 1Password CLI checks if these variables exist, not if they have values +if [ -z "$OP_CONNECT_HOST" ]; then + unset OP_CONNECT_HOST +fi +if [ -z "$OP_CONNECT_TOKEN" ]; then + unset OP_CONNECT_TOKEN +fi + +# Also update the shell RC files to ensure they're unset in new shells +if [ -z "${OP_CONNECT_HOST:-}" ]; then + echo "unset OP_CONNECT_HOST 2>/dev/null || true" >> ~/.bashrc + echo "unset OP_CONNECT_HOST 2>/dev/null || true" >> ~/.zshrc +fi +if [ -z "${OP_CONNECT_TOKEN:-}" ]; then + echo "unset OP_CONNECT_TOKEN 2>/dev/null || true" >> ~/.bashrc + echo "unset OP_CONNECT_TOKEN 2>/dev/null || true" >> ~/.zshrc +fi + # Check if we already have a service account token if [ -n "$OP_SERVICE_ACCOUNT_TOKEN" ]; then echo "✅ Using 1Password service account token" @@ -19,8 +38,8 @@ if [ -n "$OP_SERVICE_ACCOUNT_TOKEN" ]; then fi fi -# Check for Connect Server configuration -if [ -n "$OP_CONNECT_HOST" ] && [ -n "$OP_CONNECT_TOKEN" ]; then +# Check for Connect Server configuration (only if both values are non-empty) +if [ -n "${OP_CONNECT_HOST:-}" ] && [ -n "${OP_CONNECT_TOKEN:-}" ]; then echo "✅ Using 1Password Connect Server at $OP_CONNECT_HOST" # Test the connection if op vault list &>/dev/null; then diff --git a/src/devcontainer-collection.json b/src/devcontainer-collection.json new file mode 100644 index 0000000..48e7a22 --- /dev/null +++ b/src/devcontainer-collection.json @@ -0,0 +1,9 @@ +{ + "name": "Liquescent Development Templates", + "description": "A collection of secure, enterprise-grade development container templates by Liquescent Development", + "publisher": "Liquescent Development", + "ref": "https://github.com/Liquescent-Development/devcontainer", + "templates": [ + "liquescent-devcontainer" + ] +} \ No newline at end of file diff --git a/src/liquescent-devcontainer/.devcontainer/.env.example b/src/liquescent-devcontainer/.devcontainer/.env.example new file mode 100644 index 0000000..664891a --- /dev/null +++ b/src/liquescent-devcontainer/.devcontainer/.env.example @@ -0,0 +1,91 @@ +# DevContainer Configuration Options +# Copy this file to .env in your project root and customize as needed + +# Timezone Configuration +# Set your timezone (e.g., America/Phoenix, America/New_York, Europe/London) +# To find your timezone: ls /usr/share/zoneinfo/ +# If not set, defaults to UTC +TZ=America/Phoenix + +# Git Configuration Mounting +# Set to "true" to use your host's git config and SSH keys +# Set to "false" (default) for an isolated container environment +# +# When false: Run /usr/local/bin/create-limited-git-setup.sh after container starts +# When true: Your .gitconfig and .ssh are symlinked from host +# +# To enable: export MOUNT_HOST_GIT_CONFIG=true before opening in VS Code +MOUNT_HOST_GIT_CONFIG=false + +# ============================================================================ +# 1PASSWORD CLI CONFIGURATION +# ============================================================================ +# The 1Password CLI is pre-installed in the container. To authenticate it, +# you need to provide either a Service Account token or Connect Server credentials. + +# Option 1: Service Account Token (Recommended for DevContainers) +# --------------------------------------------------------------------------- +# Service accounts provide secure, scoped access without requiring interactive signin. +# +# To create a service account on your host machine: +# 1. Install 1Password CLI: https://developer.1password.com/docs/cli/get-started +# 2. Sign in to your account: op signin +# 3. Create a service account: +# op service-account create "devcontainer-$(basename $(pwd))" --expires-in 30d +# 4. Copy the token (starts with 'ops_') and paste it below +# +# For vault-specific access (more secure): +# op service-account create "my-dev" --expires-in 30d --vault Development:read_items +# +# The token will be securely passed to the container for CLI authentication. +OP_SERVICE_ACCOUNT_TOKEN= + +# Option 2: 1Password Connect Server (For Teams/Enterprise) +# --------------------------------------------------------------------------- +# Connect Server provides centralized access management for teams. +# Contact your IT admin for these values if using Connect Server. +# +# Server URL (e.g., https://connect.company.com) +OP_CONNECT_HOST= +# Connect token for authentication +OP_CONNECT_TOKEN= + +# ============================================================================ +# CUSTOM DOMAIN CONFIGURATION +# ============================================================================ +# Two ways to allow custom domains beyond the built-in ones (GitHub, npm, Anthropic): +# +# 1. CUSTOM_ALLOWED_DOMAINS (below) - Personal/temporary domains from .env +# - Stored in your .devcontainer/.env file (not committed to repo) +# - For personal/local services (e.g., local test servers, personal APIs) +# - Comma-separated list of domains (without https://) +# - Supports: domain names, IP addresses, and CIDR ranges +# +# 2. allowed-domains.txt file - Project-wide domains +# - Create file in .devcontainer/ folder (committed to repo) +# - For team-shared domains (e.g., company APIs, private registries) +# - One domain/IP per line, supports comments with # +# +# Example: CUSTOM_ALLOWED_DOMAINS=api.mycompany.com,staging.myapp.io,192.168.1.100 +CUSTOM_ALLOWED_DOMAINS= + +# ============================================================================ +# SOCKS5 PROXY CONFIGURATION +# ============================================================================ +# Configure access to a SOCKS5 proxy for routing traffic through a VPN or proxy server +# This is useful for accessing resources behind a corporate firewall or VPN + +# Enable/disable SOCKS5 proxy access (true/false) +SOCKS5_ENABLED=true + +# SOCKS5 proxy host (can be hostname or IP address) +# Default: host.docker.internal (your host machine) +# Examples: proxy.company.com, 192.168.1.100, host.docker.internal +SOCKS5_HOST=host.docker.internal + +# SOCKS5 proxy port +SOCKS5_PORT=1080 + +# To use the proxy in the container: +# curl --socks5 ${SOCKS5_HOST}:${SOCKS5_PORT} https://example.com +# git config --global http.proxy socks5://${SOCKS5_HOST}:${SOCKS5_PORT} \ No newline at end of file diff --git a/src/liquescent-devcontainer/.devcontainer/.gitignore b/src/liquescent-devcontainer/.devcontainer/.gitignore new file mode 100644 index 0000000..d73a9b3 --- /dev/null +++ b/src/liquescent-devcontainer/.devcontainer/.gitignore @@ -0,0 +1,9 @@ +# Environment file with personal settings +.env + +# Project-specific allowed domains (optional) +allowed-domains.txt + +# But keep the examples +!.env.example +!allowed-domains.txt.example \ No newline at end of file diff --git a/src/liquescent-devcontainer/.devcontainer/allowed-domains.txt.example b/src/liquescent-devcontainer/.devcontainer/allowed-domains.txt.example new file mode 100644 index 0000000..f169a53 --- /dev/null +++ b/src/liquescent-devcontainer/.devcontainer/allowed-domains.txt.example @@ -0,0 +1,58 @@ +# Custom Allowed Domains and IP Ranges +# Copy this file to 'allowed-domains.txt' in your project root to add custom allowed domains/IPs +# +# Note: The following domains are already allowed by default: +# - GitHub (all necessary endpoints) +# - npm registry +# - Anthropic API +# - 1Password services (all regions: .com, .eu, .ca) +# - Docker Hub +# +# Format: +# - One entry per line +# - Domain names will be resolved to IPs (e.g., example.com) +# - CIDR ranges are supported (e.g., 192.168.1.0/24) +# - Individual IPs are supported (e.g., 192.168.1.1) +# - Lines starting with # are comments +# - Empty lines are ignored +# +# Examples: + +# AWS Bedrock endpoints (uncomment regions you need) +# US Regions +# bedrock.us-east-1.amazonaws.com +# bedrock.us-west-2.amazonaws.com +# bedrock-runtime.us-east-1.amazonaws.com +# bedrock-runtime.us-west-2.amazonaws.com +# bedrock-agent.us-east-1.amazonaws.com +# bedrock-agent-runtime.us-east-1.amazonaws.com + +# Europe Regions +# bedrock.eu-west-1.amazonaws.com +# bedrock.eu-west-3.amazonaws.com +# bedrock.eu-central-1.amazonaws.com +# bedrock-runtime.eu-west-1.amazonaws.com +# bedrock-runtime.eu-west-3.amazonaws.com +# bedrock-runtime.eu-central-1.amazonaws.com + +# Asia Pacific Regions +# bedrock.ap-southeast-1.amazonaws.com +# bedrock.ap-southeast-2.amazonaws.com +# bedrock.ap-northeast-1.amazonaws.com +# bedrock-runtime.ap-southeast-1.amazonaws.com +# bedrock-runtime.ap-southeast-2.amazonaws.com +# bedrock-runtime.ap-northeast-1.amazonaws.com + +# AWS API Gateway +# execute-api.us-east-1.amazonaws.com + +# Custom API endpoints +# api.mycompany.com +# staging-api.mycompany.com + +# IP ranges for internal services +# 10.0.0.0/8 +# 172.16.0.0/12 + +# Individual IPs +# 203.0.113.42 \ No newline at end of file diff --git a/src/liquescent-devcontainer/.devcontainer/devcontainer.json b/src/liquescent-devcontainer/.devcontainer/devcontainer.json new file mode 100644 index 0000000..d7844b9 --- /dev/null +++ b/src/liquescent-devcontainer/.devcontainer/devcontainer.json @@ -0,0 +1,72 @@ +{ + "name": "Liquescent Development Environment", + // Uses Docker Compose to load .env file automatically + "dockerComposeFile": "docker-compose.yml", + "service": "devcontainer", + "workspaceFolder": "/workspace", + "customizations": { + "vscode": { + "extensions": [ + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode", + "eamodio.gitlens" + ], + "settings": { + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit" + }, + "terminal.integrated.defaultProfile.linux": "zsh", + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash", + "icon": "terminal-bash" + }, + "zsh": { + "path": "zsh" + } + } + } + } + }, + "features": { + "ghcr.io/devcontainers/features/go:1": { + "version": "1.23" + }, + "ghcr.io/devcontainers/features/python:1": { + "installTools": true, + "version": "3.12" + }, + "ghcr.io/devcontainers/features/rust:1": { + "version": "stable", + "profile": "default" + }, + "ghcr.io/devcontainers/features/dotnet:2": { + "version": "8.0", + "additionalVersions": "" + }, + "ghcr.io/devcontainers/features/github-cli:1": { + "version": "latest" + }, + "ghcr.io/itsmechlark/features/1password:1": { + "version": "latest" + } + }, + "remoteUser": "node", + "userEnvProbe": "loginInteractiveShell", + "updateRemoteUserUID": true, + "hostRequirements": { + "cpus": 2, + "memory": "4gb", + "storage": "32gb" + }, + "waitFor": "postCreateCommand", + "postCreateCommand": { + "firewall": "sudo /usr/local/bin/init-firewall.sh", + "git": "/usr/local/bin/setup-git.sh", + "1password": "/usr/local/bin/setup-1password.sh" + }, + "postStartCommand": { + "verify-1password": "op vault list 2>/dev/null || echo '⚠️ 1Password CLI not authenticated. Run setup-1password.sh for options.'" + } +} \ No newline at end of file diff --git a/src/liquescent-devcontainer/.devcontainer/docker-compose.yml b/src/liquescent-devcontainer/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..9f660fb --- /dev/null +++ b/src/liquescent-devcontainer/.devcontainer/docker-compose.yml @@ -0,0 +1,74 @@ +services: + devcontainer: + # Default to using pre-built image (can be overridden with docker-compose.dockerfile.yml) + image: ghcr.io/liquescent-development/devcontainer:latest + + # Environment variables from .env file are automatically loaded + environment: + # Timezone + - TZ=${TZ:-UTC} + + # 1Password Configuration - only pass if set + - OP_SERVICE_ACCOUNT_TOKEN=${OP_SERVICE_ACCOUNT_TOKEN:-} + - OP_CONNECT_HOST=${OP_CONNECT_HOST:-} + - OP_CONNECT_TOKEN=${OP_CONNECT_TOKEN:-} + + # Custom allowed domains for firewall + - CUSTOM_ALLOWED_DOMAINS=${CUSTOM_ALLOWED_DOMAINS:-} + + # SOCKS5 proxy configuration + - SOCKS5_ENABLED=${SOCKS5_ENABLED:-true} + - SOCKS5_HOST=${SOCKS5_HOST:-host.docker.internal} + - SOCKS5_PORT=${SOCKS5_PORT:-1080} + + # Git configuration mounting + - MOUNT_HOST_GIT_CONFIG=${MOUNT_HOST_GIT_CONFIG:-false} + + # Container environment + - NODE_OPTIONS=--max-old-space-size=4096 + - CLAUDE_CONFIG_DIR=/home/node/.claude + - SSH_AUTH_SOCK=/ssh-agent + - DEVCONTAINER=true + + volumes: + # Workspace + - ..:/workspace:cached + + # Claude configuration + - ${HOME}/.claude/agents:/home/node/.claude/agents:ro + - ${HOME}/.claude/CLAUDE.md:/home/node/.claude/CLAUDE.md:ro + - ${HOME}/.claude/settings.json:/home/node/.claude/settings.json:ro + + # Git configuration and SSH + - ${HOME}/.gitconfig:/home/node/.gitconfig.host:ro + - ${HOME}/.ssh:/home/node/.ssh-host:ro + + # SSH agent forwarding + - ${SSH_AUTH_SOCK:-/dev/null}:/ssh-agent + + # Command history persistence + - devcontainer-history:/commandhistory + + # Fonts (macOS specific path, will be ignored on other systems) + - ${HOME}/Library/Fonts:/usr/share/fonts/truetype/custom:ro + + # Network capabilities for firewall + cap_add: + - NET_ADMIN + - NET_RAW + + # Add host.docker.internal for accessing host services + extra_hosts: + - "host.docker.internal:host-gateway" + + # Keep container running + command: sleep infinity + + # Set working directory + working_dir: /workspace + + # Run as node user + user: node + +volumes: + devcontainer-history: \ No newline at end of file diff --git a/src/liquescent-devcontainer/README.md b/src/liquescent-devcontainer/README.md new file mode 100644 index 0000000..21b10f2 --- /dev/null +++ b/src/liquescent-devcontainer/README.md @@ -0,0 +1,58 @@ +# Liquescent Development Container Template + +A secure, polyglot development container template with network isolation, comprehensive language support, and enterprise-grade secret management. + +## 🚀 Quick Start + +This template can be used to add a development container to your existing project. + +### Using with VS Code + +1. Install the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +2. Open your project in VS Code +3. Press `F1` and select `Dev Containers: Add Dev Container Configuration Files...` +4. Search for "Liquescent" +5. Select the options you want +6. Reopen in container when prompted + +### Using with the Dev Container CLI + +```bash +# Install the CLI +npm install -g @devcontainers/cli + +# Apply the template to your project +devcontainer templates apply \ + --template-id ghcr.io/liquescent-development/templates/liquescent-devcontainer \ + --template-args '{"timezone": "America/Phoenix", "enableSocks5": true}' +``` + +## 📋 Template Options + +When adding this template to your project, you can configure: + +- **Image Source**: Use pre-built image (fast) or build from Dockerfile (customizable) +- **Timezone**: Set your container timezone (e.g., `America/Phoenix`, `Europe/London`) +- **SOCKS5 Proxy**: Enable/disable SOCKS5 proxy support for VPN/corporate networks +- **Git Config Mounting**: Mount host Git configuration and SSH keys + +## 🔧 Configuration + +After adding the template, customize your environment by: + +1. Copy `.devcontainer/.env.example` to `.devcontainer/.env` +2. Configure your settings (1Password tokens, custom domains, etc.) +3. Rebuild the container + +## 🌟 Features + +- **Languages**: Node.js, Go, Python, Rust, .NET +- **Security**: Network isolation with iptables firewall +- **Secret Management**: 1Password CLI integration +- **Developer Tools**: Git, GitHub CLI, FZF, direnv +- **Shell**: Zsh with Oh-My-Zsh and Oh-My-Posh + +## 📚 Learn More + +- [Full Documentation](https://github.com/Liquescent-Development/devcontainer) +- [Dev Container Specification](https://containers.dev/) \ No newline at end of file diff --git a/src/liquescent-devcontainer/devcontainer-template.json b/src/liquescent-devcontainer/devcontainer-template.json new file mode 100644 index 0000000..8258f28 --- /dev/null +++ b/src/liquescent-devcontainer/devcontainer-template.json @@ -0,0 +1,47 @@ +{ + "id": "liquescent-devcontainer", + "version": "1.0.0", + "name": "Liquescent Development Container", + "description": "A secure, polyglot development container with network isolation, comprehensive language support (Node.js, Go, Python, Rust, .NET), and enterprise-grade secret management via 1Password CLI.", + "documentationURL": "https://github.com/Liquescent-Development/devcontainer", + "licenseURL": "https://github.com/Liquescent-Development/devcontainer/blob/main/LICENSE", + "publisher": "Liquescent Development", + "keywords": [ + "devcontainer", + "polyglot", + "node", + "go", + "python", + "rust", + "dotnet", + "1password", + "secure", + "firewall" + ], + "platforms": [ + "Any" + ], + "options": { + "imageSource": { + "type": "string", + "description": "Use pre-built image or build from Dockerfile", + "enum": ["image", "dockerfile"], + "default": "image" + }, + "timezone": { + "type": "string", + "description": "Container timezone (e.g., America/Phoenix, Europe/London)", + "default": "UTC" + }, + "enableSocks5": { + "type": "boolean", + "description": "Enable SOCKS5 proxy support for VPN/corporate networks", + "default": true + }, + "mountGitConfig": { + "type": "boolean", + "description": "Mount host Git configuration and SSH keys", + "default": false + } + } +} \ No newline at end of file