Skip to content

Commit 93642ad

Browse files
authored
feat: add Datomic Free→Pro migration tooling
Bare-metal script (scripts/migrate-db.sh) wraps bin/datomic CLI for backup/restore/verify/list with auto-detection of Free vs Pro distributions. For backup, searches lib/ for an extracted Free distribution, prompts interactively if not found, extracts the bundled tarball (lib/datomic-free-0.9.5703.tar.gz) as last resort. Docker wrapper (docker-migrate.sh) runs the same operations in temporary containers, auto-detecting images and Compose networks. Includes full migration docs (runbook + in-depth explanation), devcontainer Dockerfile simplification (pre-cache zip only, let post-create.sh handle install), and datomic container unzip fix.
1 parent 55e9f49 commit 93642ad

10 files changed

Lines changed: 1830 additions & 82 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 7 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -16,62 +16,15 @@ RUN curl -fsSL https://raw.githubusercontent.com/technomancy/leiningen/stable/bi
1616

1717
WORKDIR /workspace
1818

19-
# Copy project.clj first (needed to know version)
20-
COPY project.clj /workspace/
21-
22-
# Copy existing lib/ directory first (preserves pdfbox and other vendor deps)
23-
# Create lib/ directory - COPY will handle copying if lib/ exists in build context
24-
RUN mkdir -p /workspace/lib/
25-
COPY lib/ /workspace/lib/
19+
# Copy project source (lib/ includes pdfbox vendor deps from host)
20+
COPY . /workspace
2621

