Skip to content

Commit 6d2965d

Browse files
NikolaySagneum
authored andcommitted
Add ARM64/Colima support and fix UI API proxying
1 parent 0fe7abe commit 6d2965d

2 files changed

Lines changed: 284 additions & 3 deletions

File tree

docs/colima-supabase-setup.md

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# DBLab with Colima (ARM64/Apple Silicon)
2+
3+
This guide explains how to run DBLab Engine on macOS with Apple Silicon using Colima.
4+
5+
## Prerequisites
6+
7+
- macOS with Apple Silicon (M1/M2/M3/M4)
8+
- [Colima](https://github.com/abiosoft/colima) installed
9+
- Docker CLI installed
10+
- Go 1.24+ (for building from source)
11+
12+
## Known Limitations
13+
14+
### ARM64 Docker Images
15+
16+
The official DBLab images are currently **amd64 only**:
17+
- `postgresai/extended-postgres:*` - amd64 only
18+
- `postgresai/ce-ui:*` - amd64 only
19+
20+
For ARM64, you need to build images from source (see below).
21+
22+
## Setup Steps
23+
24+
### 1. Start Colima and Set Up ZFS
25+
26+
Colima does not include ZFS by default. Use the provided init script to install ZFS utilities and create the pool:
27+
28+
```bash
29+
colima start
30+
31+
# Copy and run the ZFS init script inside Colima
32+
colima ssh < engine/scripts/init-zfs-colima.sh
33+
```
34+
35+
The script installs `zfsutils-linux`, creates a 5 GB virtual disk, and sets up a ZFS pool (`dblab_pool`) with datasets at `/var/lib/dblab/dblab_pool`.
36+
37+
If you need to customize the pool size or dataset names, edit the variables at the top of `engine/scripts/init-zfs-colima.sh` before running it.
38+
39+
### 2. Build ARM64 Images
40+
41+
Make sure your Docker CLI is configured to use Colima's Docker daemon:
42+
43+
```bash
44+
docker context use colima
45+
```
46+
47+
All `docker` commands below run against Colima, so no image transfer is needed.
48+
49+
#### DBLab Server
50+
51+
From the repository root:
52+
53+
```bash
54+
cd engine
55+
GOOS=linux GOARCH=arm64 make build
56+
make build-image
57+
```
58+
59+
This builds the server binary for ARM64 and creates a Docker image tagged `dblab_server:local`.
60+
61+
#### PostgreSQL Image
62+
63+
The `postgresai/extended-postgres` images are amd64 only. For ARM64, create a minimal Postgres image.
64+
65+
In the `engine/` directory, create `Dockerfile.dblab-postgres-arm64`:
66+
67+
```dockerfile
68+
FROM postgres:17-bookworm
69+
70+
ENV PG_UNIX_SOCKET_DIR=/var/run/postgresql
71+
ENV PG_SERVER_PORT=5432
72+
73+
RUN apt-get update && apt-get install -y --no-install-recommends sudo \
74+
&& rm -rf /var/lib/apt/lists/* \
75+
&& rm -rf /var/lib/postgresql/17/
76+
77+
RUN echo '#!/bin/bash' > /pg_start.sh && chmod a+x /pg_start.sh \
78+
&& echo 'chown -R postgres:postgres ${PGDATA} ${PG_UNIX_SOCKET_DIR}' >> /pg_start.sh \
79+
&& echo 'sudo -Eu postgres /usr/lib/postgresql/17/bin/postgres -D ${PGDATA} -k ${PG_UNIX_SOCKET_DIR} -p ${PG_SERVER_PORT} >& /proc/1/fd/1' >> /pg_start.sh \
80+
&& echo '/bin/bash -c "trap : TERM INT; sleep infinity & wait"' >> /pg_start.sh
81+
82+
CMD ["/pg_start.sh"]
83+
```
84+
85+
```bash
86+
docker build -f Dockerfile.dblab-postgres-arm64 \
87+
--platform linux/arm64 \
88+
-t dblab-postgres:17-arm64 .
89+
```
90+
91+
#### DBLab CE UI (optional)
92+
93+
From the repository root:
94+
95+
```bash
96+
cd ..
97+
docker build -f ui/packages/ce/Dockerfile \
98+
--platform linux/arm64 \
99+
-t dblab-ce-ui:arm64 .
100+
```
101+
102+
### 3. Create DBLab Configuration
103+
104+
Create `engine/configs/server.yml` based on one of the example configs in `engine/configs/`. A minimal example:
105+
106+
```yaml
107+
server:
108+
verificationToken: "your_token_here"
109+
host: "0.0.0.0"
110+
port: 2345
111+
112+
embeddedUI:
113+
enabled: false # We'll run UI separately for ARM64
114+
115+
global:
116+
engine: postgres
117+
debug: true
118+
database:
119+
username: postgres
120+
dbname: postgres
121+
122+
poolManager:
123+
mountDir: /var/lib/dblab/dblab_pool
124+
dataSubDir: ""
125+
clonesMountSubDir: clones
126+
socketSubDir: sockets
127+
observerSubDir: observer
128+
preSnapshotSuffix: "_pre"
129+
selectedPool: "dataset_1"
130+
131+
databaseContainer:
132+
dockerImage: "dblab-postgres:17-arm64"
133+
containerConfig:
134+
"shm-size": 256mb
135+
136+
provision:
137+
portPool:
138+
from: 6000
139+
to: 6010
140+
useSudo: false
141+
keepUserPasswords: true
142+
cloneAccessAddresses: "127.0.0.1"
143+
144+
retrieval:
145+
refresh:
146+
timetable: ""
147+
jobs:
148+
- physicalSnapshot
149+
spec:
150+
physicalSnapshot:
151+
options:
152+
skipStartSnapshot: false
153+
promotion:
154+
enabled: false
155+
156+
cloning:
157+
accessHost: "localhost"
158+
maxIdleMinutes: 60
159+
160+
platform:
161+
enableTelemetry: false
162+
```
163+
164+
### 4. Initialize PostgreSQL Data on ZFS
165+
166+
Start a PostgreSQL container to initialize data on the ZFS dataset:
167+
168+
```bash
169+
docker run -d --name pg-init \
170+
-e POSTGRES_PASSWORD=postgres \
171+
-v /var/lib/dblab/dblab_pool/dataset_1:/var/lib/postgresql/data \
172+
postgres:17-bookworm
173+
174+
# Wait for initialization to complete
175+
docker logs -f pg-init
176+
# Press Ctrl+C once you see "database system is ready to accept connections"
177+
178+
# Stop and remove the init container
179+
docker stop pg-init && docker rm pg-init
180+
181+
# Create the initial snapshot
182+
colima ssh -- sudo zfs snapshot dblab_pool/dataset_1@initial_data
183+
```
184+
185+
### 5. Start DBLab Server
186+
187+
Use `rshared` mount propagation so that ZFS clones are visible inside child containers.
188+
189+
First, copy the config into the Colima VM. From the `engine/` directory:
190+
191+
```bash
192+
colima ssh -- mkdir -p /var/lib/dblab/configs
193+
colima ssh -- tee /var/lib/dblab/configs/server.yml < configs/server.yml > /dev/null
194+
```
195+
196+
Then start the server:
197+
198+
```bash
199+
docker run -d --name dblab-server \
200+
--privileged \
201+
-v /var/run/docker.sock:/var/run/docker.sock \
202+
-v /var/lib/dblab:/var/lib/dblab:rshared \
203+
-v /var/lib/docker:/var/lib/docker \
204+
-v /var/lib/dblab/configs:/home/dblab/configs \
205+
-e HOSTNAME=dblab-server \
206+
-p 2345:2345 \
207+
dblab_server:local
208+
```
209+
210+
### 6. Start DBLab UI (optional)
211+
212+
```bash
213+
docker run -d --name dblab-ce-ui \
214+
-e DLE_HOST=host.docker.internal \
215+
-e DLE_PORT=2345 \
216+
-p 2346:80 \
217+
--add-host=host.docker.internal:host-gateway \
218+
dblab-ce-ui:arm64
219+
```
220+
221+
### 7. Use DBLab CLI
222+
223+
```bash
224+
cd engine && make build-client
225+
226+
dblab init \
227+
--url http://localhost:2345 \
228+
--token your_token_here \
229+
--environment-id local
230+
231+
dblab clone create --id dev1 --username postgres --password 'SecurePass123!'
232+
233+
dblab clone list
234+
235+
# Connect to a clone
236+
psql -h localhost -p 6000 -U postgres -d postgres
237+
```
238+
239+
## Supabase Integration
240+
241+
To use DBLab with a Supabase-managed PostgreSQL instance:
242+
243+
1. Set the database user to `supabase_admin` (Supabase superuser) in the config:
244+
245+
```yaml
246+
global:
247+
database:
248+
username: supabase_admin
249+
```
250+
251+
2. Initialize data using the Supabase Postgres image instead of stock Postgres:
252+
253+
```bash
254+
docker run -d --name supabase-pg-init \
255+
-e POSTGRES_PASSWORD=postgres \
256+
-v /var/lib/dblab/dblab_pool/dataset_1:/var/lib/postgresql/data \
257+
-p 5433:5432 \
258+
public.ecr.aws/supabase/postgres:17.6.1.064
259+
```
260+
261+
3. Set `dataSubDir: ""` in poolManager since Supabase puts data at the dataset root.
262+
263+
## Troubleshooting
264+
265+
### Clone containers cannot see data
266+
267+
Ensure dblab-server is started with `-v /var/lib/dblab:/var/lib/dblab:rshared` for mount propagation.
268+
269+
### "permission denied to alter role"
270+
271+
The database user in your config needs superuser privileges. For Supabase, use `supabase_admin`.
272+
273+
### UI shows JSON parse errors
274+
275+
The UI calls some API endpoints directly (without the `/api/` prefix). Make sure the nginx proxy configuration includes all required endpoint locations.

ui/packages/ce/nginx.conf

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,27 @@ server {
1111
# It allows to serve both versions: compressed and not.
1212
gzip_vary on;
1313

14-
# No-cache doesnt mean dont cache, it means it must revalidate with the server before using the cached resource.
14+
# No-cache doesn't mean "don't cache", it means it must revalidate with the server before using the cached resource.
1515
add_header Cache-Control 'no-cache';
1616

17-
# Enable entity tag to revalidate cache.
17+
# Enable entity tag to revalidate cache.
1818
etag on;
1919

2020
# Serve files.
2121
try_files $uri $uri/ /index.html;
2222
}
2323

24+
# API endpoints proxied directly to the DLE server.
25+
location ~ ^/(healthz|status|instance|branch|branches|clone|clones|snapshot|snapshots|observation|admin|full-refresh)(/|$) {
26+
resolver 127.0.0.11;
27+
proxy_http_version 1.1;
28+
proxy_pass http://${DLE_HOST}:${DLE_PORT}$request_uri;
29+
}
30+
2431
location /api/ {
2532
# Docker resolver.
2633
resolver 127.0.0.11;
2734

28-
# TODO: finalize "proxy_http_version" and "proxy_pass".
2935
proxy_http_version 1.1;
3036

3137
# Don't remove trailing slash, it cuts "/api" prefix.

0 commit comments

Comments
 (0)