| 3e3af55 | | | 1 | # Grove — Full Development Stack |
| 3e3af55 | | | 2 | # |
| 3e3af55 | | | 3 | # Quick start: |
| 36387cc | | | 4 | # 1. Build Mononoke: cd sapling && docker build -f ../docker/Dockerfile.mononoke -t grove/mononoke . |
| 36387cc | | | 5 | # 2. Import a repo: ./scripts/import-repo.sh /path/to/git/repo grove |
| 3e3af55 | | | 6 | # 3. Start: docker compose up |
| 3e3af55 | | | 7 | # |
| 3c994d3 | | | 8 | # Or run just the app layer while developing: |
| 3c994d3 | | | 9 | # docker compose up grove-hub-api grove-api grove-web |
| 3e3af55 | | | 10 | |
| 3e3af55 | | | 11 | services: |
| 3e3af55 | | | 12 | # ─── Mononoke Layer ─────────────────────────────────────────────── |
| 3e3af55 | | | 13 | |
| 3e3af55 | | | 14 | # SLAPI Server — Sapling Remote API (primary data API) |
| 3e3af55 | | | 15 | mononoke-slapi: |
| 3e3af55 | | | 16 | image: ghcr.io/letterpress-labs/grove-mononoke:latest |
| 3e3af55 | | | 17 | container_name: grove-mononoke-slapi |
| 3e3af55 | | | 18 | command: |
| 3e3af55 | | | 19 | - --listening-host-port |
| 3e3af55 | | | 20 | - "0.0.0.0:8443" |
| 3e3af55 | | | 21 | - --config-path |
| 3e3af55 | | | 22 | - /config |
| 3e3af55 | | | 23 | - --test-instance |
| 3e3af55 | | | 24 | ports: |
| 3e3af55 | | | 25 | - "8443:8443" |
| 3e3af55 | | | 26 | volumes: |
| 3e3af55 | | | 27 | - ../config/mononoke:/config:ro |
| 3e3af55 | | | 28 | - mononoke-data:/data/mononoke |
| 3e3af55 | | | 29 | - ../config/certs:/certs:ro |
| 3e3af55 | | | 30 | healthcheck: |
| 3e3af55 | | | 31 | test: ["CMD", "curl", "-sf", "http://localhost:8443/health_check"] |
| 3e3af55 | | | 32 | interval: 10s |
| 3e3af55 | | | 33 | timeout: 5s |
| 3e3af55 | | | 34 | retries: 3 |
| 3e3af55 | | | 35 | restart: unless-stopped |
| 3e3af55 | | | 36 | |
| 3e3af55 | | | 37 | # Git Server — standard Git HTTP protocol for clone/push/pull |
| 3e3af55 | | | 38 | mononoke-git: |
| 3e3af55 | | | 39 | image: ghcr.io/letterpress-labs/grove-mononoke:latest |
| 3e3af55 | | | 40 | container_name: grove-mononoke-git |
| 3e3af55 | | | 41 | entrypoint: ["/usr/local/bin/git_server"] |
| 3e3af55 | | | 42 | command: |
| 3e3af55 | | | 43 | - --listening-host-port |
| 3e3af55 | | | 44 | - "0.0.0.0:8080" |
| 3e3af55 | | | 45 | - --config-path |
| 3e3af55 | | | 46 | - /config |
| 3e3af55 | | | 47 | - --test-instance |
| 3e3af55 | | | 48 | ports: |
| 3e3af55 | | | 49 | - "8080:8080" |
| 3e3af55 | | | 50 | volumes: |
| 3e3af55 | | | 51 | - ../config/mononoke:/config:ro |
| 3e3af55 | | | 52 | - mononoke-data:/data/mononoke |
| 3e3af55 | | | 53 | - ../config/certs:/certs:ro |
| 3e3af55 | | | 54 | depends_on: |
| 3e3af55 | | | 55 | mononoke-slapi: |
| 3e3af55 | | | 56 | condition: service_healthy |
| 3e3af55 | | | 57 | restart: unless-stopped |
| 3e3af55 | | | 58 | |
| 3e3af55 | | | 59 | # ─── Grove App Layer ────────────────────────────────────────────── |
| 3e3af55 | | | 60 | |
| 3c994d3 | | | 61 | # Hub API — identity provider (WebAuthn passkeys, PATs, instance management) |
| 3c994d3 | | | 62 | grove-hub-api: |
| 3c994d3 | | | 63 | build: |
| 3c994d3 | | | 64 | context: .. |
| 3c994d3 | | | 65 | dockerfile: docker/Dockerfile.grove-hub-api |
| 3c994d3 | | | 66 | container_name: grove-hub-api |
| 3c994d3 | | | 67 | ports: |
| 3c994d3 | | | 68 | - "4001:4000" |
| 3c994d3 | | | 69 | volumes: |
| 3c994d3 | | | 70 | - hub-data:/data |
| 3c994d3 | | | 71 | environment: |
| 3c994d3 | | | 72 | - PORT=4000 |
| 3c994d3 | | | 73 | - DATABASE_PATH=/data/hub.db |
| 3c994d3 | | | 74 | - JWT_SECRET=${JWT_SECRET:-grove-dev-secret} |
| 3c994d3 | | | 75 | - RP_ID=localhost |
| 3c994d3 | | | 76 | - ORIGIN=http://localhost:3000 |
| 3c994d3 | | | 77 | - CORS_ORIGIN=http://localhost:3000 |
| 3c994d3 | | | 78 | restart: unless-stopped |
| 3c994d3 | | | 79 | |
| fb964da | | | 80 | # Instance API — repo browsing, diffs, CI/CD runner (verifies hub-signed JWTs) |
| 3e3af55 | | | 81 | grove-api: |
| 3e3af55 | | | 82 | build: |
| 3e3af55 | | | 83 | context: .. |
| 3e3af55 | | | 84 | dockerfile: docker/Dockerfile.grove-api |
| 3e3af55 | | | 85 | container_name: grove-api |
| 3e3af55 | | | 86 | ports: |
| 3e3af55 | | | 87 | - "4000:4000" |
| 3e3af55 | | | 88 | volumes: |
| 3e3af55 | | | 89 | - grove-data:/data |
| 3e3af55 | | | 90 | - repo-mirrors:/data/repos |
| 3e3af55 | | | 91 | environment: |
| 3e3af55 | | | 92 | - PORT=4000 |
| 3e3af55 | | | 93 | - DATABASE_PATH=/data/grove.db |
| 5130d10 | | | 94 | - GROVE_HUB_API_URL=http://grove-hub-api:4000 |
| 3e3af55 | | | 95 | - MONONOKE_GIT_URL=http://mononoke-git:8080 |
| 3e3af55 | | | 96 | - REPOS_DIR=/data/repos |
| 3c994d3 | | | 97 | - JWT_SECRET=${JWT_SECRET:-grove-dev-secret} |
| 3e3af55 | | | 98 | - CORS_ORIGIN=http://localhost:3000 |
| fb964da | | | 99 | healthcheck: |
| 39ac157 | | | 100 | test: ["CMD", "wget", "-qO-", "http://127.0.0.1:4000/health"] |
| fb964da | | | 101 | interval: 10s |
| fb964da | | | 102 | timeout: 3s |
| fb964da | | | 103 | start_period: 15s |
| fb964da | | | 104 | retries: 3 |
| 3e3af55 | | | 105 | depends_on: |
| 3e3af55 | | | 106 | mononoke-git: |
| 3e3af55 | | | 107 | condition: service_started |
| 3e3af55 | | | 108 | restart: unless-stopped |
| 3e3af55 | | | 109 | |
| 3e3af55 | | | 110 | # Web UI — Next.js frontend |
| 3e3af55 | | | 111 | grove-web: |
| 3e3af55 | | | 112 | build: |
| 3e3af55 | | | 113 | context: .. |
| 3e3af55 | | | 114 | dockerfile: docker/Dockerfile.grove-web |
| 3e3af55 | | | 115 | container_name: grove-web |
| 3e3af55 | | | 116 | ports: |
| 3e3af55 | | | 117 | - "3000:3000" |
| 3e3af55 | | | 118 | environment: |
| 3e3af55 | | | 119 | - GROVE_API_URL=http://grove-api:4000 |
| 3c994d3 | | | 120 | - GROVE_HUB_API_URL=http://grove-hub-api:4000 |
| 3e3af55 | | | 121 | depends_on: |
| 3e3af55 | | | 122 | - grove-api |
| 3c994d3 | | | 123 | - grove-hub-api |
| 3e3af55 | | | 124 | restart: unless-stopped |
| 3e3af55 | | | 125 | |
| 3e3af55 | | | 126 | volumes: |
| 3e3af55 | | | 127 | mononoke-data: |
| 3e3af55 | | | 128 | driver: local |
| 3c994d3 | | | 129 | hub-data: |
| 3c994d3 | | | 130 | driver: local |
| 3e3af55 | | | 131 | grove-data: |
| 3e3af55 | | | 132 | driver: local |
| 3e3af55 | | | 133 | repo-mirrors: |
| 3e3af55 | | | 134 | driver: local |