Skip to content

About

Repository to orchestrate the Beyou backend, frontend and postgres database for local development or production-like run

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Beyou logo

Beyou — Dev Environment

Docker Compose orchestration for the whole Beyou stack.
One command brings up Postgres, the Spring Boot API, and the web client — plus an optional observability overlay.

Docker Compose PostgreSQL Prometheus Grafana Loki GlitchTip


Beyou is a gamified personal-productivity app — habits, goals, routines, tasks, and categories, with XP and streaks on top. It lives across several repositories. This one contains no application code. It is the Compose layer that assembles the others into something you can actually run on your own machine: the dev stack with hot reload, an isolated stack for the Playwright suite, and an optional local observability overlay.

Production does not run from this repository. It runs on a single-node k3s cluster managed by Flux from be-infra — see Production.

Highlights

  • Composable overlays, not three separate stacks — a base file defines Postgres and the shared network; the dev and monitoring overlays layer on top of it, and e2e is a self-contained stack with its own project name. The monitoring overlay is a local copy of the production observability stack (Prometheus, Loki + Alloy, Grafana, GlitchTip), not the same deployment — production's lives in be-infra as Kubernetes manifests.
  • Hot reload in dev — the backend and frontend source trees are bind-mounted; build artefacts (target/, node_modules/, the Maven repo) live in named volumes so host and container tooling never fight over the same directory.
  • Three observability questions, three answers — Prometheus for how is it performing, Loki for what happened, GlitchTip for what broke. All three surface in one Grafana.
  • Loopback by default — every administrative surface (Grafana, Prometheus, GlitchTip, Alloy, the actuator) publishes to 127.0.0.1 only. Reach them through a tunnel or reverse proxy, not by widening the binding.

Architecture

flowchart LR
  subgraph app["beyou_net — application stack"]
    fe["frontend<br/>Vite (dev)"]
    be["backend<br/>Spring Boot"]
    db[("postgres 15")]
    fe --> be --> db
  end

  subgraph obs["monitoring overlay (optional)"]
    prom["Prometheus"]
    loki["Loki"]
    alloy["Alloy"]
    gt["GlitchTip"]
    graf["Grafana"]
    prom --> graf
    loki --> graf
    alloy -- push --> loki
  end

  be -- "/actuator/prometheus" --> prom
  alloy -. "Docker API<br/>(all beyou* containers)" .-> app
  fe -- "Sentry SDK" --> gt
  be -- "Sentry SDK" --> gt
  gt -- "uptime + heartbeat" --> be

  subgraph gtnet["glitchtip_net — isolated"]
    gtdb[("postgres 18")]
    valkey[("valkey")]
  end
  gt --> gtdb
  gt --> valkey
Loading

GlitchTip's web container is deliberately dual-homed: it needs beyou_net to poll the backend's management port, but its own datastores stay off the application network.

Prerequisites

  • Docker Engine or Docker Desktop with the docker compose v2 plugin
  • Git
  • openssl (for generating secrets), only if you run the monitoring overlay

Getting started

1. Clone the repositories side by side

The dev overlay builds the backend and frontend from sibling directories, so the layout matters.

git clone https://github.com/AndDev741/Beyou-dev-env.git
git clone https://github.com/AndDev741/Beyou-backend-spring.git
git clone https://github.com/AndDev741/Beyou-Frontend.git
your-workspace/
├── Beyou-dev-env/          # you are here
├── Beyou-backend-spring/   # built by docker-compose.dev.yml
└── Beyou-Frontend/         # built by docker-compose.dev.yml

Important

Keep the checkout directory name starting with beyou. Compose derives the project name from it, and the log collector only tails containers whose project name matches (?i)beyou.* — rename the directory and logs silently stop flowing.

2. Configure the environment

cd Beyou-dev-env
cp .env.example .env

.env is gitignored. Every variable is documented inline in .env.example; the ones without a working default:

Variable Needed when Notes
TOKEN_SECRET always JWT signing key, 32+ characters
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET Google sign-in leave empty to disable
MAIL_* verification & reset e-mail SMTP credentials for the backend
GRAFANA_ADMIN_PASSWORD --monitoring no default — Grafana refuses to start without it
GLITCHTIP_SECRET_KEY --monitoring no default — openssl rand -hex 32
GLITCHTIP_DB_PASSWORD --monitoring no default, required on both ends of the connection

Warning

The Postgres defaults (postgres / 1516) are local-development conveniences. Change them, along with TOKEN_SECRET and DOCS_IMPORT_SECRET, before this stack is reachable by anything but your own machine.

3. Start it

./scripts/up-dev.sh

Then open http://localhost:3000. The API answers on http://localhost:8099/api/v1.

First boot compiles the backend and installs frontend dependencies into named volumes — expect a few minutes. Subsequent starts reuse both.

Commands

Command What it does
./scripts/up-dev.sh Build and run the dev stack in the foreground, with hot reload
./scripts/down.sh dev Stop the dev stack and remove orphans
./scripts/reset-db.sh Tear down the dev stack and delete the Postgres volume
./scripts/bootstrap-glitchtip.sh Create GlitchTip's org, projects, monitors, and alert rules

Add --monitoring to up-dev.sh or down.sh to include the observability overlay:

./scripts/up-dev.sh --monitoring
./scripts/down.sh dev --monitoring

Note

reset-db.sh deletes data irreversibly and fails loudly if it cannot find the volume, rather than printing "complete" after removing nothing. If your project name differs from the directory name, set COMPOSE_PROJECT_NAME so it looks in the right place.

Stacks

Dev — docker-compose.yml + docker-compose.dev.yml

Backend and frontend are built from the sibling checkouts at the dev stage of their Dockerfiles and run against bind-mounted source. Container build output is kept in named volumes (beyou_backend_target, beyou_maven_repo, beyou_frontend_node_modules) so a host-side ./mvnw or npm run dev cannot corrupt the container's artefacts, or leave root-owned files behind.

The backend is capped at 2 CPUs / 1 GB with MaxRAMPercentage=70.

E2E — docker-compose.e2e.yml

A self-contained stack under its own Compose project name (beyou-e2e) and its own network, so it can never collide with a running dev stack. It uses the beyou_e2e database and SPRING_PROFILES_ACTIVE=e2e — the backend's E2eSafetyCheck refuses to start against the dev database.

Build the images first, then bring it up:

docker compose -f docker-compose.e2e.yml up -d --wait

The Playwright specs live in Beyou-e2e-tests.

Production

Production is not a Compose stack. It runs on a single-node k3s cluster, reconciled by Flux from be-infra:

Path in be-infra What lives there
apps/beyou web, docs and backend Deployments, plus the backup CronJobs
apps/glitchtip the production GlitchTip
data/ the shared CloudNativePG Postgres cluster
platform/monitoring kube-prometheus-stack, Loki, Alloy and Grafana, with e-mail alerting

Deploys are Flux image automation: CI pushes ghcr.io/anddev741/beyou-*:latest, and Flux picks up the new image and rolls it out. Nothing in this repository is involved, so a change here never reaches production.

Ports

Service Host port Binding Notes
Frontend 3000 all interfaces Vite dev server
Backend 8099 all interfaces API under /api/v1
Postgres 5490 loopback container port 5432
Backend management 9091 loopback, --monitoring only /actuator/*, unversioned
Grafana 3001 loopback login required
Prometheus 9090 loopback query API is unauthenticated
GlitchTip 8000 loopback see the first-run warning below
Alloy debug UI 12345 loopback pipeline health, exposes /-/reload
Loki — none, deliberately unauthenticated API; query it through Grafana
cAdvisor / node-exporter / postgres-exporter — none, deliberately scraped over beyou_net only; ports overridable via CADVISOR_PORT / NODE_EXPORTER_PORT / POSTGRES_EXPORTER_PORT

MONITORING_BIND and GLITCHTIP_BIND override the loopback default. Only do that if you know what you are exposing and have something authenticating in front of it.

Observability

docker-compose.monitoring.yml is an optional overlay carrying Prometheus, Grafana, Loki + Alloy, and GlitchTip. The division of labour:

Question Component Retention
How is it performing? Prometheus → Grafana in-memory/TSDB defaults
What are the containers doing? Prometheus (cAdvisor + node-exporter + postgres-exporter) → Grafana in-memory/TSDB defaults
What happened? Loki (fed by Alloy) 30 days
What broke? GlitchTip (Sentry-compatible) GLITCHTIP_RETENTION_DAYS, 30

Four dashboards are provisioned into Grafana automatically: Beyou — Containers (fleet health: every container's resources, scrape targets, the host, the app DB and log/error volume), Beyou — Service Health (consolidated) (backend JVM internals), Beyou — AI Agent, and Beyou Logs.

Logs (Loki + Alloy)

Zero application configuration: anything a container writes to stdout is collected. Alloy tails every container in the Beyou Compose projects through the Docker API and pushes to Loki. That covers the Spring backend, the frontend, Postgres, and the monitoring services themselves — and the e2e stack too, when it runs.

Start in Grafana → Dashboards → Beyou Logs (volume and error charts, plus a filterable browser), or query ad-hoc in Explore:

{service="backend"}                                  # everything the backend printed
{service="backend"} | detected_level="error"         # errors only
{service=~"backend|frontend"} |~ "(?i)nullpointer"   # regex across services
{project="beyou-e2e"}                                # the e2e stack, when it runs

detected_level is attached server-side by Loki, which parses JSON, logfmt, and plain-text keywords — neither the apps nor Alloy do any log parsing.

Behaviour worth knowing before you trust it
  • Scope — Alloy keeps only containers whose Compose project name starts with beyou (case-insensitive). This host runs unrelated stacks, and their logs do not belong in a Loki that anyone with Grafana access can query. Deploy from a directory not starting with beyou and logs silently stop; fix the directory name or the keep rule in monitoring/alloy/config.alloy.
  • Retention — 30 days, enforced by Loki's compactor (monitoring/loki/loki.yml). History lives in the loki_data volume; docker logs on the host only holds the rotated tail (10 MB × 3 files per container, set in every compose file).
  • Exposure — Loki has no host port. Its push and query APIs are unauthenticated, so its only clients are Alloy and Grafana over beyou_net, and the read path goes through the component that has a login.
  • Own liveness — Prometheus scrapes both (up{job="loki"}, up{job="alloy"}), because a dead log pipeline fails silent: ingestion just stops. Alloy buffers and retries while Loki is down, but the buffer is finite — loki_write_dropped_entries_total on the alloy job is the "logs were actually lost" signal.
  • Not captured — logs from real users' browsers. That is GlitchTip's job. Do not close the gap by exposing a Loki push endpoint to browsers; an unauthenticated ingest path open to the internet is an abuse surface.

Container & host metrics

Three exporters in the monitoring overlay feed the Beyou — Containers dashboard. None publishes a host port: their only clients are Prometheus and Grafana over beyou_net, same as Loki.

Exporter What it measures Job
cAdvisor (ghcr.io/google/cadvisor) Per-container CPU, memory, network, disk, uptime, labeled by Compose service/project cadvisor
node-exporter (prom/node-exporter) The host: CPU, load, memory, root disk, network node-exporter
postgres-exporter (prometheuscommunity/postgres-exporter) The app DB from the DB's own side: connections, cache hit ratio, deadlocks, locks, size (pg_up is the "DB answering" signal) postgres-exporter

Container ports are CADVISOR_PORT / NODE_EXPORTER_PORT / POSTGRES_EXPORTER_PORT (defaults 8080/9100/9187); the config template reads the same variables (monitoring/prometheus/prometheus.yml.tpl), so mapping them differently changes one line in .env. Grafana also exposes its own /metrics (GF_METRICS_ENABLED, job grafana).

The dashboard scopes cAdvisor data to Compose projects whose name starts with beyou — this host runs unrelated stacks, and their containers do not belong on the fleet board. Same rule as the Alloy log filter.

Error telemetry (GlitchTip)

GlitchTip speaks the Sentry API, so the official Sentry SDKs in the backend, web, and mobile clients point at it by DSN. It also owns the uptime and heartbeat monitors, because it is the component that can notify a human.

Everything in this section is about the local GlitchTip in the monitoring overlay. Production's GlitchTip (mnt.beyouweb.com) runs in be-infra (apps/glitchtip), and its monitors point at the cluster's Services, not at the container names used here.

Caution

GlitchTip lets the first account self-register as admin regardless of ENABLE_USER_REGISTRATION. Between up and the moment you register, whoever can reach port 8000 owns the collector — every error event and every uploaded source map. That is why the port is loopback-bound, and why you should register immediately.

First run

There is one supported path: register the admin account in the UI, then run the bootstrap script.

  1. Set GLITCHTIP_SECRET_KEY (openssl rand -hex 32) and the rest of the GLITCHTIP_* block in .env. The container will not boot without the key.

  2. Start with --monitoring. First boot runs migrations and takes a minute or two.

  3. Open http://localhost:8000, click Register, and create the account. This is the one step the script deliberately does not do — registration sets a password, which a bootstrap script has no business holding. With GLITCHTIP_ENABLE_USER_REGISTRATION=False (the default), self-signup closes as soon as it exists.

  4. Run the script:

    ./scripts/bootstrap-glitchtip.sh

    It creates the organization and team, one project per reporting surface (beyou-backend, beyou-web, beyou-mobile) plus an infrastructure project (beyou-infra) that hosts the container monitors, one uptime monitor per Beyou container plus the two public pages, the snapshot heartbeat, and one alert rule per project with an e-mail recipient wired to it. It then prints the DSNs, the heartbeat check-in URL, and which address alerts will actually reach.

  5. Paste the printed DSNs into the corresponding app env vars, and SNAPSHOT_HEARTBEAT_URL (plus NUDGE_HEARTBEAT_URL, when the nudge monitor was created) into this repo's .env.

The script reads the GLITCHTIP_*_TARGET variables (one per uptime monitor; defaults match the compose stack's CONTAINER addresses) plus GLITCHTIP_ALERT_EMAIL, and overwrites them in the collector on every run, so a wrong value here beats a right value in the UI. Full list in .env.example; the ones you are most likely to touch:

GLITCHTIP_FRONTEND_TARGET=frontend:3000   # the dev stack's Vite port, also the script's default
GLITCHTIP_ALERT_EMAIL=ops@example.com     # empty = the account you registered in step 3

Tip

Re-running is safe, and not a no-op: creation is get_or_create, but every run re-applies the script's own values over whatever is in the database, so drift is repaired rather than reported as "already present". It prints reconciled … for anything it corrected, and never creates duplicates.

Do not create the organization, projects, or alert rules by hand as well. That is how you end up with DSNs pointing at one project and alert rules attached to another, so events arrive somewhere nothing is watching.

Alerts: making one actually arrive

Storing errors and turning a monitor red announces nothing. Two GlitchTip code paths do the announcing, and both go silent unless an AlertRecipient row exists:

Path Trigger Requires
Errors apps.alerts.tasks.process_event_alerts, every 60s a rule with quantity and timespan_minutes
Uptime + heartbeat apps.uptime.tasks.send_monitor_notification, on state change a rule on the monitor's project with uptime = True

The bootstrap script creates one rule per project covering both paths — one and not two on purpose, because the uptime lookup joins through the project, so a second uptime = True rule mails every monitor event twice.

The channel is e-mail over the same SMTP the backend already uses: nothing new to provision, and that account is known to deliver. Compose GLITCHTIP_EMAIL_URL from the same MAIL_* credentials — .env.example documents the exact scheme, the STARTTLS-vs-implicit-TLS choice, and the four encoding traps that silently break it.

consolemail:// stays the default so a dev machine does not start mailing. It is not a stub — the message is fully composed and printed:

docker logs -f beyou-dev-env-glitchtip-1   # look for "Subject: Error in ..."

Important

The recipient is not the address on the rule. GlitchTip ignores that field for e-mail and resolves every user on the team that owns the project. That is why GLITCHTIP_ALERT_EMAIL is applied by the script rather than by Compose — it has to make the address a user, add it to the organization, and add it to the team. The account is created with an unusable password: a mailbox, not a login.

Two consequences: it is additive (the account from step 3 keeps receiving alerts — remove it from the team or set its per-project alerts to Off to stop that), and a per-project Off beats everything the script does. The script will not overwrite a human's opt-out, but it prints a WARNING naming the user and projects, because otherwise the rule looks wired and mails nobody.

Reference record — the alert rule, by hand

Under Settings → Projects → <project> → Alerts, for each of the four projects:

Field Value
Name New issue
Send notification when 1 event in 1 minute
Also alert on uptime check failures yes
Recipient Email (no URL — see above)

Names must match scripts/bootstrap-glitchtip.py exactly; the script keys rules on (project, name) and will otherwise create a second one alongside yours.

Monitors

One monitor per Beyou container, plus the heartbeat, all created by the bootstrap script — none by Compose. GlitchTip monitors live in its database, so a retention wipe, a volume reset, or a move to a new host means re-running the script. App monitors sit on the app projects; the container monitors sit on beyou-infra, which has its own alert rule — one rule per project, so a monitor event is never mailed twice.

# Monitor Type Question it answers
1 Beyou backend health GET http://backend:9091/actuator/health/uptime Is the process answering?
2 Snapshot scheduler heartbeat Heartbeat, 5400s Is the scheduled job still running?
2b Engagement nudge heartbeat Heartbeat, 5400s Is the nudge pass still running? Opt-in: set GLITCHTIP_NUDGE_HEARTBEAT=1 and re-run the bootstrap in the same change that sets ENGAGEMENT_NUDGES_ENABLED=true. The pass returns before checking in while the flag is off, so a monitor created earlier pages every 90 minutes about a job that is off on purpose
3 Beyou web frontend TCP frontend:3000 Is the app being served at all?
4 Beyou postgres (app DB) TCP db:5432 Is the database accepting connections?
5 Beyou glitchtip postgres TCP glitchtip-db:5432 Is the collector's DB answering?
6 Beyou glitchtip valkey TCP glitchtip-valkey:6379 Is the cache accepting connections?
7 Beyou loki GET http://loki:3100/ready Is the log store ready?
8 Beyou alloy GET http://alloy:12345/-/healthy Is the whole log pipeline healthy? (500 = any component unhealthy)
9 Beyou prometheus GET http://prometheus:9090/-/healthy Is the metrics store answering?
10 Beyou grafana GET http://grafana:3000/api/health Is Grafana's own DB healthy?
11 Beyou glitchtip (self) GET http://glitchtip:8000/_health/ Is the collector answering? (for the Uptime page, not alerts)

All infra monitors use the same tuning as the backend one: 60s interval, 10s timeout, confirmation threshold 2 (two consecutive failures before alerting — one dropped poll during a restart is not an outage). The TCP monitors need no HTTP endpoint and carry the port inside the URL field, exactly like the frontend monitor.

Monitor 2 is the interesting one. The health endpoint keeps returning 200 while RoutineSnapshotScheduler quietly stops writing daily snapshots — nothing fails, data just stops appearing. So the check is inverted: the backend checks in after every completed hourly cycle, and GlitchTip alerts on the check-in not arriving.

Reference record — full monitor settings and rationale

The names must match scripts/bootstrap-glitchtip.py exactly. The script keys every monitor on its name via get_or_create. Create one by hand under a different name and you get two monitors polling the same thing — and the hand-made one has none of the confirmation_threshold tuning, so it alerts on a single dropped poll.

1. Backend uptime

Field Value
Name Beyou backend health
Project beyou-backend
Monitor type GET
URL http://backend:9091/actuator/health/uptime
Expected status 200
Interval / timeout 60 / 10 seconds
Confirmation threshold 2 — one dropped poll during a restart is not an outage

The path is the uptime health group, not the bare /actuator/health. The bare endpoint aggregates every indicator Boot registers, and an indicator is free to make a network call: the mail one used to open a live authenticated SMTP session to Gmail on every poll, which cost ~550ms against ~4ms for a group — with no ceiling, because JavaMail's default timeout is infinite. That put a third party's latency in front of the 10s timeout above, and a slow Gmail read as a dead backend. The group is an allowlist (db,diskSpace,ping) defined in the backend's application.yaml; keep the two in step, because a renamed group leaves this monitor probing a 404. Not Boot's own readiness group: that one contains only readinessState, which is UP the moment the app has started and would not notice a dead database.

Use the in-network URL, not localhost: inside the GlitchTip container localhost is GlitchTip. The management server binds 127.0.0.1 by default; this stack sets MANAGEMENT_ADDRESS=0.0.0.0 so the container's port is reachable within beyou_net, and the overlay publishes it only to the Docker host. GLITCHTIP_UPTIME_ALLOW_PRIVATE_IPS=True is already set — without it the SSRF guard rejects RFC1918 targets and the monitor cannot be saved.

2. Snapshot job heartbeat

Field Value
Name Snapshot scheduler heartbeat
Project beyou-backend
Monitor type Heartbeat
Expected interval 5400 seconds (90 min)
Confirmation threshold 1 — the interval already carries 30 minutes of slack

The job runs hourly (@Scheduled(cron = "0 0 * * * *")) and checks in after every completed cycle, not only the midnight ones, so a stalled job is caught within the hour instead of within a day. Saving the monitor produces a check-in URL; put it in .env as SNAPSHOT_HEARTBEAT_URL (using the in-network host glitchtip:8000) and restart the backend. Leaving it empty disables the heartbeat entirely.

  • A run that throws sends nothing, so a broken job shows as a missing heartbeat rather than a green light.
  • A failed check-in never fails the snapshot job — it is logged at WARN and the cycle carries on. Monitoring must not become the cause of the outage it watches.
  • Startup backfill does not check in; otherwise a crash-restart loop would keep the monitor green forever.
  • The test and e2e profiles pin the URL empty.

3. Web frontend

Field Value
Name Beyou web frontend
Project beyou-web
Monitor type TCP Port
URL frontend:3000
Interval / timeout 60 / 10 seconds
Confirmation threshold 2

A healthy API behind a frontend that stopped being served is still a total outage, and the two monitors above would not notice. TCP Port monitors carry the port inside the URL field — GlitchTip splits on : and hands both halves to asyncio.open_connection. There is no separate port input, and Expected status is ignored.

Getting the port wrong is worse than having no monitor: it leaves a permanently red light nobody believes. The script defaults to the dev stack's frontend:3000; override GLITCHTIP_FRONTEND_TARGET only if you serve the frontend some other way. This is a TCP connect, not an HTTP fetch — it proves something is accepting connections, not that the app renders.

Watching the collector itself

Every alarm above is raised by GlitchTip. So GlitchTip cannot be what tells you GlitchTip is down: when it wedges, every signal goes quiet at once and the stack looks calm. Two mechanisms cover that:

  • Compose healthcheck on the glitchtip service, running the image's own /code/healthcheck.py. docker ps then reports unhealthy instead of a misleading Up. Allow up to the 120s start_period on first boot.
  • Prometheus scrape of glitchtip:8000/metrics as job glitchtip (django-prometheus, switched on by ENABLE_OBSERVABILITY_API). up{job="glitchtip"} is a liveness signal owned by the one component that is not the collector.

Warning

Both are still look-at-it signals. Everything GlitchTip watches announces itself by e-mail; collector death does not. Prometheus scrapes up{job="glitchtip"} and nothing evaluates it, and the healthcheck only changes what docker ps prints.

The gap is deliberate. Closing it properly means either an Alertmanager (alerting: + rule_files: in monitoring/prometheus/prometheus.yml.tpl, with up{job="glitchtip"} == 0 as the first rule) or Grafana alerting — a second notification system to own, consciously not introduced alongside the first. Until then, treat "GlitchTip has gone quiet" as a thing to check, not a thing to trust.

Backups

Production backups are not done from this repository. They are in-cluster CronJobs in be-infra (apps/beyou/backup.yaml): a nightly pg_dump plus the uploads, shipped to an encrypted restic repository on Cloudflare R2, a weekly restore drill into a throwaway Postgres, and heartbeats to production's GlitchTip so a job that silently stops is noticed.

The local dev database is not backed up at all. Treat it as disposable — that is what reset-db.sh is for.

Troubleshooting

Symptom Likely cause
Grafana container exits immediately GRAFANA_ADMIN_PASSWORD is unset — it has no default, on purpose
GlitchTip container exits immediately GLITCHTIP_SECRET_KEY or GLITCHTIP_DB_PASSWORD is unset
GlitchTip unhealthy for the first minute or two Normal — migrations run before it starts serving
No logs in Grafana Checkout directory name does not start with beyou; check the keep rule in monitoring/alloy/config.alloy
Frontend monitor permanently red GLITCHTIP_FRONTEND_TARGET does not match the frontend container's port (3000 in dev)
Alerts never arrive No AlertRecipient row, or a per-project Off — re-run the bootstrap script and read its WARNING lines
SMTP works elsewhere but not for GlitchTip Quoted value, unencoded @ in the username, or an undoubled $ — see the notes in .env.example
reset-db.sh says the volume was not found Project name differs from the directory name; set COMPOSE_PROJECT_NAME
Backend cannot reach Postgres in dev Do not re-declare the db port in docker-compose.dev.yml — the base file publishes it

Related repositories

Repository Contents
Beyou-backend-spring Spring Boot API — domain model, gamification, auth, AI
Beyou-Frontend Turborepo monorepo — React web app, Expo mobile app, shared packages
Beyou-e2e-tests Playwright suite driving the full stack
Beyou-arch-design OpenAPI specs and bilingual architecture docs
Beyou-docs-ui Viewer app for the architecture and design documentation

About

Repository to orchestrate the Beyou backend, frontend and postgres database for local development or production-like run

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages