Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## What This Is

A minimal Docker Compose setup for running LabKey Community Edition locally. Two services: `community` (LabKey app on Tomcat) and `pg-community` (PostgreSQL 17).
A minimal Docker Compose setup for running LabKey Community Edition locally. Two services: `community` (LabKey app on Tomcat) and `pg-community` (PostgreSQL — 18 by default, override with `PG_VERSION`).

## Common Commands

Expand All @@ -19,7 +19,7 @@ docker compose down
docker compose down -v --remove-orphans

# Override image version at launch
export IDENT="labkeyteamcity/labkey-community:26.3.0" && docker compose up community --detach
COMPOSE_IMAGE="labkeyteamcity/labkey-community:26.3.0" docker compose up community --detach
```

Access at `https://localhost:8443` after startup (self-signed cert — expect browser warning).
Expand All @@ -32,6 +32,7 @@ Key overridable variables:
- `COMPOSE_IMAGE` — LabKey image tag (default: `labkeyteamcity/labkey-community:26.3.0`)
- `HOST_PORT` — host HTTPS port (default: `8443`)
- `PG_PORT` — host PostgreSQL port (default: `54321`)
- `PG_VERSION` — PostgreSQL major version / `pg-community` image tag (default: `18`); also the data-dir suffix
- `POSTGRES_PASSWORD` — shared between both services
- `MAX_JVM_RAM_PERCENT` — JVM heap ceiling (default: `75.0`)
- `LABKEY_CREATE_INITIAL_USER` / `LABKEY_CREATE_INITIAL_USER_APIKEY` — skip setup wizard if set
Expand All @@ -42,7 +43,7 @@ Key overridable variables:
`mounts/` is gitignored. Do not delete these without understanding the consequences:
- `mounts/files/` — LabKey file storage
- `mounts/logs/` — server logs
- `mounts/pgdata/` — PostgreSQL data files (subdirectory keyed by `$IDENT`)
- `mounts/pgdata/` — PostgreSQL data files (subdirectory keyed by `$IDENT` and `$PG_VERSION`)
- `mounts/modules/` — custom/external LabKey modules

## Upgrading LabKey Version
Expand All @@ -52,3 +53,21 @@ Edit the `image:` line in `docker-compose.yml` (or set `COMPOSE_IMAGE`). Only ta
## Branching and PR Workflow

The `.github/workflows/workflow.yml` runs `LabKey/gitHubActions/validate-pr@develop` on all PRs. It only executes for PRs from the `LabKey` org. Feature branches follow the pattern `fb_<version>_<description>` based on recent history.

## Commit and PR Body Formatting

Applies to every commit body and every PR body, without exception. Do not hard-wrap. Write each paragraph and each bullet as a single physical line, no matter how long. Separate paragraphs with one blank line. This applies to text passed via `-m`, `--body`, here-docs, `gh pr edit`, GitHub MCP tools — every channel that produces commit or PR body text.

**Why:** GitHub renders commit and PR bodies as GFM with hard-line-break enabled. Every mid-paragraph `\n` becomes a visible `<br>` in the rendered output, producing ragged, broken-looking text. Soft-wrap is the renderer's job, not yours.

**Self-check before invoking `git commit`, `gh pr create`, or `gh pr edit`:** look at the body text you are about to pass. If any paragraph spans more than one line in your tool call, that is a bug — collapse it to a single line first. Long lines are correct. Wrapped lines are wrong.

## Commit Messages

Subject: short imperative (≈70 chars). Body: follow the formatting rule above — one physical line per paragraph, blank lines between paragraphs.

## Pull Request Format

If the repo has a `pull_request_template.md` (typically under `.github/`), follow it. Otherwise, include sections for: **Rationale** (why the change is needed), **Related Pull Requests**, and **Changes** (notable items). Keep descriptions brief. Follow the formatting rule above — one physical line per paragraph and per bullet.

Before opening a PR, always draft the title and description and confirm them with the user. Do not run `gh pr create` until the user approves.
30 changes: 28 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,31 @@ There are a substantial number of configuration options available. The `docker-
### Upgrading versions
We only publish tagged versions to Docker Hub (we don't publish a 'latest' tag). To upgrade to a new version of LabKey Community edition, you have two options:
1. Edit the `docker-compose.yml` file and update the `image` version to the LabKey version you wish to use.
2. Launch a new version with the `docker compose up` command line.
`export IDENT="labkeyteamcity/labkey-community:26.3.0" docker compose up community --detach`
2. Launch a new version from the command line by setting `COMPOSE_IMAGE`.
`COMPOSE_IMAGE="labkeyteamcity/labkey-community:26.3.0" docker compose up community --detach`

### PostgreSQL version

The database defaults to **PostgreSQL 18** (`image: postgres:${PG_VERSION:-18}`). The major
version is included in the data-directory name (`./mounts/pgdata/<IDENT>-<PG_VERSION>-data`), so
each version keeps its own directory on disk.

PostgreSQL will not read a data directory created by an older major version, so an existing
Postgres 17 database cannot be started by the Postgres 18 image in place:

- **Start fresh on Postgres 18 (simplest):** just `docker compose up community --detach`. A new,
empty data directory is created; your old data under `./mounts/pgdata/postgres-data` is left
untouched (delete it once you no longer need it).
- **Keep your existing Postgres 17 data:** pin the old version — `PG_VERSION=17 docker compose up
community --detach`. If your data predates this change it lives in the legacy
`./mounts/pgdata/postgres-data` directory; rename it to `postgres-17-data` first.

To carry real data forward, dump from a running Postgres 17 container and restore into Postgres 18:

```bash
PG_VERSION=17 docker compose up -d pg-community
docker compose exec pg-community pg_dumpall -U postgres > dump.sql
PG_VERSION=17 docker compose down
docker compose up -d pg-community # Postgres 18, fresh data dir
cat dump.sql | docker compose exec -T pg-community psql -U postgres
```
13 changes: 10 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,30 @@ services:
- PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS=${PURGE_HEAP_AND_ERROR_LOGS_OLDER_THAN_DAYS:-90}

pg-community:
image: postgres:17
image: postgres:${PG_VERSION:-18}
container_name: pg-community
# run postgres through the image entrypoint; logs stay visible so
# version/startup errors (e.g. pg data-dir incompatibility) surface in
# `docker compose logs` instead of the container silently crash-looping.
entrypoint:
- "/bin/bash"
- "-c"
- "docker-entrypoint.sh postgres >/dev/null 2>&1"
- "docker-entrypoint.sh postgres"
environment:
# we recommend changing this to a strong random password of at least 16 characters
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-a"placeholder#'password}
# pin PGDATA to the pre-18 default so the bind mount below keeps
# persisting data: the postgres:18 image moved its default PGDATA to
# /var/lib/postgresql/18/docker, which would bypass this mount entirely.
- PGDATA=/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
volumes:
- ./mounts/pgdata/${IDENT:-postgres}-data:/var/lib/postgresql/data
- ./mounts/pgdata/${IDENT:-postgres}-${PG_VERSION:-18}-data:/var/lib/postgresql/data
ports:
- ${PG_PORT:-54321}:5432