Skip to content

alienplatform/dockdash

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

10 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

dockdash

Build and push Docker images from Rust πŸ¦€ β€” without Docker installed.

crates.io docs.rs CI License


Dockdash is a Rust library for building and pushing Docker (OCI) images β€” no Docker daemon, no docker CLI, no privileged containers. Just a normal Rust crate that produces real container images and ships them to any registry.

It's fast enough to run inside a serverless function: build an image in a Lambda, push it to ECR, and exit before your cold start budget runs out.

Why Dockdash?

  • πŸ”₯ Blazingly fast β€” native Rust, zstd layer compression, and content-addressable blob caching. Builds images in milliseconds, not seconds.
  • ☁️ Runs anywhere β€” serverless functions, sandboxed CI, edge runtimes, CLIs. If Rust runs there, Dockdash works there.
  • 🐳 No Docker required β€” no daemon, no socket, no root. Just a library call.
  • 🧱 Simple API β€” a builder pattern for layers and images. No Dockerfiles, no shelling out.
  • 🌍 Multi-arch β€” build for amd64, arm64, and any other platform you need.
  • πŸ“¦ Push to any OCI registry β€” Docker Hub, ECR, GCR, ACR, GHCR, or your own. Anonymous, basic auth, and token auth supported.
  • ⚑ Incremental builds β€” local content-addressable cache means unchanged layers are reused instantly.

Quick Start

Add to your Cargo.toml:

[dependencies]
dockdash = "0.2"
tokio = { version = "1", features = ["full"] }

Build and push an image:

use dockdash::{Arch, Image, Layer, PushOptions, Result};
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<()> {
    // Create a layer from a local binary
    let layer = Layer::builder()?
        .file("./target/release/my-app", "./my-app", Some(0o755))?
        .build()
        .await?;

    // Build the OCI image
    let (image, _) = Image::builder()
        .from("ubuntu:latest")
        .platform("linux", &Arch::ARM64)
        .layer(layer)
        .entrypoint(vec!["/my-app".to_string()])
        .output_to(PathBuf::from("image.oci.tar"))
        .build()
        .await?;

    // Push to a registry
    image.push("my-registry.com/my-app:latest", &PushOptions::default()).await?;

    Ok(())
}

Features

Layer Builder

Create layers from files or raw data:

// From a file on disk
let layer = Layer::builder()?
    .file("./my-binary", "./app/my-binary", Some(0o755))?
    .build()
    .await?;

// From raw bytes
let layer = Layer::builder()?
    .data("./app/config.toml", config_bytes, None)?
    .build()
    .await?;

// Multiple files in one layer
let layer = Layer::builder()?
    .file("./binary", "./app/binary", Some(0o755))?
    .file("./config.toml", "./app/config.toml", None)?
    .data("./app/version.txt", b"1.0.0", None)?
    .build()
    .await?;

Image Builder

Compose images from a base and custom layers:

let (image, diagnostics) = Image::builder()
    .from("alpine:3.19")
    .platform("linux", &Arch::Amd64)
    .layer(app_layer)
    .layer(config_layer)
    .entrypoint(vec!["/app/server".to_string()])
    .working_dir("/app")
    .build()
    .await?;

Blob Caching

Speed up repeated builds with content-addressable caching:

use dockdash::BlobCache;

// Default location: ~/.dockdash/cache/blobs
let cache = BlobCache::new()?;

// Or use a custom cache directory (path is used as-is)
let cache = BlobCache::with_path("/my/custom/cache".into())?;

let layer = Layer::builder()?
    .blob_cache(cache.clone())
    .file("./my-binary", "./app/my-binary", Some(0o755))?
    .build()
    .await?;

let (image, _) = Image::builder()
    .from("alpine:latest")
    .blob_cache(cache)
    .layer(layer)
    .build()
    .await?;

Registry Authentication

use dockdash::{RegistryAuth, PushOptions, ClientProtocol};

// Anonymous (e.g., ttl.sh)
let opts = PushOptions::default();

// Basic auth
let opts = PushOptions {
    auth: RegistryAuth::Basic("user".into(), "pass".into()),
    ..Default::default()
};

// HTTP (for local registries)
let opts = PushOptions {
    protocol: ClientProtocol::Http,
    ..Default::default()
};

Use Cases

  • Serverless functions β€” build and push images from Lambda, Cloud Run, Vercel, or Cloudflare Workers, in milliseconds.
  • CI/CD pipelines β€” ship container images without Docker-in-Docker, root, or privileged runners.
  • Deployment platforms β€” bake user code into images on the fly as part of your build/deploy pipeline.
  • CLI tools β€” embed container image building directly into your Rust CLI, no external dependencies.
  • Edge & embedded β€” build images on resource-constrained devices where Docker simply isn't an option.

Testing

# Unit tests
cargo test

# Integration tests (requires Docker for Bollard-based tests)
cargo test --features test-utils

License

Licensed under the Apache License, Version 2.0.

About

Build and push Docker images from Rust without Docker installed

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages