Understanding the Key Components of Dewy's Architecture: A Modular Go Deployment Orchestrator

Dewy is a modular Go-based deployment orchestrator that coordinates registries, artifacts, caching, container runtimes, and notifications through a central core to deploy binaries, static assets, or containers with zero-downtime rolling updates.

Dewy is an open-source deployment tool written in Go that automates the release of applications across multiple formats. Understanding the key components of Dewy's architecture reveals how it maintains flexibility across binary servers, static asset hosting, and containerized workloads while keeping concerns cleanly separated into swappable interfaces.

Core Orchestration Engine

The heart of Dewy resides in dewy.go, which defines the Dewy struct and its lifecycle methods. This component coordinates the entire deployment workflow, initializing subsystems, scheduling periodic checks, handling OS signals, and driving the deployment loop for both server and container modes.

Key methods include New for initialization, Start to launch the scheduler and auxiliary services, Run for traditional binary deployments, and RunContainer for Docker or Podman workloads. The core maintains references to the registry client, cache, notifier, and container runtime, acting as the central dispatcher.

Configuration Management

All user-provided settings are encapsulated in the Config struct defined in config.go. This structure defines the deployment command type—SERVER, ASSETS, or CONTAINER—along with registry URLs, container options, hook commands, and notification preferences.

The DefaultConfig() function provides sensible defaults, while the CLI layer in cli.go and cmd/dewy/main.go handles flag parsing and config assembly. This separation allows Dewy to run programmatically with a constructed Config or via command-line arguments.

Registry Abstraction Layer

Dewy abstracts artifact sources through the Registry interface in registry/registry.go. This interface defines Current() to fetch the latest artifact metadata and Report() to send deployment status back to the source.

Implementations include registry/ghr.go for GitHub Releases, registry/oci.go for OCI registries, and adapters for S3 and GCS. This modular design allows Dewy to poll for new versions from virtually any artifact storage system without modifying the core logic.

Artifact Handling

The artifact package in artifact/artifact.go provides a download abstraction layer. It handles fetching binaries, tarballs, or OCI images from remote sources and exposes an io.Reader interface that integrates with the caching layer.

The artifact.New function creates an appropriate handler based on the registry type, while the Download method streams content to the local cache. This separation ensures that network I/O concerns remain isolated from deployment orchestration.

Caching and Persistence (KVS)

Dewy uses the kvs package defined in kvs/kvs.go to persist downloaded artifacts and track the current deployment version. The KVS interface supports multiple backends: file for local filesystem storage, memory for ephemeral caching, redis for distributed setups, and consul for service-discovery-backed storage.

The cache stores artifacts under versioned keys and maintains a current reference to track the active deployment, enabling atomic rollbacks and preventing redundant downloads when the registry reports a version already present in the cache.

Notification System

Deployment visibility is handled by the notifier package in notifier/notifier.go. The Notifier interface defines methods for Send, SendError, and SendHookResult, with concrete implementations for Slack (notifier/slack.go), email, and a no-op stub for silent operation.

Notifiers receive context about the deployment—version numbers, artifact sources, and error details—allowing teams to integrate Dewy into existing incident response workflows.

Container Runtime Integration

For CONTAINER command types, Dewy interfaces with Docker or Podman through the container package. The Runtime interface in container/docker.go and container/podman.go abstracts container lifecycle operations: Pull, Run, Stop, and health-check polling.

This abstraction allows Dewy to manage containerized workloads identically regardless of whether the underlying runtime is Docker or Podman, supporting rolling updates with zero downtime. Users specify their preferred runtime in the ContainerConfig, and Dewy instantiates the appropriate implementation via container.NewDocker or container.NewPodman.

Supporting Infrastructure Components

TCP Reverse Proxy

When operating in container mode, Dewy includes an in-process TCP reverse proxy defined in dewy.go. This component manages rolling updates by dynamically adding and removing backend containers via addBackend and removeBackend methods while maintaining round-robin routing.

The proxy listens on configured proxy ports and forwards traffic to dynamically allocated container ports, enabling zero-downtime deployments without external load balancers.

Admin API

Dewy exposes a small HTTP administrative interface defined in dewy.go that provides visibility into runtime state. Endpoints include /api/containers for listing managed containers and /api/status for health checks, enabling integration with external orchestration tools and monitoring systems.

Server Starter