27-
# Download and install Datomic Pro to lib/ using existing file:lib repository pattern
28-
# Latest version: https://docs.datomic.com/releases-pro.html
22+
# Pre-cache Datomic Pro zip so post-create.sh skips the download.
23+
# The actual install (extract, flatten, maven-install) is done by post-create.sh
24+
# because the volume mount overwrites /workspace during container creation.
2925
ARG DATOMIC_VERSION=1.0.7482
30-
RUN echo "[DOCKER BUILD] Starting Datomic Pro ${DATOMIC_VERSION} installation..." && \
31-
mkdir -p lib/com/datomic/datomic-pro/${DATOMIC_VERSION} && \
32-
echo "[DOCKER BUILD] Downloading Datomic Pro zip..." && \
33-
curl -L -o /tmp/datomic-pro-${DATOMIC_VERSION}.zip \
34-
"https://datomic-pro-downloads.s3.amazonaws.com/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.zip" && \
35-
echo "[DOCKER BUILD] Extracting zip..." && \
36-
unzip -q /tmp/datomic-pro-${DATOMIC_VERSION}.zip -d /tmp/datomic-extract && \
37-
echo "[DOCKER BUILD] Listing extracted contents..." && \
38-
find /tmp/datomic-extract -type f -name "*.jar" | head -5 && \
39-
# Copy entire distribution into vendor layout so POMs and support files are available
40-
EXTRACTED_DIR=$(find /tmp/datomic-extract -maxdepth 1 -type d ! -name . | head -1) && \
41-
mkdir -p lib/com/datomic/datomic-pro/${DATOMIC_VERSION} && \
42-
if [ -n "${EXTRACTED_DIR}" ]; then \
43-
echo "[DOCKER BUILD] Copying extracted distribution from ${EXTRACTED_DIR} -> lib/com/datomic/datomic-pro/${DATOMIC_VERSION}" && \
44-
cp -r "${EXTRACTED_DIR}"/* "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/" && \
45-
# If a peer jar exists in the distribution, also ensure datomic-pro-<version>.jar exists for vendor layout
46-
if [ -f "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/peer-${DATOMIC_VERSION}.jar" ]; then \
47-
cp "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/peer-${DATOMIC_VERSION}.jar" "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.jar"; \
48-
fi; \
49-
else \
50-
# Fallback to copying a single jar if extraction produced unexpected layout
51-
DATOMIC_POTENTIAL_JAR=$(find /tmp/datomic-extract -type f -name 'peer*.jar' -print -quit || true) && \
52-
if [ -z "${DATOMIC_POTENTIAL_JAR}" ]; then DATOMIC_POTENTIAL_JAR=$(find /tmp/datomic-extract -type f -name 'datomic-pro-*.jar' -print -quit || true); fi && \
53-
if [ -z "${DATOMIC_POTENTIAL_JAR}" ]; then echo "[DOCKER BUILD] ERROR: No Datomic JAR found in extracted zip" && find /tmp/datomic-extract -type f | head -20 && exit 1; fi && \
54-
cp "${DATOMIC_POTENTIAL_JAR}" "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.jar"; \
55-
fi && \
56-
echo "[DOCKER BUILD] Verifying vendor path contents..." && \
57-
ls -lh "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/" && \
58-
rm -rf /tmp/datomic-pro-${DATOMIC_VERSION}.zip /tmp/datomic-extract && \
59-
echo "[DOCKER BUILD] ✅ Datomic Pro installed to lib/ (file:lib repository pattern)"
60-
61-
# Copy the rest of the source (exclude lib/ since we've already set it up)
62-
# Use .dockerignore or copy selectively to avoid overwriting lib/
63-
COPY . /workspace
64-
# Ensure Datomic Pro JAR is still present after COPY
65-
RUN test -f lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.jar || \
66-
(echo "[DOCKER BUILD] ⚠️ Datomic Pro JAR missing after COPY, re-downloading..." && \
67-
mkdir -p lib/com/datomic/datomic-pro/${DATOMIC_VERSION} && \
68-
curl -L -o /tmp/datomic-pro-${DATOMIC_VERSION}.zip \
69-
"https://datomic-pro-downloads.s3.amazonaws.com/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.zip" && \
70-
unzip -q /tmp/datomic-pro-${DATOMIC_VERSION}.zip -d /tmp/datomic-extract && \
71-
DATOMIC_JAR=$(find /tmp/datomic-extract -name "datomic-pro-*.jar" -type f | head -1) && \
72-
cp "${DATOMIC_JAR}" "lib/com/datomic/datomic-pro/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.jar" && \
73-
rm -rf /tmp/datomic-pro-${DATOMIC_VERSION}.zip /tmp/datomic-extract && \
74-
echo "[DOCKER BUILD] ✅ Datomic Pro JAR restored")
26+
RUN curl --fail -L -o "/tmp/datomic-pro-${DATOMIC_VERSION}.zip" \
27+
"https://datomic-pro-downloads.s3.amazonaws.com/${DATOMIC_VERSION}/datomic-pro-${DATOMIC_VERSION}.zip"
7528

7629
# Default shell to bash for VS Code terminal
7730
SHELL ["/bin/bash", "-c"]

.dockerignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,8 @@ test/*
88
*.md
99
data/*
1010
log/*
11-
backups/*
11+
backups/*
12+
backup/*
13+
14+
# Datomic Pro distribution (~280MB) — Docker images download their own from S3
15+
lib/com/datomic/

README.md

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,16 @@ For the full walkthrough (including manual setup without scripts), see **[docs/G
7373

7474
### Self-hosting (Docker)
7575

76-
For running your own production instance from pre-built images:
76+
For running your own production instance:
7777

78-
1. Clone the repository
79-
2. Copy `.env.example` to `.env` and edit the values (see [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md))
80-
3. Create SSL certificates: `./deploy/snakeoil.sh`
81-
4. Run: `docker-compose pull && docker-compose up`
82-
5. Visit `https://localhost`
78+
```bash
79+
git clone https://github.com/orcpub/orcpub.git && cd orcpub
80+
./docker-setup.sh # generates .env, SSL certs, directories
81+
docker compose up -d # pull images and start
82+
./docker-user.sh init # create admin from .env settings
83+
```
8384

84-
See the [Docker deployment section](#docker-deployment) for full details.
85+
Visit `https://localhost`. See the [Docker deployment section](#docker-deployment) for full details including migration from older versions.
8586

8687
---
8788

@@ -293,36 +294,84 @@ For self-hosting a production instance.
293294

294295
### Containers
295296

296-
The Docker setup runs three containers:
297-
298297
| Container | Purpose |
299298
|-----------|---------|
300-
| `datomic` | Datomic database transactor |
301-
| `orcpub` | JVM application server |
302-
| `web` | nginx reverse proxy with SSL |
299+
| `datomic` | Datomic Pro database transactor |
300+
| `orcpub` | JVM application server (Java 21) |
301+
| `web` | nginx reverse proxy with SSL termination |
302+
303+
### Fresh Install
304+
305+
```bash
306+
git clone https://github.com/orcpub/orcpub.git && cd orcpub
307+
308+
# Interactive setup — generates .env, SSL certs, and directories
309+
./docker-setup.sh
310+
311+
# Pull pre-built images and start
312+
docker compose up -d
313+
314+
# Create your first user (once containers are healthy)
315+
./docker-user.sh init # from .env settings
316+
./docker-user.sh create <username> <email> <password> # or directly
317+
```
318+
319+
Visit `https://localhost` when running.
320+
321+
To build from source instead of pulling images:
322+
323+
```bash
324+
docker compose -f docker-compose-build.yaml build
325+
docker compose -f docker-compose-build.yaml up -d
326+
```
327+
328+
For environment variable details, see [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md).
329+
330+
### Upgrading from Datomic Free (pre-2026)
303331

304-
### Setup
332+
If you have an existing deployment using the old Java 8 / Datomic Free stack,
333+
your `./data` directory is **not compatible** with the new Datomic Pro transactor.
334+
The storage protocols (`datomic:free://` vs `datomic:dev://`) use different formats.
305335

306-
1. Clone the repository
307-
2. Copy `.env.example` to `.env` and configure (see [docs/ENVIRONMENT.md](docs/ENVIRONMENT.md))
308-
3. Create SSL certificates:
309-
- Quick self-signed: `./deploy/snakeoil.sh` (unix) or `./deploy/snakeoil.bat` (windows)
310-
- Or use your own certificate
311-
4. Launch:
336+
**You must migrate your database before upgrading.** The migration tool handles this:
337+
338+
**Bare metal** — use `scripts/migrate-db.sh` which wraps the `bin/datomic` CLI:
312339

313340
```bash
314-
docker-compose pull # use pre-built images
315-
docker-compose up -d # start in background
341+
./scripts/migrate-db.sh backup # With old (Free) transactor running
342+
# ... stop Free transactor, move ./data aside, start Pro transactor ...
343+
./scripts/migrate-db.sh restore "datomic:dev://localhost:4334/orcpub?password=..."
344+
./scripts/migrate-db.sh verify
316345
```
317346

318-
To build from source instead:
347+
**Docker** — use `docker-migrate.sh` which runs `bin/datomic` inside containers:
319348

320349
```bash
321-
docker-compose -f docker-compose-build.yaml build
322-
docker-compose -f docker-compose-build.yaml up -d
350+
./docker-migrate.sh backup # With old stack running
351+
docker compose down
352+
docker compose -f docker-compose-build.yaml build
353+
docker compose -f docker-compose-build.yaml up -d
354+
./docker-migrate.sh restore # After new stack is healthy
355+
./docker-migrate.sh verify
323356
```
324357

325-
Visit `https://localhost` when running.
358+
Or run `./docker-migrate.sh full` for a guided migration.
359+
360+
The backup is storage-protocol-independent and writes to `./backup/`, so databases
361+
of any size (including 20GB+) are handled. See [docs/migration/datomic-data-migration.md](docs/migration/datomic-data-migration.md)
362+
for the full guide including disk space planning and troubleshooting.
363+
364+
### User Management
365+
366+
```bash
367+
./docker-user.sh create <user> <email> <password> # Create a verified user
368+
./docker-user.sh batch users.txt # Bulk create from file
369+
./docker-user.sh list # List all users
370+
./docker-user.sh check <user> # Check user status
371+
./docker-user.sh verify <user> # Verify unverified user
372+
```
373+
374+
See [docs/docker-user-management.md](docs/docker-user-management.md) for details.
326375

327376
### Importing Homebrew Content
328377

@@ -333,6 +382,15 @@ Place your `.orcbrew` file at `./deploy/homebrew/homebrew.orcbrew` — it loads
333382
- **Database**: Stored in `./data/`. Back up this directory when Datomic is stopped. Delete it to start fresh.
334383
- **Logs**: Stored in `./logs/`. Safe to clean up; does not affect character data. Set up log rotation for production.
335384

385+
### Scripts Reference
386+
387+
| Script | Purpose |
388+
|--------|---------|
389+
| `scripts/migrate-db.sh` | Migrate data from Datomic Free to Pro (bare metal) |
390+
| `docker-migrate.sh` | Migrate data from Datomic Free to Pro (Docker) |
391+
| `docker-setup.sh` | Generate `.env`, SSL certs, and directories |
392+
| `docker-user.sh` | Create, verify, and list users in the database |
393+
336394
---
337395

338396
## Architecture

0 commit comments

Comments
 (0)