feat: support PID namespace mode in Compose (#276)

This adds `pid: host` compose key support.

Modelled after #238.

See: #237

Signed-off-by: Miek Gieben <miek@miek.nl>
Co-authored-by: Pasha Sviderski <me@psviderski.name>
This commit is contained in:
Miek Gieben
2026-03-24 16:18:53 +10:00
committed by GitHub
co-authored by Pasha Sviderski
parent 2ab58d24d4
commit 98439b7743
8 changed files with 29 additions and 0 deletions
+1
View File
@@ -627,6 +627,7 @@ func (s *Server) CreateServiceContainer(
Binds: spec.Container.Volumes,
Init: spec.Container.Init,
Mounts: mounts,
PidMode: spec.Container.Pid,
PortBindings: portBindings,
Privileged: spec.Container.Privileged,
Resources: container.Resources{
+3
View File
@@ -11,6 +11,7 @@ import (
mapset "github.com/deckarep/golang-set/v2"
"github.com/distribution/reference"
"github.com/docker/docker/api/types/container"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/psviderski/uncloud/internal/machine/api/pb"
@@ -256,6 +257,8 @@ type ContainerSpec struct {
Init *bool
// LogDriver overrides the default logging driver for the container. Each Docker daemon can have its own default.
LogDriver *LogDriver
// Pid allows setting the PID name space, currently only "" or "host" is supported.
Pid container.PidMode
// Privileged gives extended privileges to the container. This is a security risk and should be used with caution.
Privileged bool
// PullPolicy determines when to pull the image from the registry or use the image already available in the cluster.
+1
View File
@@ -206,6 +206,7 @@ func TestContainerSpec_Clone(t *testing.T) {
original := ContainerSpec{
CapAdd: []string{"NET_ADMIN"},
CapDrop: []string{"ALL"},
Pid: container.PidMode("host"),
Command: []string{"sh", "-c", "echo hello"},
Entrypoint: []string{"/bin/bash"},
Env: EnvVars{
+1
View File
@@ -53,6 +53,7 @@ func ServiceSpecFromCompose(project *types.Project, serviceName string) (api.Ser
Healthcheck: healthcheckFromCompose(service.HealthCheck),
Image: service.Image,
Init: service.Init,
Pid: container.PidMode(service.Pid),
Privileged: service.Privileged,
PullPolicy: pullPolicy,
Resources: resourcesFromCompose(service),
+1
View File
@@ -127,6 +127,7 @@ func TestServiceSpecFromCompose(t *testing.T) {
"max-file": "3",
},
},
Pid: "host",
Privileged: true,
PullPolicy: api.PullPolicyAlways,
Resources: api.ContainerResources{
+1
View File
@@ -6,6 +6,7 @@ services:
- ALL
command: ["nginx", "updated", "command"]
cpus: 0.5
pid: host
deploy:
update_config:
order: stop-first
+20
View File
@@ -47,6 +47,26 @@ func TestEvalContainerSpecChange_ContainerCapDrop(t *testing.T) {
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec))
}
func TestEvalContainerSpecChange_ContainerPid(t *testing.T) {
t.Parallel()
currentSpec := api.ServiceSpec{
Container: api.ContainerSpec{
Image: "nginx:latest",
},
}
newSpec := api.ServiceSpec{
Container: api.ContainerSpec{
Image: "nginx:latest",
Pid: "host",
CapAdd: []string{"NET_ADMIN"},
},
}
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(currentSpec, newSpec))
assert.Equal(t, ContainerNeedsRecreate, EvalContainerSpecChange(newSpec, currentSpec))
}
func TestEvalContainerSpecChange_ContainerResources(t *testing.T) {
t.Parallel()
@@ -38,6 +38,7 @@ If you rely on a specific Compose feature that is not supported by Uncloud, plea
| `mem_swappiness` | ❌ Not supported | |
| `memswap_limit` | ❌ Not supported | |
| `networks` | ❌ Not supported | All containers share cluster network |
| `pid` | ✅ Supported | Set the PID namespace mode, `pid: host` only |
| `ports` | ⚠️ Limited | `mode: host` only, use [`x-ports`](#x-ports) for HTTP/HTTPS |
| `privileged` | ✅ Supported | Run containers in privileged mode |
| `pull_policy` | ✅ Supported | `always`, `missing`, `never` |