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