diff --git a/.project/infrastructure/README.md b/.project/infrastructure/README.md index d0409f3..31c163f 100644 --- a/.project/infrastructure/README.md +++ b/.project/infrastructure/README.md @@ -5,3 +5,12 @@ layout a project would use for local infrastructure. Each service lives under `services//` and is discovered from its `manifest.yaml`. + +Included samples: + +- `postgresql-18`: single PostgreSQL container with a named data volume. +- `valkey-9`: cache container backed by a Quadlet volume. +- `rustfs`: S3-compatible object storage on a Quadlet network and volume. +- `keycloak`: multi-container service with PostgreSQL on a shared network. +- `app-pod`: Podman pod with web and sidecar containers. +- `local-api-build`: local image build consumed by a container Quadlet. diff --git a/.project/infrastructure/services/app-pod/README.md b/.project/infrastructure/services/app-pod/README.md new file mode 100644 index 0000000..cd527cb --- /dev/null +++ b/.project/infrastructure/services/app-pod/README.md @@ -0,0 +1,23 @@ +# App Pod + +Sample local pod service managed by `dew infra` and Podman Quadlets. + +```bash +dew infra validate app-pod +dew infra up app-pod +dew infra status app-pod +dew infra logs app-pod --lines 100 +``` + +This sample shows a Podman pod with a web container and a sidecar container. + +- web endpoint: `http://127.0.0.1:8088` +- pod: `dew_app-pod` +- web container: `dew_app-pod-web` +- sidecar container: `dew_app-pod-sidecar` + +Stop it with: + +```bash +dew infra down app-pod +``` diff --git a/.project/infrastructure/services/app-pod/dew_app-pod-sidecar.container b/.project/infrastructure/services/app-pod/dew_app-pod-sidecar.container new file mode 100644 index 0000000..7c6f520 --- /dev/null +++ b/.project/infrastructure/services/app-pod/dew_app-pod-sidecar.container @@ -0,0 +1,17 @@ +[Unit] +Description=Dew sample pod sidecar container +Requires=dew_app-pod.pod +After=dew_app-pod.pod + +[Container] +Image=docker.io/library/busybox:1.37 +ContainerName=dew_app-pod-sidecar +Pod=dew_app-pod.pod +Exec=sh -c "while true; do date; sleep 60; done" + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/app-pod/dew_app-pod-web.container b/.project/infrastructure/services/app-pod/dew_app-pod-web.container new file mode 100644 index 0000000..a400c6e --- /dev/null +++ b/.project/infrastructure/services/app-pod/dew_app-pod-web.container @@ -0,0 +1,16 @@ +[Unit] +Description=Dew sample pod web container +Requires=dew_app-pod.pod +After=dew_app-pod.pod + +[Container] +Image=docker.io/library/nginx:alpine +ContainerName=dew_app-pod-web +Pod=dew_app-pod.pod + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/app-pod/dew_app-pod.pod b/.project/infrastructure/services/app-pod/dew_app-pod.pod new file mode 100644 index 0000000..2c5a356 --- /dev/null +++ b/.project/infrastructure/services/app-pod/dew_app-pod.pod @@ -0,0 +1,6 @@ +[Pod] +PodName=dew_app-pod +PublishPort=127.0.0.1:8088:80 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/app-pod/manifest.yaml b/.project/infrastructure/services/app-pod/manifest.yaml new file mode 100644 index 0000000..726894a --- /dev/null +++ b/.project/infrastructure/services/app-pod/manifest.yaml @@ -0,0 +1,19 @@ +id: app-pod +name: App Pod + +runtime: + type: podman-quadlet + +quadlets: + - file: dew_app-pod.pod + unit: dew_app-pod-pod.service + - file: dew_app-pod-web.container + unit: dew_app-pod-web.service + container_name: dew_app-pod-web + - file: dew_app-pod-sidecar.container + unit: dew_app-pod-sidecar.service + container_name: dew_app-pod-sidecar + +schemas: + configure: schemas/configure.schema.json + init: schemas/init.schema.json diff --git a/.project/infrastructure/services/app-pod/schemas/configure.schema.json b/.project/infrastructure/services/app-pod/schemas/configure.schema.json new file mode 100644 index 0000000..b4d09e2 --- /dev/null +++ b/.project/infrastructure/services/app-pod/schemas/configure.schema.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/app-pod/configure.schema.json", + "title": "App Pod Sample Configuration", + "description": "Configuration values represented by the sample pod Quadlets.", + "type": "object", + "additionalProperties": false, + "properties": { + "host_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 8088 + }, + "pod_name": { + "type": "string", + "minLength": 1, + "default": "dew_app-pod" + } + } +} diff --git a/.project/infrastructure/services/app-pod/schemas/init.schema.json b/.project/infrastructure/services/app-pod/schemas/init.schema.json new file mode 100644 index 0000000..26a4f07 --- /dev/null +++ b/.project/infrastructure/services/app-pod/schemas/init.schema.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/app-pod/init.schema.json", + "title": "App Pod Sample Initialization", + "description": "Initialization values for the sample pod service.", + "type": "object", + "additionalProperties": false, + "properties": {} +} diff --git a/.project/infrastructure/services/keycloak/README.md b/.project/infrastructure/services/keycloak/README.md new file mode 100644 index 0000000..ee40117 --- /dev/null +++ b/.project/infrastructure/services/keycloak/README.md @@ -0,0 +1,28 @@ +# Keycloak + +Sample local Keycloak service managed by `dew infra` and Podman Quadlets. + +```bash +dew infra validate keycloak +dew infra up keycloak +dew infra status keycloak +dew infra logs keycloak --lines 100 +``` + +This sample shows a multi-container service with an explicit Quadlet network and +a PostgreSQL dependency. + +- Keycloak: `http://127.0.0.1:8080` +- admin user: `admin` +- admin password: `admin` +- database: `keycloak` +- database container: `dew_keycloak-postgresql` +- database volume: `dew_keycloak_postgresql_data` + +Stop it with: + +```bash +dew infra down keycloak +``` + +The PostgreSQL volume is intentionally retained after stopping the service. diff --git a/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.container b/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.container new file mode 100644 index 0000000..c51c31a --- /dev/null +++ b/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.container @@ -0,0 +1,21 @@ +[Unit] +Description=Dew sample Keycloak PostgreSQL +Requires=dew_keycloak.network dew_keycloak-postgresql.volume +After=dew_keycloak.network dew_keycloak-postgresql.volume + +[Container] +Image=docker.io/library/postgres:18 +ContainerName=dew_keycloak-postgresql +Network=dew_keycloak.network +NetworkAlias=postgres +Volume=dew_keycloak-postgresql.volume:/var/lib/postgresql/data +Environment=POSTGRES_DB=keycloak +Environment=POSTGRES_USER=keycloak +Environment=POSTGRES_PASSWORD=keycloak_dev_password + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.volume b/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.volume new file mode 100644 index 0000000..943c884 --- /dev/null +++ b/.project/infrastructure/services/keycloak/dew_keycloak-postgresql.volume @@ -0,0 +1,2 @@ +[Volume] +VolumeName=dew_keycloak_postgresql_data diff --git a/.project/infrastructure/services/keycloak/dew_keycloak.container b/.project/infrastructure/services/keycloak/dew_keycloak.container new file mode 100644 index 0000000..c35adb9 --- /dev/null +++ b/.project/infrastructure/services/keycloak/dew_keycloak.container @@ -0,0 +1,24 @@ +[Unit] +Description=Dew sample Keycloak +Requires=dew_keycloak.network dew_keycloak-postgresql.container +After=dew_keycloak.network dew_keycloak-postgresql.container + +[Container] +Image=quay.io/keycloak/keycloak:26.6.1 +ContainerName=dew_keycloak +Network=dew_keycloak.network +PublishPort=127.0.0.1:8080:8080 +Environment=KC_BOOTSTRAP_ADMIN_USERNAME=admin +Environment=KC_BOOTSTRAP_ADMIN_PASSWORD=admin +Environment=KC_DB=postgres +Environment=KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak +Environment=KC_DB_USERNAME=keycloak +Environment=KC_DB_PASSWORD=keycloak_dev_password +Exec=start-dev + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/keycloak/dew_keycloak.network b/.project/infrastructure/services/keycloak/dew_keycloak.network new file mode 100644 index 0000000..f767daa --- /dev/null +++ b/.project/infrastructure/services/keycloak/dew_keycloak.network @@ -0,0 +1,2 @@ +[Network] +NetworkName=dew_keycloak diff --git a/.project/infrastructure/services/keycloak/manifest.yaml b/.project/infrastructure/services/keycloak/manifest.yaml new file mode 100644 index 0000000..f31ded6 --- /dev/null +++ b/.project/infrastructure/services/keycloak/manifest.yaml @@ -0,0 +1,21 @@ +id: keycloak +name: Keycloak + +runtime: + type: podman-quadlet + +quadlets: + - file: dew_keycloak.network + unit: dew_keycloak-network.service + - file: dew_keycloak-postgresql.volume + unit: dew_keycloak-postgresql-volume.service + - file: dew_keycloak-postgresql.container + unit: dew_keycloak-postgresql.service + container_name: dew_keycloak-postgresql + - file: dew_keycloak.container + unit: dew_keycloak.service + container_name: dew_keycloak + +schemas: + configure: schemas/configure.schema.json + init: schemas/init.schema.json diff --git a/.project/infrastructure/services/keycloak/schemas/configure.schema.json b/.project/infrastructure/services/keycloak/schemas/configure.schema.json new file mode 100644 index 0000000..b94ddb9 --- /dev/null +++ b/.project/infrastructure/services/keycloak/schemas/configure.schema.json @@ -0,0 +1,31 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/keycloak/configure.schema.json", + "title": "Keycloak Sample Configuration", + "description": "Configuration values represented by the sample Keycloak Quadlets.", + "type": "object", + "additionalProperties": false, + "properties": { + "host_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 8080 + }, + "admin_username": { + "type": "string", + "minLength": 1, + "default": "admin" + }, + "database": { + "type": "string", + "minLength": 1, + "default": "keycloak" + }, + "database_volume": { + "type": "string", + "minLength": 1, + "default": "dew_keycloak_postgresql_data" + } + } +} diff --git a/.project/infrastructure/services/keycloak/schemas/init.schema.json b/.project/infrastructure/services/keycloak/schemas/init.schema.json new file mode 100644 index 0000000..e6bcdbd --- /dev/null +++ b/.project/infrastructure/services/keycloak/schemas/init.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/keycloak/init.schema.json", + "title": "Keycloak Sample Initialization", + "description": "Initialization values for the sample Keycloak service.", + "type": "object", + "additionalProperties": false, + "properties": { + "realm": { + "type": "string", + "minLength": 1, + "default": "dew" + } + } +} diff --git a/.project/infrastructure/services/local-api-build/Containerfile b/.project/infrastructure/services/local-api-build/Containerfile new file mode 100644 index 0000000..af68d9f --- /dev/null +++ b/.project/infrastructure/services/local-api-build/Containerfile @@ -0,0 +1,8 @@ +FROM docker.io/library/alpine:3.23 + +RUN mkdir -p /srv/www \ + && printf '{"service":"local-api-build","status":"ok"}\n' > /srv/www/index.html + +EXPOSE 8080 + +CMD ["busybox", "httpd", "-f", "-p", "8080", "-h", "/srv/www"] diff --git a/.project/infrastructure/services/local-api-build/README.md b/.project/infrastructure/services/local-api-build/README.md new file mode 100644 index 0000000..d345d11 --- /dev/null +++ b/.project/infrastructure/services/local-api-build/README.md @@ -0,0 +1,23 @@ +# Local API Build + +Sample local image build managed by `dew infra` and Podman Quadlets. + +```bash +dew infra validate local-api-build +dew infra up local-api-build +dew infra status local-api-build +dew infra logs local-api-build --lines 100 +``` + +This sample shows a `.build` Quadlet that builds a local image from +`Containerfile`, then runs it through a `.container` Quadlet. + +- endpoint: `http://127.0.0.1:8090` +- built image: `localhost/dew_local-api-build:latest` +- container: `dew_local-api-build` + +Stop it with: + +```bash +dew infra down local-api-build +``` diff --git a/.project/infrastructure/services/local-api-build/dew_local-api-build.build b/.project/infrastructure/services/local-api-build/dew_local-api-build.build new file mode 100644 index 0000000..d47528f --- /dev/null +++ b/.project/infrastructure/services/local-api-build/dew_local-api-build.build @@ -0,0 +1,10 @@ +[Build] +ImageTag=localhost/dew_local-api-build:latest +File=Containerfile +SetWorkingDirectory=unit + +[Service] +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/local-api-build/dew_local-api-build.container b/.project/infrastructure/services/local-api-build/dew_local-api-build.container new file mode 100644 index 0000000..e0a73ef --- /dev/null +++ b/.project/infrastructure/services/local-api-build/dew_local-api-build.container @@ -0,0 +1,16 @@ +[Unit] +Description=Dew sample local API build +Requires=dew_local-api-build.build +After=dew_local-api-build.build + +[Container] +Image=dew_local-api-build.build +ContainerName=dew_local-api-build +PublishPort=127.0.0.1:8090:8080 + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/local-api-build/manifest.yaml b/.project/infrastructure/services/local-api-build/manifest.yaml new file mode 100644 index 0000000..05a665f --- /dev/null +++ b/.project/infrastructure/services/local-api-build/manifest.yaml @@ -0,0 +1,16 @@ +id: local-api-build +name: Local API Build + +runtime: + type: podman-quadlet + +quadlets: + - file: dew_local-api-build.build + unit: dew_local-api-build-build.service + - file: dew_local-api-build.container + unit: dew_local-api-build.service + container_name: dew_local-api-build + +schemas: + configure: schemas/configure.schema.json + init: schemas/init.schema.json diff --git a/.project/infrastructure/services/local-api-build/schemas/configure.schema.json b/.project/infrastructure/services/local-api-build/schemas/configure.schema.json new file mode 100644 index 0000000..53f75d9 --- /dev/null +++ b/.project/infrastructure/services/local-api-build/schemas/configure.schema.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/local-api-build/configure.schema.json", + "title": "Local API Build Sample Configuration", + "description": "Configuration values represented by the sample local build Quadlets.", + "type": "object", + "additionalProperties": false, + "properties": { + "host_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 8090 + }, + "image_tag": { + "type": "string", + "minLength": 1, + "default": "localhost/dew_local-api-build:latest" + } + } +} diff --git a/.project/infrastructure/services/local-api-build/schemas/init.schema.json b/.project/infrastructure/services/local-api-build/schemas/init.schema.json new file mode 100644 index 0000000..cd292b4 --- /dev/null +++ b/.project/infrastructure/services/local-api-build/schemas/init.schema.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/local-api-build/init.schema.json", + "title": "Local API Build Sample Initialization", + "description": "Initialization values for the sample local build service.", + "type": "object", + "additionalProperties": false, + "properties": {} +} diff --git a/.project/infrastructure/services/rustfs/README.md b/.project/infrastructure/services/rustfs/README.md new file mode 100644 index 0000000..8dfd9fe --- /dev/null +++ b/.project/infrastructure/services/rustfs/README.md @@ -0,0 +1,28 @@ +# RustFS + +Sample local RustFS object storage service managed by `dew infra` and Podman +Quadlets. + +```bash +dew infra validate rustfs +dew infra up rustfs +dew infra status rustfs +dew infra logs rustfs --lines 100 +``` + +This sample shows a container on an explicit Quadlet network with a named +Quadlet volume. + +- S3 API: `http://127.0.0.1:9000` +- console: `http://127.0.0.1:9001` +- user: `rustfsadmin` +- password: `rustfsadmin` +- data volume: `dew_rustfs_data` + +Stop it with: + +```bash +dew infra down rustfs +``` + +The named volume is intentionally retained after stopping the service. diff --git a/.project/infrastructure/services/rustfs/dew_rustfs.container b/.project/infrastructure/services/rustfs/dew_rustfs.container new file mode 100644 index 0000000..a4c0229 --- /dev/null +++ b/.project/infrastructure/services/rustfs/dew_rustfs.container @@ -0,0 +1,23 @@ +[Unit] +Description=Dew sample RustFS object storage +Requires=dew_rustfs.network dew_rustfs.volume +After=dew_rustfs.network dew_rustfs.volume + +[Container] +Image=docker.io/rustfs/rustfs:latest +ContainerName=dew_rustfs +Network=dew_rustfs.network +PublishPort=127.0.0.1:9000:9000 +PublishPort=127.0.0.1:9001:9001 +Volume=dew_rustfs.volume:/data +Environment=RUSTFS_ACCESS_KEY=rustfsadmin +Environment=RUSTFS_SECRET_KEY=rustfsadmin +Environment=RUSTFS_CONSOLE_ENABLE=true +Exec=/data + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/rustfs/dew_rustfs.network b/.project/infrastructure/services/rustfs/dew_rustfs.network new file mode 100644 index 0000000..a5df19a --- /dev/null +++ b/.project/infrastructure/services/rustfs/dew_rustfs.network @@ -0,0 +1,2 @@ +[Network] +NetworkName=dew_rustfs diff --git a/.project/infrastructure/services/rustfs/dew_rustfs.volume b/.project/infrastructure/services/rustfs/dew_rustfs.volume new file mode 100644 index 0000000..5bbcdda --- /dev/null +++ b/.project/infrastructure/services/rustfs/dew_rustfs.volume @@ -0,0 +1,4 @@ +[Volume] +VolumeName=dew_rustfs_data +User=10001 +Group=10001 diff --git a/.project/infrastructure/services/rustfs/manifest.yaml b/.project/infrastructure/services/rustfs/manifest.yaml new file mode 100644 index 0000000..1e7856e --- /dev/null +++ b/.project/infrastructure/services/rustfs/manifest.yaml @@ -0,0 +1,18 @@ +id: rustfs +name: RustFS + +runtime: + type: podman-quadlet + +quadlets: + - file: dew_rustfs.network + unit: dew_rustfs-network.service + - file: dew_rustfs.volume + unit: dew_rustfs-volume.service + - file: dew_rustfs.container + unit: dew_rustfs.service + container_name: dew_rustfs + +schemas: + configure: schemas/configure.schema.json + init: schemas/init.schema.json diff --git a/.project/infrastructure/services/rustfs/schemas/configure.schema.json b/.project/infrastructure/services/rustfs/schemas/configure.schema.json new file mode 100644 index 0000000..6b23611 --- /dev/null +++ b/.project/infrastructure/services/rustfs/schemas/configure.schema.json @@ -0,0 +1,32 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/rustfs/configure.schema.json", + "title": "RustFS Sample Configuration", + "description": "Configuration values represented by the sample RustFS Quadlets.", + "type": "object", + "additionalProperties": false, + "properties": { + "api_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 9000 + }, + "console_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 9001 + }, + "access_key": { + "type": "string", + "minLength": 1, + "default": "rustfsadmin" + }, + "volume": { + "type": "string", + "minLength": 1, + "default": "dew_rustfs_data" + } + } +} diff --git a/.project/infrastructure/services/rustfs/schemas/init.schema.json b/.project/infrastructure/services/rustfs/schemas/init.schema.json new file mode 100644 index 0000000..1833785 --- /dev/null +++ b/.project/infrastructure/services/rustfs/schemas/init.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/rustfs/init.schema.json", + "title": "RustFS Sample Initialization", + "description": "Initialization values for the sample RustFS service.", + "type": "object", + "additionalProperties": false, + "properties": { + "bucket": { + "type": "string", + "minLength": 1, + "default": "dew" + } + } +} diff --git a/.project/infrastructure/services/valkey-9/README.md b/.project/infrastructure/services/valkey-9/README.md new file mode 100644 index 0000000..c5fbb77 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/README.md @@ -0,0 +1,24 @@ +# Valkey 9 + +Sample local Valkey service managed by `dew infra` and Podman Quadlets. + +```bash +dew infra validate valkey-9 +dew infra up valkey-9 +dew infra status valkey-9 +dew infra logs valkey-9 --lines 100 +``` + +This sample shows a container backed by a named Quadlet volume. + +- host port: `127.0.0.1:6379` +- container: `dew_valkey-9` +- data volume: `dew_valkey-9_data` + +Stop it with: + +```bash +dew infra down valkey-9 +``` + +The named volume is intentionally retained after stopping the service. diff --git a/.project/infrastructure/services/valkey-9/dew_valkey-9.container b/.project/infrastructure/services/valkey-9/dew_valkey-9.container new file mode 100644 index 0000000..2dcfd42 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/dew_valkey-9.container @@ -0,0 +1,18 @@ +[Unit] +Description=Dew sample Valkey 9 +Requires=dew_valkey-9.volume +After=dew_valkey-9.volume + +[Container] +Image=docker.io/valkey/valkey:9.0.3-alpine +ContainerName=dew_valkey-9 +PublishPort=127.0.0.1:6379:6379 +Volume=dew_valkey-9.volume:/data +Exec=valkey-server --save 60 1 --loglevel warning + +[Service] +Restart=always +TimeoutStartSec=900 + +[Install] +WantedBy=default.target diff --git a/.project/infrastructure/services/valkey-9/dew_valkey-9.volume b/.project/infrastructure/services/valkey-9/dew_valkey-9.volume new file mode 100644 index 0000000..3e814e3 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/dew_valkey-9.volume @@ -0,0 +1,2 @@ +[Volume] +VolumeName=dew_valkey-9_data diff --git a/.project/infrastructure/services/valkey-9/manifest.yaml b/.project/infrastructure/services/valkey-9/manifest.yaml new file mode 100644 index 0000000..5630d76 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/manifest.yaml @@ -0,0 +1,16 @@ +id: valkey-9 +name: Valkey 9 + +runtime: + type: podman-quadlet + +quadlets: + - file: dew_valkey-9.volume + unit: dew_valkey-9-volume.service + - file: dew_valkey-9.container + unit: dew_valkey-9.service + container_name: dew_valkey-9 + +schemas: + configure: schemas/configure.schema.json + init: schemas/init.schema.json diff --git a/.project/infrastructure/services/valkey-9/schemas/configure.schema.json b/.project/infrastructure/services/valkey-9/schemas/configure.schema.json new file mode 100644 index 0000000..78d11f6 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/schemas/configure.schema.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/valkey-9/configure.schema.json", + "title": "Valkey 9 Sample Configuration", + "description": "Configuration values represented by the sample Valkey Quadlets.", + "type": "object", + "additionalProperties": false, + "properties": { + "host_port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 6379 + }, + "volume": { + "type": "string", + "minLength": 1, + "default": "dew_valkey-9_data" + }, + "snapshot_seconds": { + "type": "integer", + "minimum": 1, + "default": 60 + } + } +} diff --git a/.project/infrastructure/services/valkey-9/schemas/init.schema.json b/.project/infrastructure/services/valkey-9/schemas/init.schema.json new file mode 100644 index 0000000..545fa46 --- /dev/null +++ b/.project/infrastructure/services/valkey-9/schemas/init.schema.json @@ -0,0 +1,9 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://artificery.dev/dew/samples/valkey-9/init.schema.json", + "title": "Valkey 9 Sample Initialization", + "description": "Initialization values for the sample Valkey service.", + "type": "object", + "additionalProperties": false, + "properties": {} +} diff --git a/.project/kanban/done/DEW-0035.md b/.project/kanban/done/DEW-0035.md new file mode 100644 index 0000000..761f0a7 --- /dev/null +++ b/.project/kanban/done/DEW-0035.md @@ -0,0 +1,8 @@ +--- +id: DEW-0035 +title: Add broader infra sample services +type: task +created: 2026-05-05T04:19:43.484054Z +--- + +Add sample infrastructure services that exercise common Podman Quadlet patterns including volumes, networks, pods, multi-container dependencies, and local image builds. diff --git a/docs/features/infra.md b/docs/features/infra.md index a6280a2..f2e51d8 100644 --- a/docs/features/infra.md +++ b/docs/features/infra.md @@ -85,8 +85,15 @@ declared units. The Dew repository includes sample service bringups under `.project/infrastructure/services/`. -`postgresql-18` brings up a local PostgreSQL 18 container through Podman -Quadlets: +Available samples: + +- `postgresql-18`: single PostgreSQL 18 container with a named data volume. +- `valkey-9`: cache container backed by a Quadlet volume. +- `rustfs`: S3-compatible object storage on a Quadlet network and volume. +- `keycloak`: multi-container Keycloak and PostgreSQL service on a shared + network. +- `app-pod`: Podman pod with web and sidecar containers. +- `local-api-build`: local image build consumed by a container Quadlet. ```bash dew infra validate postgresql-18