docs: correct loader-network reachability claim; refresh HOWTO env vars
Final-review must-fixes: - HOWTO.md: drop CAMELEER_SERVER_RUNTIME_JARDOCKERVOLUME; add the three new artifact env vars (loaderimage / artifacttokenttlseconds / artifactbaseurl). - DeploymentExecutor @PostConstruct WARN, handoff doc, and docker-orchestration rule no longer claim the loader uses cameleer-traefik. The loader runs on the PRIMARY Docker network only — additional networks are attached after startContainer returns, by which time the loader has exited. SaaS still works because the tenant's primary network hosts the tenant server. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -48,13 +48,15 @@ When deployed via the cameleer-saas platform, this server orchestrates customer
|
||||
|
||||
`DeploymentExecutor` generates the signed URL via `ArtifactDownloadTokenSigner.sign(appVersion.id(), Duration.ofSeconds(artifactTokenTtlSeconds))` and passes `appVersion.id()`, the URL, `appVersion.jarSizeBytes()`, and the loader image into `ContainerRequest`. The host filesystem is no longer involved at deploy time.
|
||||
|
||||
**Loader → server reachability**: the loader container hits the Cameleer server over HTTP from inside its
|
||||
own Docker network. The signed URL is built from `cameleer.server.runtime.artifactbaseurl` (preferred), falling
|
||||
back to `cameleer.server.runtime.serverurl`, falling back to `http://cameleer-server:8081`. The default works
|
||||
in SaaS mode because `DockerNetworkManager` adds `cameleer-traefik` as an additional network for tenant
|
||||
containers, and the server is reachable on that network via the `cameleer-server` DNS alias. For non-SaaS
|
||||
topologies (server on a different network than tenants), set `CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL`
|
||||
explicitly to a URL the loader can reach.
|
||||
**Loader → server reachability**: the loader hits the Cameleer server from its **primary** Docker
|
||||
network only (`request.network()`, set from `CAMELEER_SERVER_RUNTIME_DOCKERNETWORK`). Additional networks
|
||||
(`cameleer-traefik`, per-env) are attached by `DockerNetworkManager.connectContainer` AFTER `startContainer`
|
||||
returns — by which time the loader has already exited. The loader cannot use them. The signed URL is built
|
||||
from `cameleer.server.runtime.artifactbaseurl` (preferred), falling back to `cameleer.server.runtime.serverurl`,
|
||||
falling back to `http://cameleer-server:8081`. The default works in SaaS mode because the tenant's primary
|
||||
network (`cameleer-tenant-{slug}`) hosts the tenant's own server — same `CAMELEER_SERVER_RUNTIME_DOCKERNETWORK`
|
||||
on both. For non-SaaS topologies, set `CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL` to a URL the loader can reach
|
||||
on its primary network.
|
||||
|
||||
## DeploymentExecutor Details
|
||||
|
||||
|
||||
6
HOWTO.md
6
HOWTO.md
@@ -495,8 +495,10 @@ Key settings in `cameleer-server-app/src/main/resources/application.yml`. All cu
|
||||
| `cameleer.server.runtime.baseimage` | `cameleer-runtime-base:latest` | `CAMELEER_SERVER_RUNTIME_BASEIMAGE` | Base Docker image for app containers |
|
||||
| `cameleer.server.runtime.dockernetwork` | `cameleer` | `CAMELEER_SERVER_RUNTIME_DOCKERNETWORK` | Primary Docker network |
|
||||
| `cameleer.server.runtime.dockerruntime` | *(empty = auto)* | `CAMELEER_SERVER_RUNTIME_DOCKERRUNTIME` | Container runtime override. Empty auto-detects gVisor (`runsc`) when registered with the daemon and falls back to the daemon default. Set to e.g. `kata` to force a specific runtime, or `runc` to force the default even if `runsc` is installed. |
|
||||
| `cameleer.server.runtime.jarstoragepath` | `/data/jars` | `CAMELEER_SERVER_RUNTIME_JARSTORAGEPATH` | JAR file storage directory |
|
||||
| `cameleer.server.runtime.jardockervolume` | *(empty)* | `CAMELEER_SERVER_RUNTIME_JARDOCKERVOLUME` | Docker volume for JAR sharing |
|
||||
| `cameleer.server.runtime.jarstoragepath` | `/data/jars` | `CAMELEER_SERVER_RUNTIME_JARSTORAGEPATH` | JAR file storage directory (used by `FilesystemArtifactStore`) |
|
||||
| `cameleer.server.runtime.loaderimage` | `gitea.siegeln.net/cameleer/cameleer-runtime-loader:latest` | `CAMELEER_SERVER_RUNTIME_LOADERIMAGE` | Init-container image that fetches the JAR via signed URL |
|
||||
| `cameleer.server.runtime.artifacttokenttlseconds` | `600` | `CAMELEER_SERVER_RUNTIME_ARTIFACTTOKENTTLSECONDS` | TTL (seconds) for HMAC-signed artifact-download URLs |
|
||||
| `cameleer.server.runtime.artifactbaseurl` | *(empty)* | `CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL` | Base URL the loader uses to reach the server. Blank falls back to `serverurl`, then `http://cameleer-server:8081`. Must be reachable from the loader container's primary Docker network. |
|
||||
| `cameleer.server.runtime.routingmode` | `path` | `CAMELEER_SERVER_RUNTIME_ROUTINGMODE` | `path` or `subdomain` Traefik routing |
|
||||
| `cameleer.server.runtime.routingdomain` | `localhost` | `CAMELEER_SERVER_RUNTIME_ROUTINGDOMAIN` | Domain for Traefik routing labels |
|
||||
| `cameleer.server.runtime.serverurl` | *(empty)* | `CAMELEER_SERVER_RUNTIME_SERVERURL` | Server URL injected into app containers |
|
||||
|
||||
@@ -111,9 +111,12 @@ public class DeploymentExecutor {
|
||||
if (artifactBaseUrl.isBlank() && globalServerUrl.isBlank()) {
|
||||
log.warn("Neither cameleer.server.runtime.artifactbaseurl nor cameleer.server.runtime.serverurl is set. "
|
||||
+ "Loader containers will fall back to http://cameleer-server:8081 — this requires the loader's "
|
||||
+ "Docker network to resolve `cameleer-server`. In SaaS mode the server is on `cameleer-traefik` "
|
||||
+ "which is added as an additional network for tenant containers, so this works. For other "
|
||||
+ "deployment topologies, set CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL explicitly.");
|
||||
+ "PRIMARY Docker network (CAMELEER_SERVER_RUNTIME_DOCKERNETWORK) to resolve `cameleer-server`. "
|
||||
+ "Additional networks (e.g. cameleer-traefik) are attached AFTER startContainer returns, by "
|
||||
+ "which time the loader has already exited — they are not available to the loader. In SaaS "
|
||||
+ "mode the tenant primary network (cameleer-tenant-{slug}) hosts the tenant's server, so this "
|
||||
+ "works. For other topologies, set CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL to a URL the loader "
|
||||
+ "can reach over the primary network.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,11 +90,15 @@ New env vars (`application.yml` defaults shown):
|
||||
|
||||
Removed: `CAMELEER_SERVER_RUNTIME_JARDOCKERVOLUME` — no longer needed (loader downloads via HTTP, not bind-mount).
|
||||
|
||||
`@PostConstruct` WARN logs at server startup if neither `artifactbaseurl` nor `serverurl` is set, pointing at the implicit `cameleer-server` Docker DNS dependency that only works on `cameleer-traefik`.
|
||||
`@PostConstruct` WARN logs at server startup if neither `artifactbaseurl` nor `serverurl` is set, pointing at the implicit `cameleer-server` Docker DNS dependency on the loader's primary network.
|
||||
|
||||
## Network reachability requirement
|
||||
|
||||
The loader container must be able to reach the Cameleer server over HTTP. In SaaS mode this works because `DockerNetworkManager` adds `cameleer-traefik` as an additional network for tenant containers, and the server is reachable on that network via the `cameleer-server` DNS alias. For non-SaaS topologies, set `CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL` to a URL the loader can reach.
|
||||
The loader container reaches the server over the **primary** Docker network only — `request.network()` in `ContainerRequest`, set from `CAMELEER_SERVER_RUNTIME_DOCKERNETWORK`. Additional networks (`cameleer-traefik`, per-env, etc.) are attached by `DockerNetworkManager.connectContainer` AFTER `startContainer` returns, by which time the loader has already exited — they are NOT available to the loader.
|
||||
|
||||
In SaaS mode this works because the tenant's primary network is `cameleer-tenant-{slug}` and the tenant's own `cameleer-server` instance is configured to run on that same network (`CAMELEER_SERVER_RUNTIME_DOCKERNETWORK=cameleer-tenant-{slug}` on the server's compose/manifest). The loader resolves `cameleer-server` via Docker DNS on the primary network and pulls the artifact directly.
|
||||
|
||||
For non-SaaS topologies (e.g. server on a different network from tenant containers), set `CAMELEER_SERVER_RUNTIME_ARTIFACTBASEURL` to a URL the loader can reach over its primary network.
|
||||
|
||||
## Documented but skipped
|
||||
|
||||
|
||||
Reference in New Issue
Block a user