pub const DOCKERFILE: &str = "# =============================================================================\n# opencode-cloud Container Image\n# =============================================================================\n# A comprehensive development environment for AI-assisted coding with opencode.\n#\n# Features:\n# - Ubuntu 24.04 LTS (noble) base\n# - Non-root user with passwordless sudo\n# - Multiple languages via mise (Node.js, Python, Rust, Go)\n# - Modern CLI tools (ripgrep, eza, fzf, lazygit, etc.)\n# - GSD opencode plugin for task management\n#\n# Usage:\n# docker build -t opencode-cloud .\n# docker run -it opencode-cloud\n#\n# =============================================================================\n\n# -----------------------------------------------------------------------------\n# Stage 1: Builder\n# -----------------------------------------------------------------------------\n# Install build dependencies and tools that require compilation\nFROM ubuntu:24.04 AS builder\n\n# Avoid interactive prompts during package installation\nENV DEBIAN_FRONTEND=noninteractive\nENV TZ=UTC\n\n# Install build essentials\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n build-essential \\\n ca-certificates \\\n curl \\\n git \\\n && rm -rf /var/lib/apt/lists/*\n\n# -----------------------------------------------------------------------------\n# Stage 2: Runtime\n# -----------------------------------------------------------------------------\nFROM ubuntu:24.04 AS runtime\n\n# OCI Labels for image metadata\nLABEL org.opencontainers.image.title=\"opencode-cloud\"\nLABEL org.opencontainers.image.description=\"AI-assisted development environment with opencode\"\nLABEL org.opencontainers.image.url=\"https://github.com/pRizz/opencode-cloud\"\nLABEL org.opencontainers.image.source=\"https://github.com/pRizz/opencode-cloud\"\nLABEL org.opencontainers.image.vendor=\"pRizz\"\nLABEL org.opencontainers.image.licenses=\"MIT\"\nLABEL org.opencontainers.image.base.name=\"ubuntu:24.04\"\n\n# Environment configuration\nENV DEBIAN_FRONTEND=noninteractive\nENV TZ=UTC\nENV LANG=C.UTF-8\nENV LC_ALL=C.UTF-8\n\n# -----------------------------------------------------------------------------\n# System Dependencies\n# -----------------------------------------------------------------------------\n# Install core system packages in logical groups for better caching\n\n# Group 1: Core utilities and build tools\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n # Signal handling\n tini \\\n dumb-init \\\n # Shell and terminal\n zsh \\\n tmux \\\n # Editors\n vim \\\n neovim \\\n nano \\\n # Build essentials\n build-essential \\\n pkg-config \\\n cmake \\\n # Version control\n git \\\n git-lfs \\\n # Core utilities\n curl \\\n wget \\\n ca-certificates \\\n gnupg \\\n lsb-release \\\n software-properties-common \\\n sudo \\\n openssh-client \\\n # Process/system tools\n htop \\\n procps \\\n less \\\n file \\\n tree \\\n # JSON/YAML processing\n jq \\\n # Network tools\n netcat-openbsd \\\n iputils-ping \\\n dnsutils \\\n # Compression\n zip \\\n unzip \\\n xz-utils \\\n p7zip-full \\\n && rm -rf /var/lib/apt/lists/*\n\n# Group 2: Database clients\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n sqlite3 \\\n postgresql-client \\\n default-mysql-client \\\n && rm -rf /var/lib/apt/lists/*\n\n# Group 3: Development libraries (for compiling tools)\nRUN apt-get update && apt-get install -y --no-install-recommends \\\n libssl-dev \\\n libffi-dev \\\n zlib1g-dev \\\n libbz2-dev \\\n libreadline-dev \\\n libsqlite3-dev \\\n libncurses-dev \\\n liblzma-dev \\\n && rm -rf /var/lib/apt/lists/*\n\n# -----------------------------------------------------------------------------\n# Create Non-Root User\n# -----------------------------------------------------------------------------\n# Create \'opencode\' user with passwordless sudo\nRUN useradd -m -s /bin/zsh -G sudo opencode \\\n && echo \"opencode ALL=(ALL) NOPASSWD:ALL\" > /etc/sudoers.d/opencode \\\n && chmod 0440 /etc/sudoers.d/opencode\n\n# Switch to opencode user for remaining setup\nUSER opencode\nWORKDIR /home/opencode\n\n# Set up directories\nRUN mkdir -p \\\n /home/opencode/.config \\\n /home/opencode/.local/bin \\\n /home/opencode/.local/share \\\n /home/opencode/.cache \\\n /home/opencode/workspace\n\n# Add local bin to PATH\nENV PATH=\"/home/opencode/.local/bin:${PATH}\"\n\n# -----------------------------------------------------------------------------\n# Shell Setup: Zsh + Oh My Zsh + Starship\n# -----------------------------------------------------------------------------\n# Install Oh My Zsh\nRUN sh -c \"$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)\" \"\" --unattended\n\n# Install Starship prompt\nRUN curl -sS https://starship.rs/install.sh | sh -s -- --yes --bin-dir /home/opencode/.local/bin\n\n# Configure zsh with starship\nRUN echo \'eval \"$(starship init zsh)\"\' >> /home/opencode/.zshrc \\\n && echo \'export PATH=\"/home/opencode/.local/bin:$PATH\"\' >> /home/opencode/.zshrc\n\n# -----------------------------------------------------------------------------\n# mise: Universal Version Manager\n# -----------------------------------------------------------------------------\n# Install mise for managing Node.js, Python, Rust, Go\nRUN curl https://mise.run | sh \\\n && echo \'eval \"$(/home/opencode/.local/bin/mise activate zsh)\"\' >> /home/opencode/.zshrc\n\n# Install language runtimes via mise\n# Using specific LTS/stable versions for reproducibility\nRUN /home/opencode/.local/bin/mise install node@lts \\\n && /home/opencode/.local/bin/mise install python@3.12 \\\n && /home/opencode/.local/bin/mise install go@latest \\\n && /home/opencode/.local/bin/mise use --global node@lts \\\n && /home/opencode/.local/bin/mise use --global python@3.12 \\\n && /home/opencode/.local/bin/mise use --global go@latest\n\n# Set up mise shims in PATH for non-interactive shells\nENV PATH=\"/home/opencode/.local/share/mise/shims:${PATH}\"\n\n# -----------------------------------------------------------------------------\n# Rust Installation\n# -----------------------------------------------------------------------------\n# Install Rust via rustup (mise rust support is experimental)\nRUN curl --proto \'=https\' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable \\\n && . /home/opencode/.cargo/env \\\n && rustup component add rust-analyzer rustfmt clippy\n\nENV PATH=\"/home/opencode/.cargo/bin:${PATH}\"\n\n# -----------------------------------------------------------------------------\n# Package Managers\n# -----------------------------------------------------------------------------\n# Switch to bash for mise activation (mise outputs bash-specific syntax)\nSHELL [\"/bin/bash\", \"-c\"]\n\n# Install pnpm (corepack is included with Node.js)\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && corepack enable \\\n && corepack prepare pnpm@latest --activate\n\n# Set up pnpm global bin directory\nENV PNPM_HOME=\"/home/opencode/.local/share/pnpm\"\nENV PATH=\"${PNPM_HOME}:${PATH}\"\nRUN mkdir -p \"${PNPM_HOME}\"\n\n# Install uv (fast Python package manager)\nRUN curl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Install pipx for isolated Python application installs\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pip install --user pipx \\\n && pipx ensurepath\n\n# Install global TypeScript compiler\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pnpm add -g typescript\n\n# -----------------------------------------------------------------------------\n# Modern CLI Tools (Rust-based)\n# -----------------------------------------------------------------------------\n# Install via cargo for latest versions\nRUN . /home/opencode/.cargo/env \\\n && cargo install --locked \\\n ripgrep \\\n eza\n\n# Install lazygit (Go-based)\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && go install github.com/jesseduffield/lazygit@latest\n\n# -----------------------------------------------------------------------------\n# Additional Development Tools\n# -----------------------------------------------------------------------------\n# Install fzf\nRUN git clone --depth 1 https://github.com/junegunn/fzf.git /home/opencode/.fzf \\\n && /home/opencode/.fzf/install --all --no-bash --no-fish\n\n# Install yq (YAML processor)\nRUN curl -sL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_$(dpkg --print-architecture) -o /home/opencode/.local/bin/yq \\\n && chmod +x /home/opencode/.local/bin/yq\n\n# Install direnv\nUSER root\nRUN apt-get update && apt-get install -y --no-install-recommends direnv \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\nRUN echo \'eval \"$(direnv hook zsh)\"\' >> /home/opencode/.zshrc\n\n# Install HTTPie\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pipx install httpie\n\n# Install shellcheck and shfmt\nUSER root\nRUN apt-get update && apt-get install -y --no-install-recommends shellcheck \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && go install mvdan.cc/sh/v3/cmd/shfmt@latest\n\n# Install btop (system monitor)\nUSER root\nRUN apt-get update && apt-get install -y --no-install-recommends btop \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\n\n# -----------------------------------------------------------------------------\n# GitHub CLI\n# -----------------------------------------------------------------------------\nUSER root\nRUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \\\n && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \\\n && echo \"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main\" > /etc/apt/sources.list.d/github-cli.list \\\n && apt-get update && apt-get install -y --no-install-recommends gh \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\n\n# -----------------------------------------------------------------------------\n# CI/CD Tools\n# -----------------------------------------------------------------------------\n# Install act (run GitHub Actions locally)\nRUN curl -sL https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash -s -- -b /home/opencode/.local/bin\n\n# -----------------------------------------------------------------------------\n# Rust Tooling\n# -----------------------------------------------------------------------------\nRUN . /home/opencode/.cargo/env \\\n && cargo install --locked \\\n cargo-nextest \\\n cargo-audit \\\n cargo-deny\n\n# Install mold (fast linker) via apt for easier setup\nUSER root\nRUN apt-get update && apt-get install -y --no-install-recommends mold \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\n\n# -----------------------------------------------------------------------------\n# Code Quality Tools\n# -----------------------------------------------------------------------------\n# JavaScript/TypeScript tools\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pnpm add -g \\\n prettier \\\n eslint \\\n @biomejs/biome\n\n# Python tools\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pipx install black \\\n && pipx install ruff\n\n# Test runners (commonly needed)\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pnpm add -g jest vitest\n\n# Python pytest via pipx\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && pipx install pytest\n\n# -----------------------------------------------------------------------------\n# Protocol Buffers / gRPC\n# -----------------------------------------------------------------------------\nUSER root\nRUN apt-get update && apt-get install -y --no-install-recommends protobuf-compiler \\\n && rm -rf /var/lib/apt/lists/*\nUSER opencode\n\n# Install grpcurl\nRUN eval \"$(/home/opencode/.local/bin/mise activate bash)\" \\\n && go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest\n\n# -----------------------------------------------------------------------------\n# opencode Installation\n# -----------------------------------------------------------------------------\n# Install opencode using official install script\n# The script installs to ~/.opencode/bin/\nRUN curl -fsSL https://opencode.ai/install | bash \\\n && ls -la /home/opencode/.opencode/bin/opencode \\\n && /home/opencode/.opencode/bin/opencode --version\n\n# Add opencode to PATH\nENV PATH=\"/home/opencode/.opencode/bin:${PATH}\"\n\n# -----------------------------------------------------------------------------\n# GSD Plugin Installation\n# -----------------------------------------------------------------------------\n# Install the GSD (Get Shit Done) plugin for opencode\nRUN git clone https://github.com/rokicool/gsd-opencode.git /home/opencode/.config/opencode/plugins/gsd-opencode\n\n# -----------------------------------------------------------------------------\n# Sensible Defaults Configuration\n# -----------------------------------------------------------------------------\n# Git configuration\nRUN git config --global init.defaultBranch main \\\n && git config --global core.editor \"nvim\" \\\n && git config --global pull.rebase false \\\n && git config --global merge.conflictstyle diff3 \\\n && git config --global diff.colorMoved default\n\n# Starship configuration (minimal, fast prompt)\nRUN mkdir -p /home/opencode/.config \\\n && cat > /home/opencode/.config/starship.toml << \'STARSHIP\'\n# Minimal starship config for fast prompt\nformat = \"\"\"\n$directory\\\n$git_branch\\\n$git_status\\\n$character\"\"\"\n\n[directory]\ntruncation_length = 3\ntruncate_to_repo = true\n\n[git_branch]\nformat = \"[$branch]($style) \"\nstyle = \"bold purple\"\n\n[git_status]\nformat = \'([$all_status$ahead_behind]($style) )\'\n\n[character]\nsuccess_symbol = \"[>](bold green)\"\nerror_symbol = \"[>](bold red)\"\nSTARSHIP\n\n# Shell aliases\nRUN cat >> /home/opencode/.zshrc << \'ALIASES\'\n\n# Modern CLI aliases\nalias ls=\"eza --icons\"\nalias ll=\"eza -l --icons\"\nalias la=\"eza -la --icons\"\nalias lt=\"eza --tree --icons\"\nalias grep=\"rg\"\nalias top=\"btop\"\n\n# Git aliases\nalias g=\"git\"\nalias gs=\"git status\"\nalias gd=\"git diff\"\nalias gc=\"git commit\"\nalias gp=\"git push\"\nalias gl=\"git pull\"\nalias gco=\"git checkout\"\nalias gb=\"git branch\"\nalias lg=\"lazygit\"\n\n# Docker aliases (for Docker-in-Docker)\nalias d=\"docker\"\nalias dc=\"docker compose\"\n\nALIASES\n\n# Set up pipx path\nRUN echo \'export PATH=\"/home/opencode/.local/bin:$PATH\"\' >> /home/opencode/.zshrc\n\n# -----------------------------------------------------------------------------\n# Health Check\n# -----------------------------------------------------------------------------\n# Port 3000 must match OPENCODE_WEB_PORT in container.rs\nHEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\\n CMD curl -f http://localhost:3000/health || exit 1\n\n# -----------------------------------------------------------------------------\n# Final Configuration\n# -----------------------------------------------------------------------------\nWORKDIR /home/opencode/workspace\n\n# Expose opencode web port (matches OPENCODE_WEB_PORT in container.rs)\nEXPOSE 3000\n\n# Use tini as init system for proper signal handling\nENTRYPOINT [\"/usr/bin/tini\", \"--\"]\n\n# Default command: start opencode web interface\n# - Port 3000 must match OPENCODE_WEB_PORT in container.rs\n# - Using full path to ensure binary is found (opencode installs to ~/.opencode/bin/)\n# - --hostname 0.0.0.0 is required for Docker port mapping (default 127.0.0.1 only listens on loopback)\nCMD [\"/home/opencode/.opencode/bin/opencode\", \"web\", \"--port\", \"3000\", \"--hostname\", \"0.0.0.0\"]\n";Expand description
The Dockerfile for building the opencode-cloud container image