Skip the Build: Deploying Binaries Directly with Nomad Artifacts
Deploy binaries directly from URLs with Nomad's artifact stanza, skipping container image rebuilds entirely. A working example and key trade-offs included.
11 Nov 2025, 23:01 UTC

The Problem: Slow Builds for Simple Binaries
When deploying a simple Go or Rust binary to a container, you often bake it into a Docker image. This means rebuilding and repushing the image every time you update the binary—a slow, resource-intensive process for something as simple as a single executable file.
Thesis: Nomad's Artifact Stanza Eliminates Image Baking
Nomad's artifact stanza downloads files directly to the client node during allocation, before the task starts. This means you can execute a binary without ever building a container image containing it.
How It Works: The Artifact Lifecycle
The artifact download happens in three stages:
- Pre-allocation fetch: Nomad client downloads the file to a local cache directory.
- Extraction (optional): If the artifact is a
.tar.gzor.zip, Nomad can extract it automatically. - Task execution: The downloaded file is available at the path you specify, ready for your task to execute.
Worked Example: Deploying a Binary Without a Dockerfile
Here's a minimal Nomad job that downloads a binary from a public URL and executes it:
job "web-server" {
datacenters = ["dc1"]
type = "service"
group "app" {
task "server" {
driver = "docker"
config {
image = "alpine:latest"
command = "/local/bin/server"
}
artifact {
source = "https://example.com/builds/myserver-linux-amd64"
destination = "local/bin"
options = {
mode = "file"
}
}
env {
PORT = "8080"
}
exposed_port {
port = "http"
}
}
}
}
Key points:
sourcecan be HTTP, HTTPS, S3, GCS, or Git URLs.destinationuseslocal/bin, which maps to the task'slocaldirectory in the Docker container.options.mode = "file"tells Nomad to download as a single file; use"dir"for archives.
Cache Behavior and Performance
Nomad caches artifacts locally on each client node. If you redeploy the same artifact, Nomad skips the download and reuses the cached copy. This reduces network traffic and speeds up allocations.
To verify caching works, run nomad alloc status <alloc-id> and look for the artifact section. You should see downloaded_at populated without a recent fetch_time for repeated allocations.
Trade-offs and Limitations
While artifacts simplify deployment, they come with constraints:
- Disk usage: Each client maintains a cache. Monitor
nomad client stateto check cache size and evict old entries if needed. - Network dependency: Allocations fail if the artifact source is unreachable. Use versioned URLs (e.g., S3 version IDs or Git refs) to avoid unexpected changes.
- Security: HTTP sources without TLS are unsupported. Ensure your artifact URLs use HTTPS or properly configured S3/GCS buckets.
Actionable Next Steps
To try this yourself:
- Start a local Nomad dev cluster:
nomad dev serverandnomad dev agent. - Host a test binary on a public URL (e.g., GitHub Releases or a signed S3 bucket).
- Create a job file using the example above, pointing to your binary.
- Run
nomad run job.hcland verify the allocation succeeds withnomad alloc status.
If the allocation fails, check /var/log/nomad/client.log on the client node for artifact download errors.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.