From e4de11226f0ae17f8078b38c30b084c2cc2363b0 Mon Sep 17 00:00:00 2001 From: sebi Date: Sun, 15 Feb 2026 02:39:31 +0000 Subject: [PATCH 1/4] Update bot configurations to use Incus sandbox type - Remove backwards compatibility fields (incusImage, packages) from daniel-francoeur-assistant and sebastian-buza-assistant configs - Packages are now handled by base Incus images instead - Add sandbox configuration to assistant bot (using default Incus type) - Simplify sandbox config to only specify type: 'incus' per new Incus-only worker architecture Co-Authored-By: Claude Haiku 4.5 --- .mcp.json | 8 ++++++++ bots/assistant/config.json | 5 ++++- bots/daniel-francoeur-assistant/config.json | 4 +--- bots/sebastian-buza-assistant/config.json | 4 +--- 4 files changed, 14 insertions(+), 7 deletions(-) create mode 100644 .mcp.json diff --git a/.mcp.json b/.mcp.json new file mode 100644 index 0000000..9513853 --- /dev/null +++ b/.mcp.json @@ -0,0 +1,8 @@ +{ + "mcpServers": { + "kubeez": { + "type": "http", + "url": "https://mcp.kubeez.com/mcp" + } + } +} \ No newline at end of file diff --git a/bots/assistant/config.json b/bots/assistant/config.json index 1fcedfd..8477556 100644 --- a/bots/assistant/config.json +++ b/bots/assistant/config.json @@ -8,5 +8,8 @@ "readFile", "writeFile" ], - "mcpServers": ["filesystem"] + "mcpServers": ["filesystem"], + "sandbox": { + "type": "incus" + } } diff --git a/bots/daniel-francoeur-assistant/config.json b/bots/daniel-francoeur-assistant/config.json index 2c09d14..bbc1d13 100644 --- a/bots/daniel-francoeur-assistant/config.json +++ b/bots/daniel-francoeur-assistant/config.json @@ -16,8 +16,6 @@ "maxSteps": 50, "temperature": 0.7, "sandbox": { - "type": "incus", - "incusImage": "node:22-slim", - "packages": ["python3", "python3-pip"] + "type": "incus" } } diff --git a/bots/sebastian-buza-assistant/config.json b/bots/sebastian-buza-assistant/config.json index ae670bd..8505971 100644 --- a/bots/sebastian-buza-assistant/config.json +++ b/bots/sebastian-buza-assistant/config.json @@ -16,8 +16,6 @@ "maxSteps": 50, "temperature": 0.7, "sandbox": { - "type": "incus", - "incusImage": "node:22-slim", - "packages": ["python3", "python3-pip"] + "type": "incus" } } From 8f4bbdb31498e87afe2ddafadf5cab07017f3345 Mon Sep 17 00:00:00 2001 From: sebi Date: Sun, 15 Feb 2026 02:42:07 +0000 Subject: [PATCH 2/4] feat: Add Incus worker provisioning script - Create scripts/provision-worker.sh: installs Incus via Zabbly PPA, initializes with `incus admin init --auto`, builds ai-army-base and ai-army-base-docker LXC images with agent user, Node 22, Python3, and build tools - Update scripts/provision-server.sh: now provisions Docker only on master server, workers use provision-worker.sh instead - Add WORKER_SERVERS/WORKER_NAMES arrays to scripts/servers.sh for worker-specific operations Co-Authored-By: Claude --- scripts/provision-server.sh | 23 ++-- scripts/provision-worker.sh | 228 ++++++++++++++++++++++++++++++++++++ scripts/servers.sh | 2 + 3 files changed, 241 insertions(+), 12 deletions(-) create mode 100755 scripts/provision-worker.sh diff --git a/scripts/provision-server.sh b/scripts/provision-server.sh index 69e49c3..5c92ebc 100755 --- a/scripts/provision-server.sh +++ b/scripts/provision-server.sh @@ -1,15 +1,18 @@ #!/usr/bin/env bash -# Provision a server with Docker + Node.js 22 -# Usage: ./scripts/provision-server.sh [user@host] -# If no host given, provisions all servers from servers.sh +# Provision the master server with Docker + Node.js 22 +# Workers use provision-worker.sh (Incus) instead +# +# Usage: +# ./scripts/provision-server.sh # Provision master +# ./scripts/provision-server.sh user@host # Provision a specific host with Docker set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/servers.sh" -provision_one() { +provision_master() { local host="$1" - echo "Provisioning $host ..." + echo "Provisioning master ($host) with Docker + Node.js..." ssh $SSH_OPTS "$host" 'bash -s' << 'REMOTE' set -e @@ -41,17 +44,13 @@ docker --version docker compose version node --version npm --version -echo "=== PROVISIONING COMPLETE ===" +echo "=== MASTER PROVISIONING COMPLETE ===" REMOTE echo "Done: $host" } if [ $# -gt 0 ]; then - provision_one "$1" + provision_master "$1" else - for host in "${ALL_SERVERS[@]}"; do - provision_one "$host" & - done - wait - echo "All servers provisioned." + provision_master "$MASTER_HOST" fi diff --git a/scripts/provision-worker.sh b/scripts/provision-worker.sh new file mode 100755 index 0000000..4e4c263 --- /dev/null +++ b/scripts/provision-worker.sh @@ -0,0 +1,228 @@ +#!/usr/bin/env bash +# Provision a worker VPS with Incus (LXC) and create base images +# Usage: +# ./scripts/provision-worker.sh # Provision all workers +# ./scripts/provision-worker.sh worker1 # Provision worker1 only +# ./scripts/provision-worker.sh ubuntu@host.com # Provision specific host + +set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +source "$SCRIPT_DIR/servers.sh" + +install_incus() { + local host="$1" + echo "=== Installing Incus on $host ===" + ssh $SSH_OPTS "$host" 'bash -s' << 'REMOTE' +set -e + +# Check if already provisioned +if command -v incus &>/dev/null; then + echo "Incus already installed:" + incus --version + echo "Checking base images..." + if incus image list --format csv | grep -q "ai-army-base"; then + echo "Base images already exist." + incus image list --format table + exit 0 + fi + echo "Base images not found โ€” will create them." +fi + +echo "--- Installing Incus ---" +# Add Zabbly PPA for latest Incus (works on Ubuntu 24.04+) +if [ ! -f /etc/apt/sources.list.d/zabbly-incus-stable.sources ]; then + sudo mkdir -p /etc/apt/keyrings/ + curl -fsSL https://pkgs.zabbly.com/key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.gpg --yes + sudo sh -c 'cat < /etc/apt/sources.list.d/zabbly-incus-stable.sources +Enabled: yes +Types: deb +URIs: https://pkgs.zabbly.com/incus/stable +Suites: $(. /etc/os-release && echo "$VERSION_CODENAME") +Components: main +Architectures: $(dpkg --print-architecture) +Signed-By: /etc/apt/keyrings/zabbly.gpg +EOF' +fi + +sudo apt-get update -y +sudo apt-get install -y incus + +# Add current user to incus-admin group +sudo usermod -aG incus-admin "$USER" + +echo "--- Initializing Incus ---" +# Initialize with defaults (creates default storage pool + network bridge) +sudo incus admin init --auto + +echo "--- Verifying Incus ---" +incus --version +incus list + +echo "=== Incus installation complete ===" +REMOTE + echo "Done installing Incus on $host" +} + +create_base_images() { + local host="$1" + echo "=== Creating base images on $host ===" + ssh $SSH_OPTS "$host" 'bash -s' << 'REMOTE' +set -e + +# ------------------------------------------------------- +# ai-army-base: Standard base image (no Docker) +# ------------------------------------------------------- +if incus image list --format csv | grep -q "ai-army-base,"; then + echo "Image ai-army-base already exists, skipping." +else + echo "--- Building ai-army-base image ---" + incus launch images:ubuntu/24.04 base-build + + # Wait for container networking + echo "Waiting for container to be ready..." + sleep 5 + for i in $(seq 1 30); do + if incus exec base-build -- ping -c1 -W2 archive.ubuntu.com &>/dev/null; then + break + fi + sleep 2 + done + + incus exec base-build -- bash -c ' + set -e + + # Create agent user + useradd -m -s /bin/bash agent + echo "agent ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/agent + + # Install common tools + apt-get update -y + apt-get install -y \ + git curl wget \ + python3 python3-pip \ + build-essential \ + jq tree htop \ + ca-certificates gnupg + + # Install Node.js 22 via NodeSource + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - + apt-get install -y nodejs + + # Clean up + apt-get clean + rm -rf /var/lib/apt/lists/* + + echo "--- Verifying ---" + node --version + npm --version + python3 --version + git --version + ' + + incus stop base-build + incus publish base-build --alias ai-army-base description="AI Army base image - Ubuntu 24.04 + Node 22 + Python3 + build tools" + incus delete base-build + echo "ai-army-base image created." +fi + +# ------------------------------------------------------- +# ai-army-base-docker: Base image with Docker CE +# ------------------------------------------------------- +if incus image list --format csv | grep -q "ai-army-base-docker"; then + echo "Image ai-army-base-docker already exists, skipping." +else + echo "--- Building ai-army-base-docker image ---" + incus launch images:ubuntu/24.04 docker-base-build + incus config set docker-base-build security.nesting=true + + # Restart to apply nesting config + incus restart docker-base-build + + # Wait for container networking + echo "Waiting for container to be ready..." + sleep 5 + for i in $(seq 1 30); do + if incus exec docker-base-build -- ping -c1 -W2 archive.ubuntu.com &>/dev/null; then + break + fi + sleep 2 + done + + incus exec docker-base-build -- bash -c ' + set -e + + # Create agent user + useradd -m -s /bin/bash agent + echo "agent ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/agent + + # Install common tools + apt-get update -y + apt-get install -y \ + git curl wget \ + python3 python3-pip \ + build-essential \ + jq tree htop \ + ca-certificates gnupg + + # Install Node.js 22 via NodeSource + curl -fsSL https://deb.nodesource.com/setup_22.x | bash - + apt-get install -y nodejs + + # Install Docker CE + curl -fsSL https://get.docker.com | sh + usermod -aG docker agent + systemctl enable docker + + # Clean up + apt-get clean + rm -rf /var/lib/apt/lists/* + + echo "--- Verifying ---" + node --version + npm --version + python3 --version + git --version + docker --version + ' + + incus stop docker-base-build + incus publish docker-base-build --alias ai-army-base-docker description="AI Army Docker-enabled base - Ubuntu 24.04 + Node 22 + Docker CE" + incus delete docker-base-build + echo "ai-army-base-docker image created." +fi + +echo "" +echo "=== Base images ===" +incus image list --format table +echo "=== Provisioning complete ===" +REMOTE + echo "Done creating base images on $host" +} + +provision_worker() { + local host="$1" + echo "" + echo "############################################" + echo " Provisioning worker: $host" + echo "############################################" + echo "" + install_incus "$host" + create_base_images "$host" +} + +# Parse arguments +if [ $# -gt 0 ]; then + case "$1" in + worker1) provision_worker "$WORKER1_HOST" ;; + worker2) provision_worker "$WORKER2_HOST" ;; + *) provision_worker "$1" ;; + esac +else + # Provision all workers (not master) + for host in "${WORKER_SERVERS[@]}"; do + provision_worker "$host" & + done + wait + echo "" + echo "All workers provisioned with Incus." +fi diff --git a/scripts/servers.sh b/scripts/servers.sh index 769fab9..b930283 100755 --- a/scripts/servers.sh +++ b/scripts/servers.sh @@ -8,6 +8,8 @@ WORKER2_HOST="ubuntu@vps-02a9b234.vps.ovh.net" ALL_SERVERS=("$MASTER_HOST" "$WORKER1_HOST" "$WORKER2_HOST") SERVER_NAMES=("master" "worker1" "worker2") +WORKER_SERVERS=("$WORKER1_HOST" "$WORKER2_HOST") +WORKER_NAMES=("worker1" "worker2") DEPLOY_DIR="/home/ubuntu/ai-army" SSH_OPTS="-o StrictHostKeyChecking=no -o ConnectTimeout=10" From 09475ebb380a4c480650d572e18936033a7f325c Mon Sep 17 00:00:00 2001 From: sebi Date: Sun, 15 Feb 2026 02:44:42 +0000 Subject: [PATCH 3/4] feat: Update deploy scripts for Incus workers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Split deploy-all.sh into deploy_master (Docker Compose) and deploy_worker (sync code + verify Incus) functions - Workers no longer run docker compose โ€” they only host LXC containers managed remotely by master - Update status-all.sh to check incus list on workers instead of docker compose ps - Update logs.sh to use incus commands for worker log viewing Co-Authored-By: Claude --- scripts/deploy-all.sh | 65 ++++++++++++++++++++++++++++++++----------- scripts/logs.sh | 28 ++++++++++++++----- scripts/status-all.sh | 47 +++++++++++++++++++++++++++---- 3 files changed, 112 insertions(+), 28 deletions(-) diff --git a/scripts/deploy-all.sh b/scripts/deploy-all.sh index d8cbaa1..e3c0d6b 100755 --- a/scripts/deploy-all.sh +++ b/scripts/deploy-all.sh @@ -4,7 +4,7 @@ # ./scripts/deploy-all.sh # Deploy to all servers # ./scripts/deploy-all.sh master # Deploy to master only # ./scripts/deploy-all.sh worker1 # Deploy to worker1 only -# ./scripts/deploy-all.sh --full # Full rebuild on all servers +# ./scripts/deploy-all.sh --full # Full rebuild on master set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -23,16 +23,8 @@ for arg in "$@"; do esac done -deploy_to() { - local name="$1" - local host="$2" - - echo "=== Deploying to $name ($host) ===" - - # Create deploy dir - run_on "$host" "mkdir -p $DEPLOY_DIR" - - # Sync code (exclude heavy/sensitive dirs) +sync_code() { + local host="$1" echo " Syncing code..." rsync -az --delete \ --exclude 'node_modules' \ @@ -43,7 +35,20 @@ deploy_to() { --exclude '.env.local' \ -e "ssh $SSH_OPTS" \ "$PROJECT_DIR/" "$host:$DEPLOY_DIR/" +} + +deploy_master() { + local host="$1" + + echo "=== Deploying to master ($host) ===" + + # Create deploy dir + run_on "$host" "mkdir -p $DEPLOY_DIR" + + # Sync code + sync_code "$host" + # Build and start Docker Compose stack echo " Building and starting containers..." if [ "$FULL_BUILD" = true ]; then run_on "$host" "cd $DEPLOY_DIR && sg docker -c 'docker compose down 2>/dev/null || true' && sg docker -c 'docker compose build --no-cache' && sg docker -c 'docker compose up -d'" @@ -51,6 +56,7 @@ deploy_to() { run_on "$host" "cd $DEPLOY_DIR && sg docker -c 'docker compose up -d --build'" fi + # Health check echo " Waiting for health check..." local retries=20 for i in $(seq 1 $retries); do @@ -69,6 +75,32 @@ deploy_to() { echo " Running migrations..." run_on "$host" "cd $DEPLOY_DIR && sg docker -c 'docker compose exec -T app node bin/cli.js migrate'" 2>&1 || echo " (migration may have already run)" + echo "=== master deployed ===" + echo "" +} + +deploy_worker() { + local name="$1" + local host="$2" + + echo "=== Deploying to $name ($host) ===" + + # Create deploy dir + run_on "$host" "mkdir -p $DEPLOY_DIR" + + # Sync code (workers host LXC containers managed remotely by master) + sync_code "$host" + + # Verify Incus is available + echo " Checking Incus..." + if run_on "$host" "command -v incus &>/dev/null"; then + echo " Incus: $(run_on "$host" "incus --version")" + echo " Containers:" + run_on "$host" "incus list --format table 2>/dev/null" || echo " (none)" + else + echo " WARNING: Incus not installed. Run: ./scripts/provision-worker.sh $name" + fi + echo "=== $name deployed ===" echo "" } @@ -76,13 +108,14 @@ deploy_to() { # Resolve target if [ -n "$TARGET" ]; then case "$TARGET" in - master) deploy_to "master" "$MASTER_HOST" ;; - worker1) deploy_to "worker1" "$WORKER1_HOST" ;; - worker2) deploy_to "worker2" "$WORKER2_HOST" ;; + master) deploy_master "$MASTER_HOST" ;; + worker1) deploy_worker "worker1" "$WORKER1_HOST" ;; + worker2) deploy_worker "worker2" "$WORKER2_HOST" ;; esac else - for i in "${!ALL_SERVERS[@]}"; do - deploy_to "${SERVER_NAMES[$i]}" "${ALL_SERVERS[$i]}" + deploy_master "$MASTER_HOST" + for i in "${!WORKER_SERVERS[@]}"; do + deploy_worker "${WORKER_NAMES[$i]}" "${WORKER_SERVERS[$i]}" done fi diff --git a/scripts/logs.sh b/scripts/logs.sh index bb512e1..a7a54d1 100755 --- a/scripts/logs.sh +++ b/scripts/logs.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash # View logs from AI Army on a server # Usage: -# ./scripts/logs.sh master # Follow all logs on master -# ./scripts/logs.sh worker1 app # Follow app logs on worker1 -# ./scripts/logs.sh worker2 postgres # Follow postgres logs +# ./scripts/logs.sh master # Follow all Docker Compose logs on master +# ./scripts/logs.sh master app # Follow app logs on master +# ./scripts/logs.sh master postgres # Follow postgres logs on master +# ./scripts/logs.sh worker1 # List LXC containers on worker1 +# ./scripts/logs.sh worker1 bot-name # Follow LXC container logs on worker1 set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" @@ -16,11 +18,23 @@ case "$TARGET" in master) HOST="$MASTER_HOST" ;; worker1) HOST="$WORKER1_HOST" ;; worker2) HOST="$WORKER2_HOST" ;; - *) echo "Usage: $0 {master|worker1|worker2} [service]"; exit 1 ;; + *) echo "Usage: $0 {master|worker1|worker2} [service|container]"; exit 1 ;; esac -if [ -n "$SERVICE" ]; then - run_on "$HOST" "cd $DEPLOY_DIR && sg docker -c 'docker compose logs -f --tail=100 $SERVICE'" +if [ "$TARGET" = "master" ]; then + # Master uses Docker Compose + if [ -n "$SERVICE" ]; then + run_on "$HOST" "cd $DEPLOY_DIR && sg docker -c 'docker compose logs -f --tail=100 $SERVICE'" + else + run_on "$HOST" "cd $DEPLOY_DIR && sg docker -c 'docker compose logs -f --tail=100'" + fi else - run_on "$HOST" "cd $DEPLOY_DIR && sg docker -c 'docker compose logs -f --tail=100'" + # Workers use Incus LXC containers + if [ -n "$SERVICE" ]; then + echo "Following logs for LXC container '$SERVICE' on $TARGET..." + run_on "$HOST" "incus console $SERVICE --show-log 2>/dev/null || incus info $SERVICE" + else + echo "LXC containers on $TARGET:" + run_on "$HOST" "incus list --format table 2>/dev/null" || echo "(Incus not installed)" + fi fi diff --git a/scripts/status-all.sh b/scripts/status-all.sh index 1f33a5d..27c9388 100755 --- a/scripts/status-all.sh +++ b/scripts/status-all.sh @@ -6,18 +6,17 @@ set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" source "$SCRIPT_DIR/servers.sh" -for i in "${!ALL_SERVERS[@]}"; do - name="${SERVER_NAMES[$i]}" - host="${ALL_SERVERS[$i]}" +status_master() { + local host="$1" echo "============================================" - echo " $name ($host)" + echo " master ($host)" echo "============================================" # Check SSH if ! ssh $SSH_OPTS "$host" "echo connected" &>/dev/null; then echo " SSH: FAILED" echo "" - continue + return fi echo " SSH: OK" @@ -34,4 +33,42 @@ for i in "${!ALL_SERVERS[@]}"; do echo " Health: $health" echo "" +} + +status_worker() { + local name="$1" + local host="$2" + echo "============================================" + echo " $name ($host)" + echo "============================================" + + # Check SSH + if ! ssh $SSH_OPTS "$host" "echo connected" &>/dev/null; then + echo " SSH: FAILED" + echo "" + return + fi + echo " SSH: OK" + + # Check Incus + incus_ver=$(run_on "$host" "incus --version 2>/dev/null" || echo "NOT INSTALLED") + echo " Incus: $incus_ver" + + # Check LXC containers + echo " LXC Containers:" + run_on "$host" "incus list --format table 2>/dev/null" || echo " (none or Incus not installed)" + + # Check base images + echo " Base Images:" + run_on "$host" "incus image list --format table 2>/dev/null" || echo " (none)" + + echo "" +} + +# Check master +status_master "$MASTER_HOST" + +# Check workers +for i in "${!WORKER_SERVERS[@]}"; do + status_worker "${WORKER_NAMES[$i]}" "${WORKER_SERVERS[$i]}" done From 9ab6ac3c5bca292cf658c14189fafbae2afddf75 Mon Sep 17 00:00:00 2001 From: sebi Date: Sun, 15 Feb 2026 02:45:24 +0000 Subject: [PATCH 4/4] refactor: remove Docker-related worker-only files Deleted: - docker/images/* (all worker-specific Docker images) - scripts/build-images.sh (Docker image build script) - scripts/test-images.sh (Docker image test script) - .github/workflows/build-images.yml (Docker CI workflow) Kept: - Dockerfile (master app container) - docker-compose.yml (master orchestrator stack) - .dockerignore (still needed for master) Workers now use Incus/LXC exclusively, no Docker backend needed. Co-Authored-By: Claude Haiku 4.5 --- .github/workflows/build-images.yml | 60 --------------------- docker/images/backend-developer/Dockerfile | 57 -------------------- docker/images/data-scientist/Dockerfile | 48 ----------------- docker/images/devops-engineer/Dockerfile | 56 ------------------- docker/images/frontend-developer/Dockerfile | 47 ---------------- docker/images/qa-engineer/Dockerfile | 46 ---------------- scripts/build-images.sh | 32 ----------- scripts/test-images.sh | 57 -------------------- 8 files changed, 403 deletions(-) delete mode 100644 .github/workflows/build-images.yml delete mode 100644 docker/images/backend-developer/Dockerfile delete mode 100644 docker/images/data-scientist/Dockerfile delete mode 100644 docker/images/devops-engineer/Dockerfile delete mode 100644 docker/images/frontend-developer/Dockerfile delete mode 100644 docker/images/qa-engineer/Dockerfile delete mode 100755 scripts/build-images.sh delete mode 100755 scripts/test-images.sh diff --git a/.github/workflows/build-images.yml b/.github/workflows/build-images.yml deleted file mode 100644 index d6e5ec8..0000000 --- a/.github/workflows/build-images.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Build and Push Worker Images - -on: - push: - branches: [main] - paths: - - 'docker/images/**' - - '.github/workflows/build-images.yml' - release: - types: [published] - -env: - REGISTRY: ghcr.io - IMAGE_PREFIX: developerz-ai/ai-army - -jobs: - build: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - strategy: - matrix: - image: - - frontend-developer - - backend-developer - - devops-engineer - - data-scientist - - qa-engineer - - steps: - - uses: actions/checkout@v4 - - - name: Log in to Container Registry - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ env.IMAGE_PREFIX }}/${{ matrix.image }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push - uses: docker/build-push-action@v5 - with: - context: docker/images/${{ matrix.image }} - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/docker/images/backend-developer/Dockerfile b/docker/images/backend-developer/Dockerfile deleted file mode 100644 index 0917f46..0000000 --- a/docker/images/backend-developer/Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -# AI Army - Backend Developer Worker Image -# Base image for backend development workers. -# Includes Python 3.11, Django, FastAPI, pytest, and Node.js 22. - -FROM python:3.11-slim - -LABEL org.opencontainers.image.source="https://github.com/developerz-ai/ai-army" -LABEL org.opencontainers.image.description="AI Army - Backend Developer Worker" -LABEL org.opencontainers.image.version="1.0.0" -LABEL ai-army.worker-type="backend-developer" -LABEL ai-army.tools="bash,git,pip,python,readFile,writeFile" - -# hadolint: pipefail needed for curl | bash pattern -SHELL ["/bin/bash", "-o", "pipefail", "-c"] - -# Install system dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - curl \ - postgresql-client \ - build-essential \ - ca-certificates \ - gnupg \ - && rm -rf /var/lib/apt/lists/* - -# Install Python packages -RUN pip3 install --no-cache-dir \ - django \ - fastapi \ - uvicorn \ - sqlalchemy \ - psycopg2-binary \ - pytest \ - black \ - ruff - -# Install Node.js 22 (for scripts and tooling) -RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - && \ - apt-get install -y --no-install-recommends nodejs && \ - rm -rf /var/lib/apt/lists/* - -# Create agent user and workspace -RUN useradd -m -s /bin/bash agent - -WORKDIR /home/agent - -# Configure git for AI worker -RUN git config --global user.name "AI Worker" && \ - git config --global user.email "worker@ai-army.dev" && \ - git config --global init.defaultBranch main - -# Set permissions -RUN chown -R agent:agent /home/agent - -USER agent - -CMD ["sleep", "infinity"] diff --git a/docker/images/data-scientist/Dockerfile b/docker/images/data-scientist/Dockerfile deleted file mode 100644 index e5e9068..0000000 --- a/docker/images/data-scientist/Dockerfile +++ /dev/null @@ -1,48 +0,0 @@ -# AI Army - Data Scientist Worker Image -# Base image for data science and machine learning workers. -# Includes Python 3.11, pandas, numpy, scikit-learn, matplotlib, and Jupyter. -# NOTE: Uses python:3.11-slim (not jupyter/scipy-notebook) to keep image <1GB. -# Heavy ML frameworks (tensorflow, torch) are left for user customization. - -FROM python:3.11-slim - -LABEL org.opencontainers.image.source="https://github.com/developerz-ai/ai-army" -LABEL org.opencontainers.image.description="AI Army - Data Scientist Worker" -LABEL org.opencontainers.image.version="1.0.0" -LABEL ai-army.worker-type="data-scientist" -LABEL ai-army.tools="bash,git,python,pip,jupyter,readFile,writeFile" - -# Install system dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - curl \ - build-essential \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Install core data science packages -RUN pip3 install --no-cache-dir \ - pandas \ - numpy \ - scikit-learn \ - matplotlib \ - seaborn \ - plotly \ - jupyterlab \ - notebook \ - scipy \ - statsmodels - -# Create agent user, workspace, and configure git -RUN useradd -m -s /bin/bash agent && \ - git config --global user.name "AI Worker" && \ - git config --global user.email "worker@ai-army.dev" && \ - git config --global init.defaultBranch main - -WORKDIR /home/agent - -RUN chown -R agent:agent /home/agent - -USER agent - -CMD ["sleep", "infinity"] diff --git a/docker/images/devops-engineer/Dockerfile b/docker/images/devops-engineer/Dockerfile deleted file mode 100644 index e46ea58..0000000 --- a/docker/images/devops-engineer/Dockerfile +++ /dev/null @@ -1,56 +0,0 @@ -# AI Army - DevOps Engineer Worker Image -# Base image for DevOps and infrastructure workers. -# Includes Docker CLI, kubectl, Terraform, and common DevOps tools. - -FROM alpine:3.19 - -LABEL org.opencontainers.image.source="https://github.com/developerz-ai/ai-army" -LABEL org.opencontainers.image.description="AI Army - DevOps Engineer Worker" -LABEL org.opencontainers.image.version="1.0.0" -LABEL ai-army.worker-type="devops-engineer" -LABEL ai-army.tools="bash,git,docker,kubectl,terraform,readFile,writeFile" - -# Install system tools -RUN apk add --no-cache \ - bash \ - git \ - curl \ - docker-cli \ - python3 \ - py3-pip \ - openssh-client \ - jq \ - yq \ - ca-certificates \ - unzip - -# Install kubectl -RUN KUBECTL_VERSION=$(curl -L -s https://dl.k8s.io/release/stable.txt) && \ - curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl" && \ - install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl && \ - rm kubectl - -# Install terraform -ARG TERRAFORM_VERSION=1.7.0 -RUN curl -fsSL -o "terraform_${TERRAFORM_VERSION}_linux_amd64.zip" \ - "https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip" && \ - unzip "terraform_${TERRAFORM_VERSION}_linux_amd64.zip" && \ - mv terraform /usr/local/bin/ && \ - rm "terraform_${TERRAFORM_VERSION}_linux_amd64.zip" - -# Create agent user and workspace -RUN adduser -D -s /bin/bash agent - -WORKDIR /home/agent - -# Configure git for AI worker -RUN git config --global user.name "AI Worker" && \ - git config --global user.email "worker@ai-army.dev" && \ - git config --global init.defaultBranch main - -# Set permissions -RUN chown -R agent:agent /home/agent - -USER agent - -CMD ["sleep", "infinity"] diff --git a/docker/images/frontend-developer/Dockerfile b/docker/images/frontend-developer/Dockerfile deleted file mode 100644 index 85534f8..0000000 --- a/docker/images/frontend-developer/Dockerfile +++ /dev/null @@ -1,47 +0,0 @@ -# AI Army - Frontend Developer Worker Image -# Base image for frontend development workers. -# Includes Node.js 22, TypeScript, Vite, ESLint, Prettier, and Playwright. - -FROM node:22-slim - -LABEL org.opencontainers.image.source="https://github.com/developerz-ai/ai-army" -LABEL org.opencontainers.image.description="AI Army - Frontend Developer Worker" -LABEL org.opencontainers.image.version="1.0.0" -LABEL ai-army.worker-type="frontend-developer" -LABEL ai-army.tools="bash,git,npm,readFile,writeFile" - -# Install system dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - curl \ - python3 \ - python3-pip \ - build-essential \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Install global npm packages -RUN npm install -g \ - typescript@latest \ - vite@latest \ - eslint@latest \ - prettier@latest \ - @playwright/test@latest \ - && npm cache clean --force - -# Create agent user and workspace -RUN useradd -m -s /bin/bash agent - -WORKDIR /home/agent - -# Configure git for AI worker -RUN git config --global user.name "AI Worker" && \ - git config --global user.email "worker@ai-army.dev" && \ - git config --global init.defaultBranch main - -# Set permissions -RUN chown -R agent:agent /home/agent - -USER agent - -CMD ["sleep", "infinity"] diff --git a/docker/images/qa-engineer/Dockerfile b/docker/images/qa-engineer/Dockerfile deleted file mode 100644 index eaa9c3b..0000000 --- a/docker/images/qa-engineer/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -# AI Army - QA Engineer Worker Image -# Base image for QA and test automation workers. -# Includes Playwright with Chromium, Jest, Vitest, and testing tools. - -FROM node:22-slim - -LABEL org.opencontainers.image.source="https://github.com/developerz-ai/ai-army" -LABEL org.opencontainers.image.description="AI Army - QA Engineer Worker" -LABEL org.opencontainers.image.version="1.0.0" -LABEL ai-army.worker-type="qa-engineer" -LABEL ai-army.tools="bash,git,npm,playwright,readFile,writeFile" - -# Install system dependencies -RUN apt-get update && apt-get install -y --no-install-recommends \ - git \ - curl \ - python3 \ - ca-certificates \ - && rm -rf /var/lib/apt/lists/* - -# Install Playwright with Chromium browser and system deps -RUN npx playwright install --with-deps chromium - -# Install global testing tools -RUN npm install -g \ - @playwright/test@latest \ - jest@latest \ - vitest@latest \ - && npm cache clean --force - -# Create agent user and workspace -RUN useradd -m -s /bin/bash agent - -WORKDIR /home/agent - -# Configure git for AI worker -RUN git config --global user.name "AI Worker" && \ - git config --global user.email "worker@ai-army.dev" && \ - git config --global init.defaultBranch main - -# Set permissions -RUN chown -R agent:agent /home/agent - -USER agent - -CMD ["sleep", "infinity"] diff --git a/scripts/build-images.sh b/scripts/build-images.sh deleted file mode 100755 index fa1074f..0000000 --- a/scripts/build-images.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash -set -e - -REGISTRY="${DOCKER_REGISTRY:-ai-army}" -VERSION="${VERSION:-latest}" - -IMAGES=( - "frontend-developer" - "backend-developer" - "devops-engineer" - "data-scientist" - "qa-engineer" -) - -echo "๐Ÿณ Building AI Army worker images..." -echo "Registry: $REGISTRY" -echo "Version: $VERSION" -echo "" - -for image in "${IMAGES[@]}"; do - echo "๐Ÿ“ฆ Building $image..." - - docker build \ - -t "$REGISTRY/$image:$VERSION" \ - -t "$REGISTRY/$image:latest" \ - docker/images/$image/ - - echo " โœ… Built $image" - echo "" -done - -echo "๐ŸŽ‰ All images built successfully!" diff --git a/scripts/test-images.sh b/scripts/test-images.sh deleted file mode 100755 index e1981e9..0000000 --- a/scripts/test-images.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/bash -set -e - -REGISTRY="${DOCKER_REGISTRY:-ai-army}" -VERSION="${VERSION:-latest}" - -IMAGES=( - "frontend-developer" - "backend-developer" - "devops-engineer" - "data-scientist" - "qa-engineer" -) - -echo "๐Ÿงช Testing AI Army worker images..." -echo "Registry: $REGISTRY" -echo "Version: $VERSION" -echo "" - -for image in "${IMAGES[@]}"; do - echo "Testing $image..." - - CONTAINER_NAME="test-$image-$$" - - # Start container - echo " Starting container..." - docker run -d --name "$CONTAINER_NAME" "$REGISTRY/$image:$VERSION" > /dev/null - - # Test Node.js available (for frontend-developer, backend-developer, qa-engineer) - if [[ "$image" == "frontend-developer" ]] || [[ "$image" == "backend-developer" ]] || [[ "$image" == "qa-engineer" ]]; then - echo " Checking Node.js..." - docker exec "$CONTAINER_NAME" node --version || exit 1 - fi - - # Test Python available (for backend-developer, data-scientist, qa-engineer) - if [[ "$image" == "backend-developer" ]] || [[ "$image" == "data-scientist" ]] || [[ "$image" == "qa-engineer" ]]; then - echo " Checking Python..." - docker exec "$CONTAINER_NAME" python3 --version || exit 1 - fi - - # Test git available (all images) - echo " Checking git..." - docker exec "$CONTAINER_NAME" git --version || exit 1 - - # Test workspace writable (all images) - echo " Checking workspace is writable..." - docker exec "$CONTAINER_NAME" sh -c 'echo test > /home/agent/test.txt' || exit 1 - - # Cleanup - echo " Cleaning up..." - docker rm -f "$CONTAINER_NAME" > /dev/null - - echo " โœ… $image passed" - echo "" -done - -echo "๐ŸŽ‰ All images tested successfully!"