# How to Deploy a Binary Application with Dewy: Complete Guide for Go and Compiled Binaries

> Deploy Go binaries with Dewy. Package your compiled executable, publish it to GitHub Releases, and run dewy server for a seamless deployment. Get the complete guide now.

- Repository: [Tomohisa Oda/dewy](https://github.com/linyows/dewy)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Deploy a binary application with Dewy by packaging your compiled executable as a `<name>_<os>_<arch>.tar.gz` archive, publishing it to a supported registry such as GitHub Releases, and running the `dewy server` command with your registry URL and binary path specified after the `--` separator.**

Dewy is an open-source deployment agent written in Go that automates the release management of binary applications. Whether you are deploying a Go microservice, a Rust CLI tool, or any compiled executable, Dewy handles polling for updates, atomic deployments, and graceful process restarts. This guide explains how to deploy a binary application with Dewy using the `server` command and the underlying implementation in the `linyows/dewy` repository.

## How Dewy Deploys Binary Applications

When you run the **`server`** command, Dewy treats your binary as a *server-type* application and executes a continuous deployment loop. The `Run` method in [`main/dewy.go`](https://github.com/linyows/dewy/blob/main/main/dewy.go) orchestrates this process by performing the following steps:

1. **Polls the registry** (GitHub Releases, S3, GCS, OCI, etc.) for the latest version using the `Current()` method defined in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go).
2. **Downloads the artifact** (your binary archive) and caches it in the local key-value store ([`kvs/file.go`](https://github.com/linyows/dewy/blob/main/kvs/file.go)).
3. **Extracts the archive** into a timestamped release directory under `./releases/`.
4. **Atomically updates the `current` symlink** to point to the new release using `os.Rename` in the `deploy` method.
5. **Starts or restarts the binary** via the supplied command line, using `github.com/linyows/server-starter` to manage the process lifecycle.

By default, Dewy retains the **7 most recent releases** (`keepReleases = 7` in [`dewy.go`](https://github.com/linyows/dewy/blob/main/dewy.go)), automatically cleaning up older versions to conserve disk space.

## Packaging Your Binary for Dewy

Dewy expects binary applications to follow a specific packaging convention. The artifact name must contain the target operating system and architecture, or you must explicitly specify the artifact name using registry options.

### Naming Convention

Package your binary using the format:

```bash
<app>_<os>_<arch>.tar.gz

```

For example, a Go binary built for Linux AMD64 should be named `myapp_linux_amd64.tar.gz`. Dewy automatically detects the current OS and architecture when polling the registry, selecting the appropriate artifact from the release.

### Archive Structure

The archive should contain the executable at the root level or within a predictable path. When Dewy extracts the archive to `./releases/<timestamp>/`, it creates a `current` symlink pointing to this directory. Your deployment command should reference the binary via this symlink path, such as `/opt/myapp/current/myapp`.

## Step-by-Step Deployment Guide

Follow these steps to deploy a binary application with Dewy from compilation to production execution.

### 1. Build and Package the Binary

Compile your Go application for the target platform and create a compressed archive:

```bash

# Build the binary

GOOS=linux GOARCH=amd64 go build -o myapp

# Package as tar.gz (Dewy expects this format)

tar -czf myapp_linux_amd64.tar.gz myapp

```

### 2. Publish to a Supported Registry

Upload the artifact to a registry that Dewy can poll. GitHub Releases is the most common choice:

```bash

# Create a release and upload the artifact

gh release create v1.0.0 myapp_linux_amd64.tar.gz \
  --title "v1.0.0" \
  --notes "Initial release"

```

Dewy supports multiple registry backends implemented in the `registry/` directory, including AWS S3 ([`s3.go`](https://github.com/linyows/dewy/blob/main/s3.go)), Google Cloud Storage ([`gcs.go`](https://github.com/linyows/dewy/blob/main/gcs.go)), and OCI registries.

### 3. Run the Dewy Server Command

Execute the `server` command to start the deployment agent. The command-line parsing logic in [`main/cli.go`](https://github.com/linyows/dewy/blob/main/main/cli.go) handles the `--registry` flag and the `--` separator that distinguishes Dewy options from your binary's command line.

```bash
dewy server \
  --registry ghr://myorg/myapp \
  --notifier slack://#deploys?title=myapp \
  -p 8080 \
  -l info \
  -- /opt/myapp/current/myapp

```

**Key parameters explained:**

- **`--registry ghr://myorg/myapp`**: Specifies the GitHub Releases registry endpoint.
- **`-p 8080`**: Defines the port for the server (optional, required only if your binary is an HTTP server that Dewy should proxy or monitor).
- **`--`**: Separator indicating the end of Dewy options and the start of the command to execute.
- **`/opt/myapp/current/myapp`**: Path to the binary via the `current` symlink that Dewy manages.

### 4. Configure Deployment Hooks (Optional)

Add `--before-deploy-hook` and `--after-deploy-hook` to execute custom scripts during the deployment lifecycle. The `execHook` function in [`dewy.go`](https://github.com/linyows/dewy/blob/main/dewy.go) runs these via `/bin/sh -c` and reports results to your notifier.

```bash
dewy server \
  --registry ghr://myorg/myapp \
  --before-deploy-hook "cp /opt/myapp/current/myapp /backup/myapp_$(date +%F_%T)" \
  --after-deploy-hook "/opt/myapp/current/myapp --migrate" \
  -- /opt/myapp/current/myapp

```

## Key Implementation Details

Understanding how Dewy manages binary deployments at the code level helps troubleshoot issues and optimize your configuration.

### Registry Polling and Version Detection

Dewy abstracts registry interactions through the `Registry` interface defined in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go). Each implementation (GitHub Releases in [`ghr.go`](https://github.com/linyows/dewy/blob/main/ghr.go), S3 in [`s3.go`](https://github.com/linyows/dewy/blob/main/s3.go)) provides a `Current()` method that returns a `CurrentResponse` containing the latest tag and artifact URL.

The polling interval and registry-specific options (such as `artifact=` to override the default naming pattern) are parsed in [`main/cli.go`](https://github.com/linyows/dewy/blob/main/main/cli.go) and passed to the registry driver.

### Atomic Release Switching

To ensure zero-downtime deployments, Dewy performs atomic updates using symlinks. The `deploy` method in [`main/dewy.go`](https://github.com/linyows/dewy/blob/main/main/dewy.go) (lines 32-55) extracts the new release into a timestamped directory under `./releases/`, creates a temporary symlink pointing to this directory, and then uses `os.Rename` to atomically replace the `current` symlink.

This approach ensures that the `current` path always points to a complete, valid release, preventing partial deployments from serving traffic.

### Process Management with Server Starter

Dewy leverages `github.com/linyows/server-starter` to manage the lifecycle of your binary application. The `startServer` and `restartServer` functions in [`main/dewy.go`](https://github.com/linyows/dewy/blob/main/main/dewy.go) handle process spawning and graceful restarts.

When a new version is detected and deployed, Dewy sends a `SIGHUP` signal to the running process (or starts it if not running), allowing the application to reload without dropping connections. The Admin API runs on `localhost:17539` by default, providing endpoints at `/api/status` and `/api/containers` for monitoring deployment state.

## Summary

Deploying binary applications with Dewy provides a robust, zero-downtime continuous deployment pipeline for compiled executables. Key takeaways include:

- **Package binaries** using the `<name>_<os>_<arch>.tar.gz` naming convention for automatic artifact detection.
- **Use the `server` command** to enable continuous polling, atomic deployments via symlinks, and automatic process restarts.
- **Reference the binary** via the `current` symlink path (e.g., `/opt/myapp/current/myapp`) in your command arguments after the `--` separator.
- **Configure hooks** using `--before-deploy-hook` and `--after-deploy-hook` to run custom logic during the deployment lifecycle.
- **Monitor deployments** through the Admin API on `localhost:17539` or configured notifiers like Slack.

## Frequently Asked Questions

### How does Dewy handle zero-downtime deployments for binary applications?

Dewy achieves zero-downtime deployments through **atomic symlink switching** and **graceful process restarts**. When a new version is detected, Dewy extracts the artifact into a timestamped directory and creates a temporary symlink pointing to it. The `deploy` method in [`main/dewy.go`](https://github.com/linyows/dewy/blob/main/main/dewy.go) then uses `os.Rename` to atomically replace the `current` symlink, ensuring the path always points to a complete release. The running binary is then gracefully restarted via `SIGHUP` using the `server-starter` library, allowing the application to reload without dropping active connections.

### What registry formats does Dewy support for binary artifacts?

Dewy supports multiple registry backends through its pluggable `Registry` interface defined in [`registry/registry.go`](https://github.com/linyows/dewy/blob/main/registry/registry.go). The built-in implementations include **GitHub Releases** ([`ghr.go`](https://github.com/linyows/dewy/blob/main/ghr.go)), **AWS S3** ([`s3.go`](https://github.com/linyows/dewy/blob/main/s3.go)), **Google Cloud Storage** ([`gcs.go`](https://github.com/linyows/dewy/blob/main/gcs.go)), and **OCI registries**. Each registry driver implements the `Current()` method, which returns the latest version tag and artifact URL. For GitHub Releases, use the format `ghr://owner/repo`, while S3 and GCS use their respective URL schemes with optional `artifact=` query parameters to override default naming patterns.

### How do I configure pre-deployment and post-deployment hooks?

You can configure custom scripts to run during the deployment lifecycle using the `--before-deploy-hook` and `--after-deploy-hook` flags when executing the `dewy server` command. These hooks are executed via `/bin/sh -c` by the `execHook` function in [`main/dewy.go`](https://github.com/linyows/dewy/blob/main/main/dewy.go), and their output is logged and sent to your configured notifier. For example, you can specify `--before-deploy-hook "cp /opt/app/current/binary /backup/binary_$(date +%F)"` to create backups before deployment, or `--after-deploy-hook "/opt/app/current/binary --migrate"` to run database migrations after the new version is activated.

### What is the purpose of the `--` separator in the Dewy server command?

The `--` separator in the `dewy server` command distinguishes between **Dewy's own command-line options** and the **command to execute your binary application**. Everything before `--` is parsed by the CLI handler in [`main/cli.go`](https://github.com/linyows/dewy/blob/main/main/cli.go) and configures Dewy's behavior (registry URL, notifiers, ports, hooks). Everything after `--` is treated as the literal command line to start your binary, typically referencing the `current` symlink path such as `/opt/myapp/current/myapp`. This separation ensures that flags intended for your application (like `-port` or `-config`) are not intercepted by Dewy's flag parser.