mirror of https://github.com/ghostfolio/ghostfolio
Browse Source
- .devcontainer/devcontainer.json: Node 22 base image with Docker-in-Docker feature so the upstream docker/docker-compose.dev.yml can bring up Postgres + Redis inside the Ona VM. - .devcontainer/post-create.sh: idempotent setup that seeds .env from .env.dev, fills the <INSERT_*> placeholders with safe dev defaults + random strings, prepulls images, runs npm ci. - .ona/automations.yaml: three services (postgres-redis, api, client) plus manual 'seed' and 'dry-run-demo' tasks. First boot runs npm run database:setup and marks .ona/.db-initialized so subsequent restarts skip re-seeding. - .ona/README.md: explainer of the changes and how to bring the env up. - .gitignore: ignore the .db-initialized marker.pull/6760/head
5 changed files with 182 additions and 0 deletions
@ -0,0 +1,30 @@ |
|||
{ |
|||
"name": "Ghostfolio (Ona demo)", |
|||
"image": "mcr.microsoft.com/devcontainers/javascript-node:1-22", |
|||
"features": { |
|||
"ghcr.io/devcontainers/features/docker-in-docker:2": { |
|||
"moby": false, |
|||
"dockerDashComposeVersion": "v2" |
|||
}, |
|||
"ghcr.io/devcontainers/features/git:1": {} |
|||
}, |
|||
"forwardPorts": [3333, 4200, 5432, 6379], |
|||
"portsAttributes": { |
|||
"3333": { "label": "Ghostfolio API" }, |
|||
"4200": { "label": "Ghostfolio Client" }, |
|||
"5432": { "label": "PostgreSQL" }, |
|||
"6379": { "label": "Redis" } |
|||
}, |
|||
"postCreateCommand": "bash .devcontainer/post-create.sh", |
|||
"remoteUser": "node", |
|||
"customizations": { |
|||
"vscode": { |
|||
"extensions": [ |
|||
"dbaeumer.vscode-eslint", |
|||
"esbenp.prettier-vscode", |
|||
"Prisma.prisma", |
|||
"nrwl.angular-console" |
|||
] |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
#!/usr/bin/env bash |
|||
# One-shot setup for the Ghostfolio dev container inside Ona. |
|||
# Idempotent: safe to re-run. |
|||
|
|||
set -euo pipefail |
|||
|
|||
cd "$(dirname "$0")/.." |
|||
|
|||
echo "==> Seeding .env from .env.dev (if missing)" |
|||
if [ ! -f .env ]; then |
|||
cp .env.dev .env |
|||
# Fill in safe dev defaults — the upstream .env.dev has <INSERT_...> placeholders. |
|||
sed -i 's|<INSERT_REDIS_PASSWORD>|devredispassword|g' .env |
|||
sed -i 's|<INSERT_POSTGRES_PASSWORD>|devpostgrespassword|g' .env |
|||
sed -i 's|<INSERT_RANDOM_STRING>|'"$(openssl rand -hex 32)"'|g' .env |
|||
fi |
|||
|
|||
echo "==> Pre-pulling Postgres + Redis images (cached into prebuild)" |
|||
docker pull postgres:15 >/dev/null 2>&1 || true |
|||
docker pull redis:7 >/dev/null 2>&1 || true |
|||
|
|||
echo "==> Installing npm dependencies" |
|||
npm ci --no-audit --no-fund |
|||
|
|||
echo "==> Done. Services will be brought up by Ona automations." |
|||
@ -0,0 +1,47 @@ |
|||
# Ona demo setup — Ghostfolio fork |
|||
|
|||
This fork is the target codebase for the **Apr 23 BlackRock deep-dive** demo. |
|||
|
|||
## What this folder contains |
|||
|
|||
- [`automations.yaml`](automations.yaml) — Ona services for Postgres, Redis, the |
|||
NestJS API, and the Angular client, plus manual `seed` and `dry-run-demo` tasks. |
|||
|
|||
## What changed vs upstream |
|||
|
|||
1. **`.devcontainer/devcontainer.json`** — new. Node 22 base image, Docker-in-Docker |
|||
feature enabled (needed so `docker compose -f docker/docker-compose.dev.yml up` |
|||
works for Postgres + Redis), ports forwarded, `postCreateCommand` wires up |
|||
`.env` and npm install. |
|||
|
|||
2. **`.devcontainer/post-create.sh`** — new. Seeds `.env` from `.env.dev`, |
|||
replaces the `<INSERT_*>` placeholders with safe dev defaults, prepulls |
|||
`postgres:15` / `redis:7` images, runs `npm ci`. Idempotent. |
|||
|
|||
3. **`.ona/automations.yaml`** — new. Starts the stack on |
|||
`postDevcontainerStart` / `postEnvironmentStart`. First boot runs |
|||
`npm run database:setup` (schema + seed), marks it with |
|||
`.ona/.db-initialized` so subsequent restarts skip re-seeding. |
|||
|
|||
## How to bring it up |
|||
|
|||
1. Open this repo in Ona. |
|||
2. Wait for the devcontainer build (DinD is heavy first time; subsequent opens |
|||
use the prebuild cache). |
|||
3. `gitpod automations service list` — all three services should go `ready`. |
|||
4. Open the forwarded port `4200` → Ghostfolio UI. First user created gets |
|||
`ADMIN`. |
|||
|
|||
## Reset before a demo |
|||
|
|||
``` |
|||
gitpod automations task start seed |
|||
``` |
|||
|
|||
## Notes for the demo day |
|||
|
|||
- Keep `5432` + `6379` forwarded but unadvertised. Port `4200` is the only UI. |
|||
- The `.env` generated by post-create uses throwaway dev passwords. DO NOT |
|||
commit a real `.env`. |
|||
- If DinD is slow to come up on first boot, `gitpod automations service logs postgres-redis` |
|||
tails the compose output. |
|||
@ -0,0 +1,77 @@ |
|||
# Ona automations for the Ghostfolio demo environment. |
|||
# |
|||
# Shape of the world when services are up: |
|||
# postgres (5432) + redis (6379) via docker compose on the host |
|||
# api (3333) via `npm run start:server` |
|||
# client (4200) via `npm run start:client` |
|||
# |
|||
# This is the "dev env == preprod test env" demo: the full Ghostfolio stack |
|||
# compiles, runs, and serves requests inside the same Ona VM that the |
|||
# agent (Claude Code / Cursor / Codex / Ona) operates in. |
|||
|
|||
services: |
|||
postgres-redis: |
|||
name: PostgreSQL + Redis |
|||
description: Backing stores for Ghostfolio. Uses the upstream dev compose file. |
|||
triggeredBy: |
|||
- postDevcontainerStart |
|||
- postEnvironmentStart |
|||
commands: |
|||
start: docker compose -f docker/docker-compose.dev.yml up |
|||
ready: | |
|||
docker exec gf-postgres-dev pg_isready -U user -d ghostfolio-db && \ |
|||
docker exec gf-redis-dev redis-cli --pass "$(grep ^REDIS_PASSWORD .env | cut -d= -f2)" ping | grep -q PONG |
|||
stop: docker compose -f docker/docker-compose.dev.yml down |
|||
|
|||
api: |
|||
name: Ghostfolio API |
|||
description: NestJS backend, hot-reload, port 3333. |
|||
triggeredBy: |
|||
- postDevcontainerStart |
|||
- postEnvironmentStart |
|||
commands: |
|||
start: | |
|||
# Wait for DB to be ready, then sync schema + seed on first run. |
|||
until docker exec gf-postgres-dev pg_isready -U user -d ghostfolio-db >/dev/null 2>&1; do sleep 1; done |
|||
if [ ! -f .ona/.db-initialized ]; then |
|||
npm run database:setup |
|||
touch .ona/.db-initialized |
|||
fi |
|||
npm run start:server |
|||
ready: curl -sf http://localhost:3333/api/v1/health |
|||
|
|||
client: |
|||
name: Ghostfolio Client |
|||
description: Angular frontend, hot-reload, port 4200. |
|||
triggeredBy: |
|||
- postDevcontainerStart |
|||
- postEnvironmentStart |
|||
commands: |
|||
start: npm run start:client |
|||
ready: curl -skf https://localhost:4200/en || curl -sf http://localhost:4200/en |
|||
|
|||
tasks: |
|||
seed: |
|||
name: Reset + seed demo data |
|||
description: Wipe the DB and reseed. Use before a demo run. |
|||
triggeredBy: |
|||
- manual |
|||
command: | |
|||
rm -f .ona/.db-initialized |
|||
docker compose -f docker/docker-compose.dev.yml down -v |
|||
docker compose -f docker/docker-compose.dev.yml up -d |
|||
until docker exec gf-postgres-dev pg_isready -U user -d ghostfolio-db >/dev/null 2>&1; do sleep 1; done |
|||
npm run database:setup |
|||
touch .ona/.db-initialized |
|||
echo "✅ Ghostfolio DB reset + seeded." |
|||
|
|||
dry-run-demo: |
|||
name: "Dry-run: local agent beat" |
|||
description: Sanity check that Claude Code + Ona agent can reach the API and run a test. |
|||
triggeredBy: |
|||
- manual |
|||
command: | |
|||
set -e |
|||
curl -sf http://localhost:3333/api/v1/health | jq . |
|||
npx nx test api --watch=false --passWithNoTests | tail -20 |
|||
echo "✅ Local agent beat ready." |
|||
Loading…
Reference in new issue