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