For SERVER command deployments, Dewy leverages github.com/linyows/server-starter to manage the user-provided binary. This helper handles graceful restarts, socket passing, and process supervision, ensuring that binary deployments maintain availability during updates.

Structured Logging

All subsystems report through a centralized logger defined in logging/logger.go. The Logger struct provides JSON-encoded output with methods for Info, Error, and Debug levels, ensuring consistent observability across the registry, cache, and container runtime components.

Execution Flow: How Components Interact

The deployment process follows a clear orchestration pattern that varies by command type.

For server and assets deployments, the flow begins with the CLI parsing flags in cmd/dewy/main.go and cli.go to build a Config. The dewy.New function initializes the core with a file-based cache (kvs.File). When Start is invoked, it launches the registry client, notifier, and scheduler.

The scheduler triggers Run at configured intervals. This method calls registry.Current to check for new versions, consults the KVS cache to avoid redundant downloads, and uses artifact.New to fetch the artifact if needed. After caching via kvs.ExtractArchive, it creates a current symlink and launches the binary via the starter helper, finally sending a deployment report through the notifier.

For container deployments, the flow diverges at RunContainer. After pulling the OCI image via artifact.New, Dewy resolves port mappings through resolvePortMappings, which auto-detects exposed ports when not explicitly configured. It then starts containers using the selected runtime (container.NewDocker or container.NewPodman), registering each with the TCP proxy via addProxyBackend.

Once health checks pass, Dewy removes old containers from the proxy and stops them, cleans up obsolete images, and updates the admin API state. Signal handling via waitSigs ensures graceful shutdowns, invoking stopManagedContainers, stopProxy, and stopAdminAPI when receiving SIGTERM or SIGINT.

This architecture isolates side effects within dedicated sub-packages while the core focuses on deployment decisions, enabling users to swap registries, caches, or runtimes without modifying the orchestration logic.

Summary

  • Dewy Core (dewy.go) orchestrates the deployment lifecycle, scheduling, and signal handling for all command types.
  • Registry Interface (registry/registry.go) abstracts version sources like GitHub Releases, OCI registries, and S3, enabling pluggable artifact discovery.
  • Artifact & Cache (artifact/artifact.go and kvs/kvs.go) handle secure downloads and local persistence with support for filesystem, Redis, and Consul backends.
  • Container Runtime (container/docker.go, container/podman.go) provides a unified interface for Docker and Podman operations, supporting zero-downtime rolling updates.
  • Infrastructure Services include an in-process TCP Proxy for traffic routing, an Admin API for observability, and a Notifier system for deployment alerts.

Frequently Asked Questions

What is the role of the Dewy Core in the architecture?

The Dewy Core acts as the central orchestrator defined in dewy.go. It initializes all subsystems including the registry client, cache, and notifier, then manages the deployment loop through methods like Start, Run, and RunContainer. The core handles OS signals for graceful shutdowns and coordinates rolling updates, keeping the main decision logic separate from implementation details like network I/O or container runtime specifics.

How does Dewy support different container runtimes?

Dewy abstracts container operations through the Runtime interface implemented in container/docker.go and container/podman.go. This interface standardizes lifecycle methods including Pull, Run, Stop, and health-check polling, allowing the core to treat Docker and Podman identically. Users specify their preferred runtime in the ContainerConfig, and Dewy instantiates the appropriate implementation via container.NewDocker or container.NewPodman, supporting rolling updates with zero downtime regardless of the underlying engine.

What caching mechanisms does Dewy use for artifacts?

Dewy implements caching through the KVS (Key-Value Store) interface defined in kvs/kvs.go, supporting multiple persistence backends. The system can store artifacts locally using the file backend, maintain ephemeral caches with memory, or distribute state using redis or consul. The cache tracks downloaded artifacts under versioned keys and maintains a current reference to the active deployment, enabling atomic rollbacks and preventing redundant network requests when the registry reports a version already present in storage.

How does Dewy achieve zero-downtime deployments for containers?

Dewy implements zero-downtime rolling updates through a combination of an in-process TCP reverse proxy and health-check orchestration. When deploying new container versions, Dewy starts new instances alongside existing ones, registers them with the TCP proxy via addProxyBackend, and performs health checks. Once new containers pass validation, Dewy removes old instances from the proxy via removeBackend and stops them, ensuring continuous traffic flow without requiring external load balancers.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →