635a130f0b
Build and Push Docker Images / detect-changes (push) Successful in 11s
Build and Push Docker Images / build-auth-api (push) Successful in 1m0s
Build and Push Docker Images / build-employee-api (push) Successful in 1m2s
Build and Push Docker Images / build-transit-api (push) Successful in 1m1s
Build and Push Docker Images / build-error-log-api (push) Successful in 1m5s
Build and Push Docker Images / build-admin-ui (push) Successful in 1m13s
Build and Push Docker Images / build-monitoring-ui (push) Successful in 1m15s
Build and Push Docker Images / deploy-test-node (push) Successful in 3s
### Summary of Changes
1. Documentation Consolidation:
• Relocated the docs/ folder and all repository .md files (README.md, DEPLOYMENT.md, DOCKER_README.md,
DOMAINS_README.md, GETTING_STARTED.md, CI_CD_PORTAINER_GUIDE.md, ADMIN_DEPLOYMENT_SUMMARY.md,
SECURITY_PRIVATE_FILES.md, handoff.md, azure-project-plan.md, plus service-specific READMEs) into .
• Updated document links in README.md.
2. AI Agent Project Map:
• Created PROJECT_MAP.md in the project root containing complete architecture diagrams, service specs, ports, DB
schemas, environment variables, and developer workflows.
• Added PROJECT_MAP.md to .gitignore.
3. Monitoring UI & Infrastructure Integration:
• Added monitoring_ui service to docker-compose.yml (port 5175).
• Configured Gitea workflow docker-build.yml for monitoring_ui builds.
• Added CORS middleware headers in index.js.
• Added nginx.conf copy step in Dockerfile.
──────
### Recommended Commit Message
docs: consolidate project documentation into monitoring_ui and add agent project map
- Move all markdown documentation files and docs/ folder into monitoring_ui/docs/
- Update documentation hub index (monitoring_ui/docs/README.md) with relative paths
- Generate comprehensive AI agent reference map (PROJECT_MAP.md) in repository root
- Add PROJECT_MAP.md and monitoring_ui build output/env overrides to .gitignore
- Integrate monitoring_ui service into docker-compose.yml and Gitea CI workflow
- Configure CORS handling in employee_api for monitoring dashboard access
──────
### Alternative Short Commit Message
refactor(docs): move docs to monitoring_ui and create AI agent PROJECT_MAP.md
129 lines
6.4 KiB
Markdown
129 lines
6.4 KiB
Markdown
<!-- azure-cor-disclaimer -->
|
|
> **Important:** This skill provides guidance and recommended instructions to assist the AI system. Outputs are not guaranteed to be complete, correct, secure, or applicable to every scenario. Results should be reviewed and validated by a human before being applied. The AI model may choose not to follow all instructions exactly, and additional verification may be required.
|
|
|
|
# PostgreSQL
|
|
|
|
> PostgreSQL has no Azure-provided emulator. Use the standard `postgres` Docker image for local development. If the project targets **Azure Cosmos DB for PostgreSQL**, note in the plan that no local emulator is available.
|
|
|
|
## Docker Image
|
|
|
|
```
|
|
postgres:16
|
|
```
|
|
|
|
## docker-compose Service Block
|
|
|
|
Declare the local credentials **once** in a workspace-root `.env`, then reference them everywhere
|
|
else. Compose interpolates `${...}` from `.env` (or the shell environment), so the same values feed
|
|
the database service and every application service.
|
|
|
|
`.env` is required — without it Compose interpolates `${POSTGRES_USER}` to an empty string and the
|
|
database silently fails to authenticate:
|
|
|
|
```
|
|
POSTGRES_USER=postgres
|
|
POSTGRES_PASSWORD=postgres
|
|
POSTGRES_DB=localdev
|
|
```
|
|
|
|
> ⛔ **`.gitignore` must list `.env` before you create it.** A credential that reaches a commit is
|
|
> compromised and has to be rotated — deleting it in a later commit leaves the value in history and
|
|
> in every existing clone and fork. Private repositories are no exception. If the project has no
|
|
> `.gitignore`, or has one that omits `.env`, fix that before writing the file.
|
|
|
|
> **Never inline a concrete `user:password@host` URL** in a generated file — build it from the
|
|
> variables above. Beyond hard-coding a credential, such literals are rewritten by secret-redaction
|
|
> filters, and a masked value starting with `*` is a fatal YAML parse error: YAML reads a leading
|
|
> `*` as an alias reference.
|
|
|
|
```yaml
|
|
services:
|
|
postgres:
|
|
image: postgres:16
|
|
ports:
|
|
- "5432:5432"
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
|
POSTGRES_DB: ${POSTGRES_DB}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
restart: unless-stopped
|
|
|
|
# Declare the named volume at the top level of the compose file (merge into an
|
|
# existing top-level `volumes:` key if the file already has one).
|
|
volumes:
|
|
postgres_data:
|
|
```
|
|
|
|
> ⛔ **Use a named volume for the Postgres data dir — not a `./.postgres` bind mount.** On its first
|
|
> start Postgres's `initdb` sets the data directory's permissions to `0700`, which requires `chown`/`chmod`
|
|
> on the mount. Against a **host bind mount on Windows/macOS** — especially **rootless Podman**, where the
|
|
> container user can't change ownership of a Windows-side path — that fails with
|
|
> `could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted`, and the
|
|
> database never initializes. A **named volume** is managed inside the engine's VM (ext4), so `initdb`
|
|
> succeeds on Docker Desktop and Podman alike. This also sidesteps the bind-mount performance and
|
|
> permission quirks Postgres hits on Docker Desktop for Windows/macOS. (Azurite and most other emulators
|
|
> tolerate a workspace bind mount fine — this named-volume rule is specific to database emulators like
|
|
> Postgres that `chown` their data directory.)
|
|
|
|
## Connection String
|
|
|
|
The host depends on where the client runs:
|
|
|
|
| Client location | Host |
|
|
|---|---|
|
|
| Host machine (VS Code debug target, `npm` task) | `localhost` |
|
|
| Another docker-compose service | `postgres` (the service name) |
|
|
|
|
```
|
|
postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}
|
|
```
|
|
|
|
## Required App Environment Variables
|
|
|
|
Declare these in the workspace-root **`.env`**, alongside the `POSTGRES_*` values:
|
|
|
|
| Variable | Value |
|
|
|----------|-------|
|
|
| `DATABASE_URL` | `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}` |
|
|
| `POSTGRES_CONNECTION_STRING` | `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}` |
|
|
|
|
> Use whichever variable name the project's ORM or SDK expects. Both forms above are shown as reference.
|
|
> When the value is set on a docker-compose service, replace the `localhost` host with `postgres`.
|
|
|
|
> **`.env` must declare every key `.env.example` declares.** `.env.example` is documentation —
|
|
> nothing loads it, so a key that appears only there is undefined at run time.
|
|
|
|
> **A runtime settings file does not cover host-run tasks.** `local.settings.json` is read by the
|
|
> Azure Functions host and a compose `environment:` block by its own container; neither reaches a
|
|
> VS Code task that runs a tool directly on the host, such as `npm run db:migrate`. That client
|
|
> fails with "Unable to acquire a connection", which reads like an unready database but is a
|
|
> missing variable — it never opened a socket. Put the value in `.env` so both paths resolve it.
|
|
|
|
## Healthcheck
|
|
|
|
The healthcheck is included in the docker-compose service block above. It uses `pg_isready` to verify PostgreSQL is accepting connections. The migration service (see [migrations.md](../migrations.md)) depends on `condition: service_healthy` to wait for readiness before running migrations.
|
|
|
|
```yaml
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 5
|
|
start_period: 30s
|
|
```
|
|
|
|
## Notes
|
|
|
|
- Port 5432 is the standard PostgreSQL port.
|
|
- Default credentials (`postgres`/`postgres`) are intentionally simple for local dev and are declared in the workspace-root `.env`. Never use in production.
|
|
- Data is persisted to the **named volume `postgres_data`** (managed by the container engine, not a workspace folder). Reset it with `docker compose down -v` / `podman compose down -v`, or `docker volume rm <project>_postgres_data`. Because it is not a workspace directory, it needs no `.vscode/settings.json` `files.exclude` entry and is not part of the workspace stale-**directory** preflight check.
|
|
- **Container runtime:** Certified for both **Docker** and **Podman** — the service block, healthcheck, and named `postgres_data` volume are unchanged for either engine. The named volume (not a bind mount) is what lets `initdb` run under rootless Podman on Windows/macOS. The `condition: service_healthy` gate that migrations depend on is honored by both `docker compose` and `podman compose`.
|