Skip to content

feat(docker): add Coolify/deploy image for iris server - #29

Merged
shivros merged 5 commits into
mainfrom
deploy/coolify
Aug 20, 2026
Merged

feat(docker): add Coolify/deploy image for iris server#29
shivros merged 5 commits into
mainfrom
deploy/coolify

Conversation

@shivros

@shivros shivros commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Purpose

Make iris deployable: multi-stage Dockerfile (linux/arm64 target — Hetzner CAX fleet), env-driven entrypoint, .dockerignore.

What's in the image

  • Builder: rust:1.89-slim + libssl-dev/pkg-config (lettre → native-tls chain). Cargo cache mounts for fast rebuilds.
  • Runtime: debian:bookworm-slim + libssl3/ca-certificates, non-root iris user, /data volume (attachments via IRIS_ATTACHMENT_DIR, audit via IRIS_AUDIT_DIR).
  • Entrypoint materializes iris.toml from IRIS_ENABLED_PROVIDERS (comma list: mock/telegram/email/sms). All secrets env-backed via iris's { env = ... } SecretValue — nothing baked into the image. A full config mounted at /etc/iris/iris.mounted.toml overrides generation.
  • Server: iris serve --addr 0.0.0.0:9876, /health endpoint.

Environment tested

  • Built on builder-01 (linux/arm64) during deploy verification.
  • Runtime target: platform-01 via Coolify.

Verification

  • Image builds on builder-01
  • Container boots with mock provider, /health responds
  • docker inspect shows Architecture: arm64

shivros and others added 5 commits August 19, 2026 19:32
Multi-stage ARM64 image: rust:1.89-slim builder (openssl for lettre),
debian:bookworm-slim runtime, non-root iris user, /data volume for
attachments and audit log. Entrypoint materializes iris.toml from
IRIS_ENABLED_PROVIDERS at container start; secrets stay env-backed
({ env = ... } SecretValue), never baked into the image. A config
mounted at /etc/iris/iris.mounted.toml overrides generation.

Co-authored-by: Archon <archon@purelymail.com>
Entrypoint runs as non-root and cannot mkdir /etc/iris at runtime.

Co-authored-by: Archon <archon@purelymail.com>
rust:1-slim now tracks trixie (glibc 2.39); binaries built there crash
on the bookworm-slim runtime with GLIBC_2.39 not found.

Co-authored-by: Archon <archon@purelymail.com>
Tag order is slim-bookworm, not bookworm-slim.

Co-authored-by: Archon <archon@purelymail.com>
@shivros
shivros merged commit 0c6293c into main Aug 20, 2026
6 checks passed
@shivros
shivros deleted the deploy/coolify branch August 20, 2026 02:11
@shivros

shivros commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Auto-Merge Gate — Approval Rationale

Confidence: 0.91 — MERGE (squash)

Goal recovery: No linked Linear ticket; goal recovered from the PR body — make iris deployable via multi-stage Docker image (arm64/Hetzner fleet), env-driven entrypoint, .dockerignore, no secrets baked into the image.

Semantic verification performed (beyond CI):

  • Config wiring audited against source: IRIS_CONFIG env resolution confirmed in load_default_config() (crates/iris-providers/src/config.rs), SecretValue { env = "..." } untagged enum matches, all six email credential keys match required() calls in email.rs, sms ssh_host/phone_number match sms.rs, mock ignores credentials at registry dispatch. IRIS_ATTACHMENT_DIR/IRIS_AUDIT_DIR env handling confirmed in iris-cli/src/commands.rs.
  • Branch was behind main (strict branch protection): updated via merge of origin/main (creed-adoption commit, zero file overlap with Docker files) — pushed as a270632, all 6 CI checks re-ran green on it.
  • Image built locally from this branch: docker build → success.
  • Container booted with default mock provider: entrypoint log Enabling provider: mock, generated /etc/iris/iris.toml verified valid, non-root iris user, GET /health{"status":"ok"}.

Checks observed: Test, Format Check, Clippy, Secret Scan, Dependency Audit, Creed context drift — all SUCCESS on head a270632.

Scope limits: 3 files, +129/−0, all new files — no Rust source touched, secrets env-only via { env = ... } SecretValue, mounted-config override path preserved.

Residual note: arm64 base resolution not exercised locally (x86_64 host); accepted on the author's builder-01 deploy-verification record. Build logic is arch-agnostic.

Gate policy: standing gate per repo policy (AGENTS.md: CI green + confidence ≥ 0.80). No manual-review markers found.

shivros added a commit that referenced this pull request Aug 20, 2026
…IRIS-11 PR3) (#30)

* feat: generated-surface attachment inputs for send_message (COD-406)

Adopt hydra v0.2.0 json parameters: declare `attachments` in
api/operations.yaml as a body json parameter carrying the closed
inline/stored union schema plus CLI representation overrides
(repeatable --attach with companion --attach-mime). Regenerate
CLI/MCP artifacts and pin hydra to tag v0.2.0.

Runtime decoding lives in iris-core::wire (pure, no I/O):
- decode_attachments: union -> OutboundAttachment::Bytes/Stored,
  rejecting malformed base64, invalid UUIDs, empty inline bytes,
  missing MIME, mixed/unknown fields before any dispatch
- plan_attachments: local-path vs iris://attachment/UUID split,
  --attach-mime cardinality (exactly one per local path, in order,
  stored refs consume none) with explicit override of extension
  inference

HTTP routes and the MCP handler decode through the shared module
(400 / JSON-RPC rejection on malformed unions); the CLI reads local
files at the boundary and builds the OutboundMessage.

Surface tests: HTTP 400 on mixed/unknown/bad-base64, MCP tool
rejection, CLI flag parsing + boundary reads + mime override
ordering, generated-schema union assertions, and a codegen
freshness test mirroring `iris-codegen check`.

180/180 tests; build/clippy/fmt/codegen green.

* chore: check off T8-T11 in add-outbound-attachments tasks

* fix: reject null filename and blank --attach-mime overrides (review panel)

Review panel findings on COD-406:
- Reviewer B [MAJOR]: decode_item mapped explicit `filename: null` to None,
  widening the declared optional-but-not-nullable union schema. Now rejected
  before dispatch like any other unknown/malformed union member.
- Reviewer A [MAJOR]: CLI --attach-mime overrides accepted empty/whitespace
  values while HTTP/MCP reject blank mime_type. plan_attachments now rejects
  blank overrides, keeping all three surfaces on the same contract.

Both regression-tested in iris-core::wire.

The panel's Docker-deletion BLOCK was a false positive caused by base drift:
PR #29 added Docker files to main after this branch was cut; the rebase onto
0c6293c resolves it. No Docker files are touched by this branch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant