How to Deploy Containerized Applications with Dewy's Container Command: A Complete Guide
Use dewy container with port mappings (-p), a registry URL (--registry), and optional health checks to perform zero-downtime blue-green deployments of Docker or Podman containers.
Dewy is an open-source deployment tool (linyows/dewy) designed for zero-downtime application releases. The container subcommand orchestrates containerized deployments by managing image pulls, health checks, TCP proxying, and rolling updates—all without requiring external load balancers.
Understanding Dewy's Container Deployment Architecture
Dewy's container deployment follows a modular architecture spanning CLI parsing, runtime abstraction, and orchestration logic.
CLI Flag Parsing in cli.go
The container subcommand is configured in cli.go via the configureContainerCommand function. Key flags include:
--replicas: Number of container instances (default: 1)--health-path: HTTP path for health checks (e.g.,/health)--health-timeout: Health check timeout in seconds (default: 30)--drain-time: Graceful drain period after traffic switch (default: 30)--runtime: Container engine (dockerorpodman, default:docker)--cmd: Command and arguments to pass to the container--admin-port: Admin API port (default: 17539, auto-increments if in use)
The -p or --port flag is required and accepts proxy:container mappings or just proxy for auto-detection.
Runtime Abstraction in container/container.go and docker.go
Dewy abstracts container operations through the Runtime interface defined in container/container.go:
type Runtime interface {
Pull(ctx context.Context, imageRef string) error
Run(ctx context.Context, opts RunOptions) (string, error)
Stop(ctx context.Context, containerID string, timeout time.Duration) error
Remove(ctx context.Context, containerID string) error
GetMappedPort(ctx context.Context, containerID string, containerPort int) (int, error)
GetImageExposedPorts(ctx context.Context, imageRef string) ([]int, error)
// ... additional methods for labels, listing, cleanup
}
The Docker implementation in container/docker.go provides concrete methods like Pull (lines 64-89), Run (lines 40-100), and GetImageExposedPorts (lines 779-830) for reading image metadata.
Orchestration Flow in dewy.go
The RunContainer function (lines 668-712 in dewy.go) orchestrates the deployment:
- Fetches latest image info from the registry
- Builds the Docker/Podman runtime
- Pulls the image via
dockerRuntime.Pull - Resolves port mappings via
resolvePortMappings(lines 152-215) - Executes pre-deploy hooks
- Deploys via
deployContainer(lines 222-284) with rolling updates - Runs post-deploy hooks and cleanup
Required Flags and Configuration
Port Mappings (-p)
The -p flag is required and supports two formats:
# Explicit mapping: public port 8080 forwards to container port 80
dewy container -p 8080:80 ...
# Auto-detection: public port 8080 maps to the image's single EXPOSEd port
dewy container -p 8080 ...
When using auto-detection, Dewy calls GetImageExposedPorts and requires exactly one exposed port in the image metadata.
Registry URL (--registry)
Specify the image source using the img:// protocol:
--registry "img://ghcr.io/linyows/myapp:1.2.3"
Dewy automatically handles registry authentication when needed.
Optional Configuration
- Replicas:
--replicas 3runs three container instances behind the proxy - Health Checks:
--health-path /health --health-timeout 60ensures containers are healthy before receiving traffic - Runtime:
--runtime podmanuses Podman instead of Docker - Drain Time:
--drain-time 10sets the graceful shutdown period after traffic switch
Step-by-Step Deployment Process
Image Pull and Port Detection
When RunContainer executes, it first pulls the image via dockerRuntime.Pull. If port mappings omit the container port, resolvePortMappings queries the image's exposed ports using GetImageExposedPorts and validates that exactly one port is exposed.
Health Check Implementation
If --health-path is provided, createHealthCheckFunc (lines 886-931 in dewy.go) builds a health check function that repeatedly performs HTTP GET requests to http://localhost:<mappedPort>/<health-path> until the container responds with 200 OK or the timeout expires.
Proxy Setup and Traffic Management
Dewy starts a TCP proxy via startProxy (lines 442-473) that listens on each ProxyPort. The proxy maintains a round-robin backend list of host ports assigned by Docker (127.0.0.1::<containerPort>). When new containers start, addProxyBackend adds their ports; old containers are removed via removeProxyBackend before stopping.
Rolling Update Execution
The deployContainer function performs rolling updates:
- Starts new containers with unique names (
<app>-<timestamp>-<replica>) and the labeldewy.managed=true - Waits for health checks to pass
- Adds new containers to the proxy backends
- Removes old containers from the proxy and stops them with a 10-second timeout
- Cleans up old images via
cleanupOldImages
If any step fails, rollbackContainers stops and removes all new containers, restoring the previous state.
Practical Usage Examples
Basic Deployment with Explicit Ports
Deploy an image with explicit port mapping and health checks:
dewy container \
-p 8080:80 \
-p 8443:443 \
--registry "img://ghcr.io/linyows/myapp:1.2.3" \
--health-path /health \
--replicas 2
Auto-Detecting Exposed Ports
When the image has a single EXPOSE directive, omit the container port:
dewy container \
-p 8080 \
--registry "img://ghcr.io/linyows/myapp:latest" \
--health-path /ready
Dewy queries the image metadata via GetImageExposedPorts and maps port 8080 to the exposed container port automatically.
Blue-Green Deployments with Slots
Use the --slot flag for blue-green deployment strategies:
dewy container \
-p 8080:80 \
--registry "img://ghcr.io/linyows/myapp:${VERSION}" \
--slot blue
Dewy checks the image's slot metadata and skips deployment if the slot doesn't match, enabling safe blue-green switches.
Inspecting Running Containers
Query the admin API to view managed containers:
dewy container list
This command queries http://localhost:17539/api/containers (or the configured --admin-port) and displays container IDs, IP:port mappings, deployment times, and names. Internally, this uses ListContainersByLabels with the dewy.managed=true label filter.
Summary
- Dewy's
containercommand orchestrates zero-downtime deployments for Docker and Podman containers viadewy containerwith flags for ports, registry, and health checks. - Required configuration includes port mappings (
-p) and a registry URL (--registry img://...), with optional auto-detection of exposed ports viaGetImageExposedPorts. - Deployment flow pulls images, resolves ports, performs health checks via
createHealthCheckFunc, and manages traffic through a built-in TCP proxy with rolling updates. - Key source files include
cli.gofor flag parsing,container/docker.gofor runtime operations, anddewy.gofor orchestration viaRunContaineranddeployContainer. - Advanced features support blue-green deployments with
--slot, configurable drain times, and an admin API for container inspection.
Frequently Asked Questions
What container runtimes does Dewy support?
Dewy supports Docker and Podman as container runtimes. You can specify the runtime using the --runtime flag (e.g., --runtime podman), with Docker being the default. The runtime abstraction is defined in container/container.go as the Runtime interface, with concrete implementations in container/docker.go and container/podman.go.
How does Dewy handle port mapping when I don't specify the container port?
When you omit the container port in the -p flag (e.g., -p 8080 instead of -p 8080:80), Dewy automatically detects the exposed port by calling GetImageExposedPorts in the runtime implementation. This function inspects the image metadata (the EXPOSE directive in the Dockerfile). Dewy requires exactly one exposed port when using auto-detection; if multiple ports are exposed or none are found, the deployment aborts with an error.
What happens if a health check fails during deployment?
If a health check fails, Dewy performs an automatic rollback. During the deployContainer execution in dewy.go, if the health check function (created by createHealthCheckFunc) fails to receive a 200 OK response within the --health-timeout period, Dewy triggers rollbackContainers. This stops and removes all newly started containers, cleans up the proxy backends, and leaves the previous containers running, ensuring zero-downtime failure recovery.
Can I use Dewy for blue-green deployments?
Yes, Dewy supports blue-green deployments through the --slot flag. When you specify a slot (e.g., --slot blue), Dewy checks the image's slot metadata during the RunContainer execution. If the image's slot does not match the configured slot, Dewy logs "Deploy skipped: slot mismatch" and exits without deploying. This allows you to maintain separate blue and green environments and switch traffic between them by controlling which slot Dewy is configured to accept.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →