Hi!
I’m experimenting with a "Dagger-in-Dagger" setup for module integration tests. My goal is to have a pytest container connect to a Dagger Engine running as a Dagger Service.
While I know this isn't the standard pattern, I'm trying to understand the feasibility of the architecture. Currently, the client container hangs/fails to connect to the engine service despite a health-check loop.
import dagger
@dagger.object_type
class DaggerTest:
@dagger.function
async def run_nested_dagger(self) -> str:
"""Starts a nested Dagger Engine and runs 'dagger version' against it."""
version = "0.20.8"
engine_svc = (
dagger.dag.container()
.from_(f"registry.dagger.io/engine:v{version}")
.with_exposed_port(8080)
# .with_mounted_cache(
# "/var/lib/dagger", dagger.dag.cache_volume("nested-engine-data")
# )
.with_exec(
["/usr/local/bin/dagger-entrypoint.sh", "--addr", "tcp://0.0.0.0:8080"],
experimental_privileged_nesting=True,
insecure_root_capabilities=True,
)
.as_service()
)
client = (
dagger.dag.container()
.from_("python:3.11-slim")
.with_exec(["apt-get", "update", "-qq"])
.with_exec(["apt-get", "install", "-y", "-qq", "curl"])
.with_exec(
[
"sh", "-c", f"curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION={version} BIN_DIR=/usr/local/bin sh",
]
)
.with_service_binding("dagger-engine", engine_svc)
.with_env_variable("DAGGER_HOST", "tcp://dagger-engine:8080")
.with_exec(
[
"sh", "-c", "until dagger version; do echo 'Waiting for Dagger Engine...'; sleep 1; done",
]
)
)
return await client.with_exec(["dagger", "version"]).stdout()