Demo multi-stage Docker containers
This commit is contained in:
parent
372d547138
commit
ac72ab16ab
24
Dockerfile.multistage-example
Normal file
24
Dockerfile.multistage-example
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# -*- mode: dockerfile -*-
|
||||||
|
#
|
||||||
|
# An example Dockerfile showing how to build a Rust executable using this
|
||||||
|
# image, and deploy it with a tiny Alpine Linux container.
|
||||||
|
|
||||||
|
# Our first FROM statement declares the build environment.
|
||||||
|
FROM ekidd/rust-musl-builder AS builder
|
||||||
|
|
||||||
|
# You would normally add your source code to /home/rust/src like this.
|
||||||
|
# ADD . ./
|
||||||
|
|
||||||
|
# ...but we're going to just create a new app instead for demo purposes.
|
||||||
|
RUN cd .. && rm -r src && USER=rust cargo new --vcs none --bin --name hello src
|
||||||
|
|
||||||
|
# Build our application.
|
||||||
|
RUN cargo build --release
|
||||||
|
|
||||||
|
# Now, we need to build our _real_ Docker container, copying in `hello`.
|
||||||
|
FROM alpine:latest
|
||||||
|
RUN apk --no-cache add ca-certificates
|
||||||
|
COPY --from=builder \
|
||||||
|
/home/rust/src/target/x86_64-unknown-linux-musl/release/hello \
|
||||||
|
/usr/local/bin/
|
||||||
|
CMD /usr/local/bin/hello
|
68
README.md
68
README.md
|
@ -18,11 +18,7 @@ making final release builds.
|
||||||
|
|
||||||
## Deploying your Rust application
|
## Deploying your Rust application
|
||||||
|
|
||||||
With a bit of luck, you should be able to just copy your application binary
|
With a bit of luck, you should be able to just copy your application binary from `target/x86_64-unknown-linux-musl/release`, and install it directly on any reasonably modern x86_64 Linux machine. In particular, you should be able make static release binaries using TravisCI and GitHub, or you can copy your Rust application into an [Alpine Linux container][]. See below for details!
|
||||||
from `target/x86_64-unknown-linux-musl/release`, and install it directly on
|
|
||||||
any reasonably modern x86_64 Linux machine. In particular, you should be
|
|
||||||
able to copy your Rust application into an
|
|
||||||
[Alpine Linux container][].
|
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
|
|
||||||
|
@ -50,32 +46,6 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Adding more C libraries
|
|
||||||
|
|
||||||
If you're using Docker crates which require specific C libraries to be
|
|
||||||
installed, you can create a Dockerfile based on this one, and use
|
|
||||||
`musl-gcc` to compile the libraries you need. For example:
|
|
||||||
|
|
||||||
```Dockerfile
|
|
||||||
FROM ekidd/rust-musl-builder
|
|
||||||
|
|
||||||
# EXAMPLE ONLY! libz is already included.
|
|
||||||
RUN VERS=1.2.11 && \
|
|
||||||
cd /home/rust/libs && \
|
|
||||||
curl -LO http://zlib.net/zlib-$VERS.tar.gz && \
|
|
||||||
tar xzf zlib-$VERS.tar.gz && cd zlib-$VERS && \
|
|
||||||
CC=musl-gcc ./configure --static --prefix=/usr/local/musl && \
|
|
||||||
make && sudo make install && \
|
|
||||||
cd .. && rm -rf zlib-$VERS.tar.gz zlib-$VERS
|
|
||||||
```
|
|
||||||
|
|
||||||
This usually involves a bit of experimentation for each new library, but it
|
|
||||||
seems to work well for most simple, standalone libraries.
|
|
||||||
|
|
||||||
If you need an especially common library, please feel free to submit a pull
|
|
||||||
request adding it to the main `Dockerfile`! We'd like to support popular
|
|
||||||
Rust crates out of the box.
|
|
||||||
|
|
||||||
## Making static releases with Travis CI and GitHub
|
## Making static releases with Travis CI and GitHub
|
||||||
|
|
||||||
These instructions are inspired by [rust-cross][].
|
These instructions are inspired by [rust-cross][].
|
||||||
|
@ -122,6 +92,42 @@ For a working example, see [faradayio/cage][cage].
|
||||||
[uploading]: https://docs.travis-ci.com/user/deployment/releases
|
[uploading]: https://docs.travis-ci.com/user/deployment/releases
|
||||||
[cage]: https://github.com/faradayio/cage
|
[cage]: https://github.com/faradayio/cage
|
||||||
|
|
||||||
|
## Making tiny Docker images with Alpine Linux and Rust binaries
|
||||||
|
|
||||||
|
Docker now supports [multistage builds][multistage], which make it easy to
|
||||||
|
build your Rust application with `rust-musl-builder` and deploy it using
|
||||||
|
[Alpine Linux][]. For a working example, see
|
||||||
|
[`Dockerfile.multistage-example`](./Dockerfile.multistage-example).
|
||||||
|
|
||||||
|
[multistage]: https://docs.docker.com/engine/userguide/eng-image/multistage-build/
|
||||||
|
[Alpine Linux]: https://alpinelinux.org/
|
||||||
|
|
||||||
|
## Adding more C libraries
|
||||||
|
|
||||||
|
If you're using Docker crates which require specific C libraries to be
|
||||||
|
installed, you can create a `Dockerfile` based on this one, and use
|
||||||
|
`musl-gcc` to compile the libraries you need. For example:
|
||||||
|
|
||||||
|
```Dockerfile
|
||||||
|
FROM ekidd/rust-musl-builder
|
||||||
|
|
||||||
|
# EXAMPLE ONLY! libz is already included.
|
||||||
|
RUN VERS=1.2.11 && \
|
||||||
|
cd /home/rust/libs && \
|
||||||
|
curl -LO http://zlib.net/zlib-$VERS.tar.gz && \
|
||||||
|
tar xzf zlib-$VERS.tar.gz && cd zlib-$VERS && \
|
||||||
|
CC=musl-gcc ./configure --static --prefix=/usr/local/musl && \
|
||||||
|
make && sudo make install && \
|
||||||
|
cd .. && rm -rf zlib-$VERS.tar.gz zlib-$VERS
|
||||||
|
```
|
||||||
|
|
||||||
|
This usually involves a bit of experimentation for each new library, but it
|
||||||
|
seems to work well for most simple, standalone libraries.
|
||||||
|
|
||||||
|
If you need an especially common library, please feel free to submit a pull
|
||||||
|
request adding it to the main `Dockerfile`! We'd like to support popular
|
||||||
|
Rust crates out of the box.
|
||||||
|
|
||||||
## Development notes
|
## Development notes
|
||||||
|
|
||||||
After modifying the image, run `./test-image` to make sure that everything
|
After modifying the image, run `./test-image` to make sure that everything
|
||||||
|
|
|
@ -9,6 +9,10 @@ docker build -t ekidd/rust-musl-builder .
|
||||||
# Make sure we can build our example derived container.
|
# Make sure we can build our example derived container.
|
||||||
docker build -t rust-musl-zlib -f Dockerfile.example .
|
docker build -t rust-musl-zlib -f Dockerfile.example .
|
||||||
|
|
||||||
|
# Make sure we can build a multi-stage container.
|
||||||
|
docker build -t rust-multistage-example -f Dockerfile.multistage-example .
|
||||||
|
docker run --rm rust-multistage-example
|
||||||
|
|
||||||
# Make sure we can build a static executable.
|
# Make sure we can build a static executable.
|
||||||
docker run --rm ekidd/rust-musl-builder bash -c "
|
docker run --rm ekidd/rust-musl-builder bash -c "
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
Loading…
Reference in a new issue