mirror of https://github.com/OpenVidu/openvidu.git
131 lines
6.1 KiB
Markdown
131 lines
6.1 KiB
Markdown
# packaging Specification
|
|
|
|
## Purpose
|
|
Defines how the dashboard is built into its container image and what the image guarantees to whoever runs it:
|
|
location of the Dockerfile, build arguments, base images, user, ports, health check, architectures and size budget.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: One Dockerfile per edition inside its package
|
|
|
|
Edition: CE. The CE edition SHALL be built from `dashboard-ce/docker/Dockerfile`, with the workspace root
|
|
(`openvidu-dashboard/`) as build context, so one `docker build` sees the lockfile and every package.
|
|
|
|
#### Scenario: CE image built from the workspace root
|
|
- **GIVEN** a checkout of the workspace
|
|
- **WHEN** `docker build -f dashboard-ce/docker/Dockerfile .` runs from `openvidu-dashboard/`
|
|
- **THEN** it produces a runnable CE image without any other input
|
|
|
|
### Requirement: Base href build argument
|
|
Edition: CE. The Dockerfile SHALL accept the build argument `BASE_HREF` (default `/`) and build the SPA
|
|
with it, so the application can be served under a path prefix such as `/dashboard/`.
|
|
|
|
#### Scenario: Prefixed base href
|
|
- **WHEN** the image is built with `--build-arg BASE_HREF=/dashboard/`
|
|
- **THEN** the served `index.html` declares `<base href="/dashboard/">` and its assets resolve under that prefix
|
|
|
|
#### Scenario: Default base href
|
|
- **WHEN** the image is built without `BASE_HREF`
|
|
- **THEN** the served `index.html` declares `<base href="/">`
|
|
|
|
### Requirement: Reproducible dependency installation
|
|
Edition: CE. The image build SHALL install dependencies with pnpm from the committed lockfile in frozen mode
|
|
and SHALL use a Node 24 base image pinned to an exact version tag.
|
|
|
|
#### Scenario: Lockfile out of date
|
|
- **GIVEN** a `package.json` change not reflected in `pnpm-lock.yaml`
|
|
- **WHEN** the image is built
|
|
- **THEN** the build fails at the install step instead of resolving new versions
|
|
|
|
### Requirement: CE runtime is a plain Node image without private dependencies
|
|
|
|
Edition: CE. The CE image SHALL run the built backend (which serves the SPA) on an official Node 24 image with only
|
|
production dependencies and no private package; npm, npx, corepack and yarn SHALL be absent from the runtime image.
|
|
|
|
#### Scenario: CE build needs no private access
|
|
- **GIVEN** no build secret and no credentials for private repositories
|
|
- **WHEN** the CE image is built
|
|
- **THEN** the build succeeds
|
|
|
|
#### Scenario: CE image carries no private package
|
|
|
|
- **WHEN** the CE image filesystem is searched for packages of private repositories
|
|
- **THEN** nothing is found
|
|
|
|
### Requirement: Non-root runtime user
|
|
Edition: CE. The main process of the image SHALL run as a non-root user with uid 1000 and gid 1000.
|
|
|
|
#### Scenario: Process identity
|
|
- **WHEN** a container of the image is running
|
|
- **THEN** its main process reports uid 1000 and the application files are readable by that user
|
|
|
|
### Requirement: Exposed port and container health check
|
|
Edition: CE. The image SHALL declare `EXPOSE 5000` and a `HEALTHCHECK` that requests
|
|
`GET /api/healthcheck` on `127.0.0.1:${SERVER_PORT}` (default 5000) without external tools.
|
|
|
|
#### Scenario: Healthy container
|
|
- **GIVEN** a container that has started listening
|
|
- **WHEN** Docker evaluates the health check
|
|
- **THEN** the container becomes `healthy` within the start period
|
|
|
|
#### Scenario: Custom port
|
|
- **GIVEN** a container started with `SERVER_PORT=6000`
|
|
- **WHEN** Docker evaluates the health check
|
|
- **THEN** the check targets port 6000 and the container becomes `healthy`
|
|
|
|
### Requirement: Multi-architecture images
|
|
|
|
Edition: CE. The Dockerfile SHALL build for `linux/amd64` and `linux/arm64`: the platform-independent SPA build stage
|
|
runs once on `$BUILDPLATFORM` and the other stages run per target platform (buildx with QEMU, no native arm64
|
|
runner).
|
|
|
|
#### Scenario: Multi-platform build
|
|
- **WHEN** the image is built with `--platform linux/amd64,linux/arm64`
|
|
- **THEN** the resulting manifest list contains both platforms and each variant starts on its architecture
|
|
|
|
### Requirement: No timezone database in the images
|
|
Edition: CE. The runtime image SHALL NOT contain `tzdata` (it is purged from the Node base image); timestamps are
|
|
stored and logged in UTC and time zone conversion for bucketing uses the data bundled with Node.
|
|
|
|
#### Scenario: Time zone conversion without tzdata
|
|
- **GIVEN** a container with `TZ` unset and no `/usr/share/zoneinfo`
|
|
- **WHEN** a time-series request specifies `tz=Europe/Madrid`
|
|
- **THEN** buckets are aligned to that zone and log timestamps are UTC
|
|
|
|
### Requirement: Signal delivery to the application process
|
|
Edition: CE. The image `CMD` SHALL use exec form so the application process is PID 1 and receives `SIGTERM`
|
|
directly.
|
|
|
|
#### Scenario: docker stop
|
|
- **GIVEN** a running container of the image
|
|
- **WHEN** `docker stop` is issued with the default 10 s timeout
|
|
- **THEN** the container exits with code 0 before the timeout, without being killed
|
|
|
|
### Requirement: Image names and build wrapper
|
|
|
|
Edition: CE. The image SHALL be named `openvidu/openvidu-dashboard`. `./dashboard.sh build-image ce` SHALL build it
|
|
honouring `IMAGE_TAG` (default `dev`) and `BASE_HREF` (default `/`).
|
|
|
|
#### Scenario: Wrapper builds CE
|
|
- **WHEN** `./dashboard.sh build-image ce` runs
|
|
- **THEN** the image `openvidu/openvidu-dashboard:dev` exists locally
|
|
|
|
### Requirement: Image size budget
|
|
|
|
Edition: CE. The uncompressed `linux/amd64` CE image SHALL NOT exceed 300 MB; the image smoke test
|
|
(`./dashboard.sh smoke-image ce`) enforces the budget.
|
|
|
|
#### Scenario: Budget exceeded
|
|
- **WHEN** a built image is larger than its budget
|
|
- **THEN** the smoke test fails and reports the measured size
|
|
|
|
### Requirement: Supply-chain verification inside the image build
|
|
Edition: CE. The Dockerfile SHALL install Aikido safe-chain in the build stage and run `npm safe-chain-verify`
|
|
(with `SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS=0`, so only packages flagged as malicious fail the build) before installing
|
|
dependencies, so the verification runs wherever the image is built.
|
|
|
|
#### Scenario: Build with a flagged package
|
|
- **GIVEN** a lockfile that resolves a package flagged as malicious by safe-chain
|
|
- **WHEN** the image is built
|
|
- **THEN** the build fails in the verification step before any dependency is installed
|