Project /
Building from source
Build the Gresbase binary and Docker image yourself, with the same commands the project uses.
On this page
Before you start#
The recommended way needs only Docker and git. Every toolchain runs inside the development container.
If you prefer to build on your own machine, you need:
| Tool | Version | Where it comes from |
|---|---|---|
| Go | 1.27.2 | go.mod |
| Node.js | 22 or newer | engines in web/package.json |
| pnpm | 12.10.1 | packageManager in web/package.json (enable it with corepack enable) |
| Task | v3 | Taskfile.yml |
You don't need to build Gresbase to use it: each release publishes the image ghcr.io/amtzespinosa/gresbase:latest and binaries for Linux, macOS and Windows. Build it yourself to try unreleased changes or to contribute.
Build the Docker image#
Run this from the root of the repository. You don't need Go or Node: the Dockerfile brings its own.
docker build -t gresbase --build-arg VERSION=dev .The build has three stages:
node:22-bookworm-sliminstalls the web dependencies with pnpm and compiles the frontend.golang:1.27-bookwormcompiles a static binary withCGO_ENABLED=0and the frontend embedded.gcr.io/distroless/static-debian12:nonrootis the final image: the binary, the license files in/licenses/and the/datavolume.
VERSION is optional and defaults to dev. The binary prints it with gresbase version. The image listens on port 8080, runs as a non-root user and has its own health check (gresbase healthcheck).
Use gresbase as the image name in the examples of Running with docker run or the Quick start.
Use the development container#
dev.compose.yml starts a container with Go, Node 22 with pnpm, Task, golangci-lint, tygo, Playwright and psql. It also starts its own Docker daemon for integration tests and the sample database.
-
Start the container#
Terminaldocker compose -f dev.compose.yml up -d --buildThe first build takes a while. Later starts reuse the image and the caches.
-
Run a task inside it#
Terminaldocker compose -f dev.compose.yml exec -T workspace bash -lc "task build"Replace
task buildwith any command from the table below. -
Develop with live reload#
Terminaldocker compose -f dev.compose.yml exec workspace bash -lc "task dev"Open
http://localhost:15173for Vite orhttp://localhost:18080for the backend. The backend restarts when a Go file changes.
Use git from your machine, not from the container. The container has no git identity and no SSH keys.
Task commands#
| Command | What it does |
|---|---|
task build |
Builds the frontend and then bin/gresbase with the frontend embedded |
task dev |
Sample PostgreSQL, backend with reload and Vite |
task dev:db |
Sample PostgreSQL only (deploy/docker-compose.dev.yml) |
task test |
Go tests and Vitest |
task test:go:all |
Go tests against PostgreSQL 12 to 19, one version after another |
task e2e |
Playwright against the compiled binary and a freshly reset sample database |
task lint |
golangci-lint, ESLint, tsc, Prettier, generated types, license report and actionlint |
task gen |
Regenerates web/src/lib/api/types.gen.ts from the Go structs with tygo |
task licenses |
Regenerates the third-party license report and notices |
task ci:quick |
Local CI for every merge: lint, generated types, Go on PostgreSQL 18, Vitest and e2e on 18 |
task ci:full |
ci:quick plus Go on 12 to 19, e2e on 12, 17 and 18, the binary, the image and a Docker smoke test |
task image:local |
Builds the image gresbase:local |
task image:export |
Saves gresbase:local to dist/gresbase-local.tar |
The Go integration tests start a real PostgreSQL with testcontainers. PG_VERSION picks its version (17 by default).
How the binary is built#
task build runs pnpm build in web/ first. Vite writes the frontend to internal/ui/dist, and the internal/ui package embeds that folder with go:embed.
Then it runs go build on ./cmd/gresbase and writes bin/gresbase. The Taskfile sets CGO_ENABLED=0, so the binary is static and has no system dependencies.
The version comes from git describe. Without a tag it is dev+<short commit>, with -dirty if there are uncommitted changes.
To run the binary outside Docker, point it at a database and at a writable data folder:
DATABASE_URL=postgres://USER:PASSWORD@HOST:5432/DBNAME \
GRESBASE_DATA_DIR=./data \
./bin/gresbaseIt listens on port 8080 (GRESBASE_PORT) on every interface. GRESBASE_DATA_DIR is /data by default, which rarely exists outside a container. The rest of the options are in Environment variables.
Try a local image on another machine#
task image:local builds gresbase:local inside the development container's own Docker daemon. Your machine's Docker doesn't see it.
To take it out, export it and load it on your machine:
docker compose -f dev.compose.yml exec -T workspace bash -lc "task image:export"
docker load -i dist/gresbase-local.tarThe project folder is mounted in the container, so dist/gresbase-local.tar appears in your copy of the repository.
goreleaser release --snapshot --clean builds the standalone binaries for Linux, macOS and Windows (amd64 and arm64) locally. It publishes nothing.