feat(release): add verified image publication pipeline
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user