Skip to content

Commit

Permalink
feat: dockerize iroh services (#494)
Browse files Browse the repository at this point in the history
  • Loading branch information
b5 authored Nov 15, 2022
1 parent 804255c commit f8af48a
Show file tree
Hide file tree
Showing 8 changed files with 289 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
**/target*
# ignore edits to dockerfiles so they don't invalidate cache
# dockerfiles shouldn't be in the build image anyway
**/docker/Dockerfile*
7 changes: 7 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,11 @@ inherits = 'release'
lto = true
panic = 'abort'
incremental = false
codegen-units = 8

[profile.docker]
inherits = 'release'
lto = true
panic = 'abort'
incremental = false
codegen-units = 8
46 changes: 46 additions & 0 deletions docker/Dockerfile.iroh-gateway
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
################################################################################
## Builder
################################################################################
FROM rust:latest AS builder

RUN update-ca-certificates

# install latest protocol buffer compiler.
ARG TARGETPLATFORM
COPY ../docker/install_protoc.sh .
RUN ./install_protoc.sh

# set build env vars
ENV RUST_BACKTRACE=1 \
PROTOC=/usr/local/bin/protoc \
PROTOC_INCLUDE=/usr/local/include

# has the side effect of updating the crates.io index & installing rust toolchain
# called in a separate step for nicer caching. the command itself will fail,
# b/c empty-library is not a dependency, so we override with an exit code 0
RUN cargo install empty-library; exit 0

WORKDIR /iroh

COPY ../ .

RUN cargo build --bin iroh-gateway --profile=docker

################################################################################
## Final image
################################################################################
FROM gcr.io/distroless/cc

WORKDIR /iroh

# Copy our build, changing owndership to distroless-provided "nonroot" user,
# (65532:65532)
COPY --from=builder --chown=65532:65532 /iroh/target/docker/iroh-gateway ./

# Use nonroot (unprivileged) user
USER nonroot

# expose the default RPC port and default gateway HTTP port
EXPOSE 4400 9050

CMD ["/iroh/iroh-gateway"]
52 changes: 52 additions & 0 deletions docker/Dockerfile.iroh-one
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
################################################################################
## Builder
################################################################################
# FROM --platform=linux/amd64 rust:latest AS builder
FROM rust:latest AS builder

RUN update-ca-certificates

# rocksDB needs libclang
RUN apt-get update && \
apt-get install -y \
clang libclang-dev

# install latest protocol buffer compiler.
ARG TARGETPLATFORM
COPY ../docker/install_protoc.sh .
RUN ./install_protoc.sh

# set build env vars
ENV RUST_BACKTRACE=1 \
PROTOC=/usr/local/bin/protoc \
PROTOC_INCLUDE=/usr/local/include

# has the side effect of updating the crates.io index & installing rust toolchain
# called in a separate step for nicer caching. the command itself will fail,
# b/c empty-library is not a dependency, so we override with an exit code 0
RUN cargo install empty-library; exit 0

WORKDIR /iroh

COPY ../ .

RUN cargo build --bin iroh-one --profile=docker

################################################################################
## Final image
################################################################################
FROM gcr.io/distroless/cc

WORKDIR /iroh

# Copy our build, changing owndership to distroless-provided "nonroot" user,
# (65532:65532)
COPY --from=builder --chown=65532:65532 /iroh/target/docker/iroh-one ./

# Use nonroot (unprivileged) user
USER nonroot

# expose gateway, p2p & all default RPC ports
EXPOSE 4400 4401 4402 4403 4444 9050

CMD ["/iroh/iroh-one"]
53 changes: 53 additions & 0 deletions docker/Dockerfile.iroh-p2p
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
################################################################################
## Builder
################################################################################
FROM rust:latest AS builder

RUN update-ca-certificates

# install latest protocol buffer compiler.
ARG TARGETPLATFORM
COPY ../docker/install_protoc.sh .
RUN ./install_protoc.sh

# set build env vars
ENV RUST_BACKTRACE=1 \
PROTOC=/usr/local/bin/protoc \
PROTOC_INCLUDE=/usr/local/include

# has the side effect of updating the crates.io index & installing rust toolchain
# called in a separate step for nicer caching. the command itself will fail,
# b/c empty-library is not a dependency, so we override with an exit code 0
RUN cargo install empty-library; exit 0

WORKDIR /iroh

COPY ../ .

RUN cargo build --bin iroh-p2p --profile=docker

################################################################################
## Final image
################################################################################
FROM gcr.io/distroless/cc

WORKDIR /iroh

# Copy our build, changing owndership to distroless-provided "nonroot" user,
# (65532:65532)
COPY --from=builder --chown=65532:65532 /iroh/target/docker/iroh-p2p ./

# TODO (b5) - investigate max file descriptor limits within the container image
# libp2p needs lots of FDs for open ports, and we should be maxing them out.
# I have no idea if distroless honors ERL_MAX_PORTS, consider this a starting
# point for experimentation
# ENV ERL_MAX_PORTS=65536

# Use nonroot (unprivileged) user
USER nonroot

# expose the default RPC port
EXPOSE 4401 4444
EXPOSE 4444/udp

CMD ["/iroh/iroh-p2p"]
51 changes: 51 additions & 0 deletions docker/Dockerfile.iroh-store
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
################################################################################
## Builder
################################################################################
FROM rust:latest AS builder

RUN update-ca-certificates

# rocksDB needs libclang
RUN apt-get update && \
apt-get install -y \
clang libclang-dev

# install latest protocol buffer compiler.
ARG TARGETPLATFORM
COPY ../docker/install_protoc.sh .
RUN ./install_protoc.sh

# set build env vars
ENV RUST_BACKTRACE=1 \
PROTOC=/usr/local/bin/protoc \
PROTOC_INCLUDE=/usr/local/include

# has the side effect of updating the crates.io index & installing rust toolchain
# called in a separate step for nicer caching. the command itself will fail,
# b/c empty-library is not a dependency, so we override with an exit code 0
RUN cargo install empty-library; exit 0

WORKDIR /iroh

COPY ../ .

RUN cargo build --bin iroh-store --profile=docker

################################################################################
## Final image
################################################################################
FROM gcr.io/distroless/cc

WORKDIR /iroh

# Copy our build, changing owndership to distroless-provided "nonroot" user,
# (65532:65532)
COPY --from=builder --chown=65532:65532 /iroh/target/docker/iroh-store ./

# Use nonroot (unprivileged) user
USER nonroot

# expose the default RPC port
EXPOSE 4402

CMD ["/iroh/iroh-store"]
14 changes: 14 additions & 0 deletions docker/install_protoc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# install latest protocol buffer compiler. Yes, it's really this irritating.
# recent build URLs are missing "3" version prefix. version is actually "3.21.9"
PROTOC_VERSION=21.9
case ${TARGETPLATFORM} in
"linux/amd64") PROTOC_ZIP=protoc-21.9-linux-x86_64.zip ;;
"linux/arm64") PROTOC_ZIP=protoc-21.9-linux-aarch_64.zip ;;
*) exit 1
esac

curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOC_VERSION/$PROTOC_ZIP
unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP
echo "installed $($PROTOC --version)"
62 changes: 62 additions & 0 deletions xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{
env, fs, io,
path::{Path, PathBuf},
process::Command,
str,
};

#[derive(Debug, Parser)]
Expand All @@ -26,6 +27,15 @@ enum Commands {
#[clap(short, long)]
build: bool,
},
#[command(about = "build docker images")]
Docker {
#[clap(short, long)]
all: bool,
/// Set type of progress output (auto, plain, tty). Use plain to show container output (default "auto")
#[clap(short, long, default_value_t = String::from("auto"))]
progress: String,
images: Vec<String>,
},
}

fn main() {
Expand All @@ -41,6 +51,11 @@ fn run_subcommand(args: Cli) -> Result<()> {
Commands::Dist {} => dist()?,
Commands::Man {} => dist_manpage()?,
Commands::DevInstall { build } => dev_install(build)?,
Commands::Docker {
all,
images,
progress,
} => build_docker(all, images, progress)?,
}
Ok(())
}
Expand Down Expand Up @@ -130,3 +145,50 @@ fn project_root() -> PathBuf {
fn dist_dir() -> PathBuf {
project_root().join("target/dist")
}

fn build_docker(all: bool, build_images: Vec<String>, progress: String) -> Result<()> {
let mut images = build_images;
if all {
images = vec![
String::from("iroh-one"),
String::from("iroh-store"),
String::from("iroh-p2p"),
String::from("iroh-gateway"),
];
}

let commit = current_git_commit()?;

for image in images {
println!("building {}:{}", image, commit);
let status = Command::new("docker")
.current_dir(project_root())
.args([
"build",
"-t",
format!("n0computer/{}:{}", image, commit).as_str(),
"-t",
format!("n0computer/{}:latest", image).as_str(),
"-f",
format!("docker/Dockerfile.{}", image).as_str(),
format!("--progress={}", progress).as_str(),
".",
])
.status()?;

if !status.success() {
Err(anyhow::anyhow!("cargo build failed"))?;
}
}

Ok(())
}

fn current_git_commit() -> Result<String> {
let output = Command::new("git")
.current_dir(project_root())
.args(["log", "-1", "--pretty=%h"])
.output()?;
let commitish = str::from_utf8(&output.stdout)?.trim_end();
Ok(String::from(commitish))
}

0 comments on commit f8af48a

Please sign in to comment.