Caddy needs to create and manage secrets for storing TLS certificates
obtained via ACME (Let's Encrypt).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The network section was being overwritten by ports, losing any
http-proxy configuration provided by the stack's init hook.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Solana/Agave validators require at least 2 CPU threads for the
ip-echo-server. Increased defaults to support more resource-intensive
workloads.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ConfigMaps containing scripts need execute permissions.
Without this, scripts mounted from ConfigMaps fail with
"permission denied" when used as container commands.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docker-compose command and entrypoint are now passed to K8s:
- entrypoint -> K8s command (overrides ENTRYPOINT)
- command -> K8s args (overrides CMD)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implement _expand_shell_vars to handle ${VAR}, ${VAR:-default}, ${VAR-default}
- Pass config file values to envs_from_compose_file for variable substitution
- Variables from config file still override expanded defaults
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed from ghcr.io/caddyserver/ingress to caddy/ingress (Docker Hub).
The GHCR image returns 403 Forbidden.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Parse protocol suffix (e.g., "8001/udp") in port definitions
- Support multiple ports per container instead of just the first
- Include protocol in NodePort service names for uniqueness
- Enables Solana RPC deployments that require UDP for QUIC protocol
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add get_kind_cluster() to detect existing kind clusters
- Modify create_cluster() to reuse existing clusters automatically
- Add 'laconic-so deploy k8s list cluster' command
- Skip --stack requirement for k8s subcommand
This allows multiple deployments to share the same kind cluster,
simplifying local development workflows.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace nginx with Caddy as the default ingress controller for kind
deployments. Caddy provides automatic HTTPS via Let's Encrypt without
requiring cert-manager.
Changes:
- Add ingress-caddy-kind-deploy.yaml manifest with full RBAC setup
- Modify helpers.py to support configurable ingress_type parameter
- Update cluster_info.py to use caddy ingress class
- Add port 443 mapping for HTTPS support in kind config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Publish / Build and publish (push) Failing after 5sDetails
Deploy Test / Run deploy test suite (push) Failing after 2sDetails
Smoke Test / Run basic test suite (push) Failing after 2sDetails
Lint Checks / Run linter (push) Failing after 2sDetails
Webapp Test / Run webapp test suite (push) Failing after 2sDetails
This is needed to allow custom deploy commands to handle arbitrary args.
* Adds a `DeploymentContext.modify_yaml` helper
* Removes `laconicd` from test stack to simplify it
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/972
Reviewed-by: ashwin <ashwin@noreply.git.vdb.to>
Publish / Build and publish (push) Failing after 7sDetails
Deploy Test / Run deploy test suite (push) Failing after 2sDetails
Smoke Test / Run basic test suite (push) Failing after 2sDetails
Lint Checks / Run linter (push) Failing after 2sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Part of [Service provider auctions for web deployments](https://www.notion.so/Service-provider-auctions-for-web-deployments-104a6b22d47280dbad51d28aa3a91d75) and https://git.vdb.to/cerc-io/stack-orchestrator/issues/948
- Add a command `publish-deployment-auction` to create and publish an app deployment auction
- Add a command `handle-deployment-auction` to handle auctions on deployer side
- Update `request-webapp-deployment` command to allow using an auction id in deployment requests
- Update `deploy-webapp-from-registry` command to handle deployment requests with auction
- Add a command `request-webapp-undeployment` to request an application undeployment
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/950
Reviewed-by: ashwin <ashwin@noreply.git.vdb.to>
Co-authored-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Co-committed-by: Prathamesh Musale <prathamesh.musale0@gmail.com>
Publish / Build and publish (push) Failing after 6sDetails
Lint Checks / Run linter (push) Failing after 3sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
Otherwise we sometimes see errors like:
```
cerc-webapp-deployer: File "/root/.shiv/laconic-so_0f937aa98c2748ef9af8585d6f441dbc01546ace0d6660cbb159d1e5040aeddf/site-packages/stack_orchestrator/deploy/webapp/deploy_webapp_from_registry.py", line 671, in command
cerc-webapp-deployer: shutil.rmtree(tempdir)
cerc-webapp-deployer: File "/usr/lib/python3.10/shutil.py", line 725, in rmtree
cerc-webapp-deployer: _rmtree_safe_fd(fd, path, onerror)
cerc-webapp-deployer: File "/usr/lib/python3.10/shutil.py", line 681, in _rmtree_safe_fd
cerc-webapp-deployer: onerror(os.unlink, fullname, sys.exc_info())
cerc-webapp-deployer: File "/usr/lib/python3.10/shutil.py", line 679, in _rmtree_safe_fd
cerc-webapp-deployer: os.unlink(entry.name, dir_fd=topfd)
cerc-webapp-deployer: FileNotFoundError: [Errno 2] No such file or directory: 'S.gpg-agent.extra'
```
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/941
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Lint Checks / Run linter (push) Failing after 5sDetails
Publish / Build and publish (push) Failing after 4sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
This adds two new commands: `publish-webapp-deployer` and `request-webapp-deployment`.
`publish-webapp-deployer` creates a `WebappDeployer` record, which provides information to requestors like the API URL, minimum required payment, payment address, and public key to use for encrypting config.
```
$ laconic-so publish-deployer-to-registry \
--laconic-config ~/.laconic/laconic.yml \
--api-url https://webapp-deployer-api.dev.vaasl.io \
--public-key-file webapp-deployer-api.dev.vaasl.io.pgp.pub \
--lrn lrn://laconic/deployers/webapp-deployer-api.dev.vaasl.io \
--min-required-payment 100000
```
`request-webapp-deployment` simplifies publishing a `WebappDeploymentRequest` and can also handle automatic payment, and encryption and upload of configuration.
```
$ laconic-so request-webapp-deployment \
--laconic-config ~/.laconic/laconic.yml \
--deployer lrn://laconic/deployers/webapp-deployer-api.dev.vaasl.io \
--app lrn://cerc-io/applications/webapp-hello-world@0.1.3 \
--env-file ~/yaml/hello.env \
--make-payment auto
```
Related changes are included for the deploy/undeploy commands for decrypting and using config, using the payment address from the WebappDeployer record, etc.
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/938
Lint Checks / Run linter (push) Failing after 4sDetails
Publish / Build and publish (push) Failing after 5sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
Adds three new options for deployment/undeployment:
```
"--min-required-payment",
help="Requests must have a minimum payment to be processed",
"--payment-address",
help="The address to which payments should be made. Default is the current laconic account.",
"--all-requests",
help="Handle requests addressed to anyone (by default only requests to my payment address are examined).",
```
In this mode, requests should be designated for a particular address with the attribute `to` and include a `payment` attribute which is the tx hash for the payment.
The deployer will confirm the payment (to the right account, right amount, not used before, etc.) and then proceed with the deployment or undeployment.
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/928
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Deploy Test / Run deploy test suite (push) Failing after 4sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 4sDetails
Publish / Build and publish (push) Failing after 4sDetails
K8s Deployment Control Test / Run deployment control suite on kind/k8s (push) Failing after 3sDetails
Lint Checks / Run linter (push) Failing after 3sDetails
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/917
Reviewed-by: Thomas E Lackey <telackey@noreply.git.vdb.to>
Co-authored-by: David Boreham <david@bozemanpass.com>
Co-committed-by: David Boreham <david@bozemanpass.com>
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
Lint Checks / Run linter (push) Failing after 2sDetails
Publish / Build and publish (push) Failing after 4sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Related to https://git.vdb.to/cerc-io/webapp-deployment-status-api/issues/10
There are two issues in that. One is that the output probably changed recently, whether in the client or server, where no matching record is found by ID (Note this is specific to `laconic record get --id <v>` and does not seem to apply to the similar command to retrieve a record by name, `laconic name resolve <n>`).
Rather than returning `[]` it is now returning `[ null ]`. This cause us to think there *was* an application record found, and we attempt to treat the `null` entry like an Application object. That's fixed by filtering out null responses, which is a good precaution for the deployer, though I think it makes sense to ask whether this new behavior by the client/server is correct. Seems suspicious.
The other issue is that all the defensive checks we had in place to deal with broken/bad AppDeploymentRequests were around the _build_. This error was coming much earlier, merely when parsing and examining the request to see if it needed to be handled at all.
I have now added similar defensive error handling around that portion of the code.
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/922
Reviewed-by: zramsay <zramsay@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Lint Checks / Run linter (push) Failing after 4sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Publish / Build and publish (push) Failing after 5sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
The str type check doesn't work if the port is a ruamel.yaml.scalarstring.SingleQuotedScalarString or ruamel.yaml.scalarstring.DoubleQuotedScalarString
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/919
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/918
Reviewed-by: Thomas E Lackey <telackey@noreply.git.vdb.to>
Co-authored-by: David Boreham <david@bozemanpass.com>
Co-committed-by: David Boreham <david@bozemanpass.com>
Smoke Test / Run basic test suite (push) Failing after 4sDetails
Lint Checks / Run linter (push) Failing after 2sDetails
Publish / Build and publish (push) Failing after 4sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
This emulates the K8S ConfigMap behavior on Docker by using a regular volume.
If a directory exists under `config/` which matches a named volume, the contents will be copied to the volume on `create` (provided the destination volume is empty). That is, rather than a ConfigMap, it is essentially a "config volume".
For example, with a compose file like:
```
version: '3.7'
services:
caddy:
image: cerc/caddy-ethcache:local
restart: always
volumes:
- caddyconfig:/etc/caddy:ro
volumes:
caddyconfig:
```
And a directory:
```
❯ ls stack-orchestrator/config/caddyconfig/
Caddyfile
```
After `laconic-so deploy create --spec-file caddy.yml --deployment-dir /srv/caddy` there will be:
```
❯ ls /srv/caddy/data/caddyconfig
Caddyfile
```
Mounted at `/etc/caddy`
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/914
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Webapp Test / Run webapp test suite (push) Failing after 2sDetails
Publish / Build and publish (push) Failing after 4sDetails
Smoke Test / Run basic test suite (push) Failing after 2sDetails
Lint Checks / Run linter (push) Failing after 2sDetails
NodePort example:
```
network:
ports:
caddy:
- 1234
- 32020:2020
```
Replicas example:
```
replicas: 2
```
This also adds an optimization for k8s where if a directory matching the name of a configmap exists in beneath config/ in the stack, its contents will be copied into the corresponding configmap.
For example:
```
# Config files in the stack
❯ ls stack-orchestrator/config/caddyconfig
Caddyfile Caddyfile.one-req-per-upstream-example
# ConfigMap in the spec
❯ cat foo.yml | grep config
...
configmaps:
caddyconfig: ./configmaps/caddyconfig
# Create the deployment
❯ laconic-so --stack ~/cerc/caddy-ethcache/stack-orchestrator/stacks/caddy-ethcache deploy create --spec-file foo.yml
# The files from beneath config/<config_map_name> have been copied to the ConfigMap directory from the spec.
❯ ls deployment-001/configmaps/caddyconfig
Caddyfile Caddyfile.one-req-per-upstream-example
```
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/913
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Deploy Test / Run deploy test suite (push) Failing after 5sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
Lint Checks / Run linter (push) Failing after 3sDetails
Publish / Build and publish (push) Failing after 4sDetails
Instead of attempting to rewriting the nextConfig file directly, inject a helper function to add the config we need.
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/901
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>
Publish / Build and publish (push) Failing after 5sDetails
Webapp Test / Run webapp test suite (push) Failing after 3sDetails
Smoke Test / Run basic test suite (push) Failing after 3sDetails
Lint Checks / Run linter (push) Failing after 3sDetails
Deploy Test / Run deploy test suite (push) Failing after 3sDetails
Reviewed-on: https://git.vdb.to/cerc-io/stack-orchestrator/pulls/896
Reviewed-by: David Boreham <dboreham@noreply.git.vdb.to>
Co-authored-by: Thomas E Lackey <telackey@bozemanpass.com>
Co-committed-by: Thomas E Lackey <telackey@bozemanpass.com>