Skip to content

Latest commit

 

History

History
165 lines (121 loc) · 5.62 KB

cuos-init-app.md

File metadata and controls

165 lines (121 loc) · 5.62 KB

Your CuOS Init App

To start your application you have to define a container. Let's call it CuOS Init App; it runs as cuos-app. Bringing your own is the Own CuOS Init App level — if you do not, you get CuOS IaC.

What you can do within this container:

  • Start your application
  • Start more docker container (you need to mount the docker socket, see app_command label)
  • Interact with the CuOS API via /var/run/cuos.sock.

Start the container

Relevant configuration fields, see system.json:

{
  "init_image": "your-registry/your-app",
  "init_image_version": "1.2.3",
  "init_image_digest": "sha256:..."
}

CuOS IaC is the default one

CuOS IaC is a CuOS Init App like any other — the one you get if you do not bring your own. cuos-release's release.json pins it as init_image, so a configuration that includes release.json already has one and starts CuOS IaC, which then deploys your services from a git repository.

Setting init_image yourself replaces it:

{
  "#include": ["cuos-release/release.json"],
  "init_image": "your-registry/your-app",
  "init_image_version": "1.2.3",
  "init_image_digest": "sha256:..."
}

The system's name follows the same key: product_name defaults to CuOS IaC when init_image contains cuos-iac, and to CuOS otherwise (product_name in updater/lib/config.sh).

Build your CuOS Init App

FROM your-base-image

# Your application setup
COPY app /app

Label Based Custom Command

If the application image sets a label:

LABEL dev.cuos.app_command="--env FOO=bar --cap-add NET_ADMIN"

Its value replaces the default Docker run argument block (still augmented with standard names/restart/logging flags). Keep security in mind: avoid unnecessary capabilities.

Default:

--volume /var/run/docker.sock:/var/run/docker.sock \
--volume /root/.docker/config.json:/root/.docker/config.json:ro \
--volume /system.json:/system.json:ro \
--volume /var/run/cuos.sock:/var/run/cuos.sock \
--volume /usr/local/share/ca-certificates/custom:/usr/local/share/ca-certificates/custom:ro

Suggestions for more parameters:

--memory 512MB \
--user myuser:mygroup \
--read-only \
--tmpfs /etc/ssl/certs:rw,noexec,nosuid,size=16m
--tmpfs /tmp:rw,size=64m

Entrypoint

To make ca-certificate import work, you have to execute

update-ca-certificates --fresh

Entrypoint: Container Startup Parameters

Additional runtime environment variables, that are set by CuOS:

Variable Purpose
SYSTEM_TYPE=cuos Identify environment
SYSTEM_CONFIG_PATH=/system.json Location of active config
VIRT_TYPE Result of systemd-detect-virt
Positional Args Current + previous app version (used by your entrypoint logic)

In-Container Hooks

CuOS runs scripts inside the container by name. All of them are optional — if the file is not there, CuOS carries on.

Script When Called by
/api/post_update after a successful OS/app update system/cuos/app-init.sh:195, exit code ignored
/api/trigger cuos trigger, with the input on stdin and the arguments passed through system/cuos/api.sh:344
/api/cuos-trigger-update cuos trigger-update; if it is missing, CuOS runs cuos update itself system/cuos/api.sh:149

post_update is where migrations or internal reconfiguration belong — the one place guaranteed to run once, after the new version is in place.

cuos-trigger-update is the one hook whose exit code matters. Exit 0 tells CuOS your app has taken the update over; on 1 or 126 CuOS runs cuos update itself. So do not leave an empty stub there: it returns 0 and cuos trigger-update then does nothing at all. CuOS IaC's implementation wakes its poll loop, which does the work.

Don't forget to add execution permission to your scripts.

What a hook is given:

Name Type Description
SYSTEM_TYPE env Always cuos for identification
SYSTEM_CONFIG_PATH env Path to active config (/system.json)
VIRT_TYPE env Result of systemd-detect-virt (e.g. kvm, docker, none)
$1 arg Current application version (from init_image_version)
$2 arg Previous application version (if available)

Failure & Rollback Logic

Failure Scenario Host Reaction
App fails to start repeatedly during update window Triggers OS rollback
Digest never matches (tamper?) Continuous pull attempts + error logs
Timeout (> 3600s startup/update) Rollback & reboot
Single transient pull failure Retry every 60s

Rollback resets to previous OS subvolume and replays last stable config.

Operational Tips

  • Use digests for production to ensure integrity.
  • Store persistent writable data under mounted /data volumes if you add any (consider explicit mounts rather than relying on default host path sharing beyond what CuOS provides).
  • Avoid --privileged unless mandatory; prefer granular --cap-add.

Launch Flow (Simplified)

[systemd] → cuos-app.service → app-init.sh
  └─ waits for Docker daemon ready
     └─ performs registry login (if configured)
        └─ evaluates desired vs current image digest
           ├─ pull if missing / version change / digest mismatch
           ├─ create or start container `cuos-app`
           └─ invoke optional in-container hook (/api/post_update)