Skip to content

Commit

Permalink
Write a Dockerfile that can build both entropy and server. (#430)
Browse files Browse the repository at this point in the history
* Write a Dockerfile that can build both `entropy` and `server`.

This commit satisfies the pre-requisite for building container images
from the source code herein inside a CI/CD pipeline (or, really, for any
other purpose we might need containers for), as described in #423. The
long and short of it is that we can use this to have container images
built of the current commit, or any commit that we want.

Since the code here depends on access to currently-private GitHub
repositories, we need to have set a GitHub Personal Access Token (PAT)
that can access the `entropyxyz/synedrion` and `entropyxyz/constraints`
repositories. This is expected to be part of the `entropy-workstation-setup`
[prerequisites](https://github.com/entropyxyz/entropy-workstation-setup#pre-requisites),
so do that first if you haven't yet.

The canonical place for such a token on a developer machine is
`~/.entropy.auth.sh`, so developers can create containers of the
`entropy` binary in a manner like so from their local workstation:

```shell
docker buildx build \
    --secret id=credentials,src=$HOME/.entropy.auth.sh \
    --tag entropy .
```

This assumes a line like the following exists in `~/.entropy.auth.sh`:

```shell
export GITHUB_TOKEN="ghp_xxxxxxxxxx" # Obviously, put a real PAT here.
```

You can also build arbitrary packages in the same environment by setting
the `PACKAGE` build argument:

```shell
docker buildx build --build-arg PACKAGE=server \
    --secret id=credentials,src=$HOME/.entropy.auth.sh \
    --tag server .
```

Additional build arguments provide some flexibility for the build
environment: `RUST_VERSION`, `DEBIAN_CODENAME`, and `ALPINE_VERSION`.

* Add clarifying comment on multi-stage builds.

Co-authored-by: Hernando Castano <[email protected]>

---------

Co-authored-by: Hernando Castano <[email protected]>
  • Loading branch information
vitropy and HCastano authored Oct 16, 2023
1 parent d4bce7c commit 012ea55
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
59 changes: 59 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# This file lists filesystem patterns to omit from the container
# build context. Omitting files from the build context speeds up
# the build by reducing the amount of files transferred by the
# container engine client to the image build server.
#
# See:
# https://docs.docker.com/build/building/context/#dockerignore-files

###
# Docker and container engine preparation/runtime stuff.
###
.dockerignore
docker-compose.yml

#################################
# General editor and IDE stuff. #
#################################
*.swp
.editorconfig

# Microsoft Visual Studio Code
.vscode
.devcontainer

##############################################
# Git, GitHub, CI/CD, and Rust system stuff. #
##############################################
.git
.github
.gitignore
.circleci
.rustfmt.toml
.taplo.toml
cliff.toml
CHANGELOG.md
LICENSE
README.md
Makefile
target

###
# Stuff generated during build or runtime.
###
.cargo
.cargo-remote.toml

# Our own generated stuff.
.entropy
chains
scripts
shell.nix
service

# No idea what this stuff is for but we don't seem to need it.
# TODO: Are these actually just temporary things that we can
# delete because they're no longer needed? Is it cruft?
.envrc
file_header.txt
local-share1.json
62 changes: 62 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Which Cargo package to build. This is also the binary name.
ARG PACKAGE=entropy
# Version of Rust to build with.
ARG RUST_VERSION=1.73.0
# Version of upstream Debian to build with.
ARG DEBIAN_CODENAME=bullseye
# Version of Alpine to deploy with.
ARG ALPINE_VERSION=3
# Whether or not to `strip(1)` the binaries. See:
# https://doc.rust-lang.org/rustc/codegen-options/index.html#strip
ARG STRIP=symbols

FROM --platform=linux/amd64 rust:${RUST_VERSION}-slim-${DEBIAN_CODENAME} as build
ARG PACKAGE
ARG ALPINE_VERSION
ARG STRIP

COPY ./ /usr/local/src
WORKDIR /usr/local/src
RUN --mount=type=secret,id=credentials,required=true apt-get update \
&& apt-get install --yes \
git pkg-config protobuf-compiler make libjemalloc2 clang \
openssl libssl-dev \
&& rustup target add wasm32-unknown-unknown \
&& $(grep 'export GITHUB_TOKEN' /run/secrets/credentials | cut -d '#' -f 1 | tr -d '"') \
&& git config --global \
url."https://entropyxyz:${GITHUB_TOKEN}@github.com/entropyxyz".insteadOf \
"ssh://[email protected]/entropyxyz" \
&& cargo rustc --release -p ${PACKAGE} -- \
-C target-feature=+crt-static \
-C strip=${STRIP} \
&& install target/release/${PACKAGE} /usr/local/bin

# Second stage containing just the built binary and no other build dependencies
FROM --platform=linux/amd64 alpine:${ALPINE_VERSION}
ARG PACKAGE
ENV binary $PACKAGE

WORKDIR /srv/entropy
RUN addgroup --system entropy \
&& adduser --system \
--disabled-password \
--no-create-home \
--home /srv/entropy \
entropy \
&& chown -R entropy:entropy /srv/entropy

COPY --from=build --chown=entropy:entropy --chmod=554 /usr/local/bin/${PACKAGE} /usr/local/bin/${PACKAGE}
COPY --chown=entropy:entropy --chmod=554 bin/entrypoint.sh /usr/local/bin/entrypoint.sh
USER entropy

# Expose Substrate's default Prometheus endpoint.
EXPOSE 9615

# Expose Substrate's default RPC port.
EXPOSE 9944

# Expose Substrate's default P2P port.
EXPOSE 30333

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["--help"]
13 changes: 13 additions & 0 deletions bin/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh
###
# Container entrypoint script.
###

# Function main simply wraps execution of the binary set in the
# image's build environment. This makes it possible to use one
# Dockerfile and still ultimately run a few different bianries.
main () {
exec "/usr/local/bin/${binary}" "$@"
}

main "$@"

0 comments on commit 012ea55

Please sign in to comment.