57 lines
3.2 KiB
Markdown
57 lines
3.2 KiB
Markdown
# PortfolioHub container publication and operator handoff
|
|
|
|
## Publication is not deployment
|
|
|
|
Only a requester-authorized strict `vX.Y.Z` tag push may publish. The workflow builds once and gives the same tested image exactly two selectors:
|
|
|
|
- `ghcr.io/fourblocks2020/portfolio-hub:<source-commit-first-12>`
|
|
- `ghcr.io/fourblocks2020/portfolio-hub:vX.Y.Z`
|
|
|
|
It never publishes `latest`. The registry digest is the immutable artifact identity:
|
|
|
|
```text
|
|
ghcr.io/fourblocks2020/portfolio-hub@sha256:<64-lowercase-hex-digest>
|
|
```
|
|
|
|
Publication does **not** deploy, place, replace, start, stop, or restart a container in any environment. This repository change adds no production Compose, Kubernetes, Helm, systemd, Dockge, or other deployment configuration. An authorized deployment system and operator must consume the digest separately.
|
|
|
|
## Operator handoff contract
|
|
|
|
A successful publication hands the operator or deployment system only these verified inputs:
|
|
|
|
- exact `vX.Y.Z` source tag;
|
|
- full source commit and OCI `org.opencontainers.image.revision`;
|
|
- immutable registry digest;
|
|
- matching commit-prefix and version selectors;
|
|
- successful tested-image workflow evidence.
|
|
|
|
Before any separately authorized use, verify that the digest and OCI revision identify the intended source. The publication workflow itself does not claim runtime deployment or production readiness.
|
|
|
|
## Required pre-start migration contract
|
|
|
|
Database migration is a separate, explicit pre-start operation using the exact image digest and runtime-injected production settings:
|
|
|
|
1. execute `pfhub migrate-db` as a one-shot operation;
|
|
2. stop on nonzero migration result;
|
|
3. start the application only after migration succeeds;
|
|
4. evaluate HTTP liveness and database readiness separately.
|
|
|
|
The image's default application command does not run migrations. Do not run migration implicitly from every application replica. Production migration execution remains outside this implementation and requires separate authorization.
|
|
|
|
## Runtime security inputs
|
|
|
|
The image contract provides:
|
|
|
|
- default UID/GID `10001:10001`;
|
|
- explicit command `uvicorn app.main:app --host 0.0.0.0 --port 8000`;
|
|
- no application-required writable data path;
|
|
- migration resources installed inside the Python package.
|
|
|
|
A deployment system should enforce a read-only root filesystem, dropped capabilities, no-new-privileges, and only a bounded temporary filesystem when needed. PostgreSQL credentials, token configuration, and `CREDENTIAL_ENCRYPTION_KEY` are runtime secrets; they must never be baked into the image or publication artifact. Secret injection and writable-mount configuration belong to the separately authorized deployment environment, not this repository change.
|
|
|
|
## Image and database rollback boundary
|
|
|
|
Rollback identity is a previously verified immutable image digest whose OCI revision is known. This document defines that identity boundary only; it does not add or execute rollback automation.
|
|
|
|
Image rollback is **not** database rollback. Selecting older application bytes does not reverse Alembic migrations, schema or data changes, tokens, or external side effects. Database restore, downgrade, or forward-fix requires a separately reviewed and authorized operational procedure.
|