mirror of https://github.com/linkerd/linkerd2.git
Remove proxy/Dockerfile-deps (#279)
The current proxy Dockerfile configuration does not cache dependencies well, which can increase build times substantially. By carefully splitting proxy/Dockerfile into several stages that mock parts of the project, dependencies may be built and cached in Docker such that changes to the proxy only require building the conduit-proxy crate. Furthermore, proxy/Dockerfile now runs the proxy's tests before producing an artifact, unless the ` PROXY_SKIP_TESTS` build-arg is set and not-empty. The `PROXY_UNOPTIMIZED` build-arg has been added to support quicker, debug-friendly builds.
This commit is contained in:
parent
185f48b086
commit
6a0936e699
|
@ -65,9 +65,6 @@ jobs:
|
|||
for f in $( grep -lR --include=Dockerfile\* go-deps: . ) ; do
|
||||
validate_go_deps_tag $f
|
||||
done
|
||||
for f in $( grep -lR --include=Dockerfile\* proxy-deps: . ) ; do
|
||||
validate_proxy_deps_tag $f
|
||||
done
|
||||
)
|
||||
|
||||
# Push container images to Google Container Registry.
|
||||
|
@ -123,10 +120,11 @@ jobs:
|
|||
- |
|
||||
export CONDUIT_TAG=$(. bin/_tag.sh ; clean_head_root_tag)
|
||||
echo "CONDUIT_TAG=${CONDUIT_TAG}"
|
||||
- export PROXY_RELEASE=1 BUILD_DEBUG=1 DOCKER_TRACE=1
|
||||
- export BUILD_DEBUG=1 DOCKER_TRACE=1
|
||||
|
||||
script:
|
||||
- bin/docker-build
|
||||
# Tests are run in the `test` stage, se-running them here would be redundant/slow. #280
|
||||
- SKIP_TESTS=1 bin/docker-build
|
||||
|
||||
after_success:
|
||||
- bin/docker-push-deps
|
||||
|
|
33
BUILD.md
33
BUILD.md
|
@ -327,6 +327,23 @@ To connect to a live `proxy-api` at `localhost:8086`:
|
|||
bin/go-run controller/cmd/proxy-api
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
The `bin/docker-build-proxy` script builds the proxy:
|
||||
|
||||
```bash
|
||||
DOCKER_TRACE=1 PROXY_UNOPTIMIZED=1 PROXY_SKIP_TESTS=1 bin/docker-build-proxy
|
||||
```
|
||||
|
||||
It supports two environment variables:
|
||||
|
||||
- `PROXY_UNOPTIMIZED` -- When set and non-empty, produces unoptimized build artifacts,
|
||||
which reduces build times at the expense of runtime performance. Changing this will
|
||||
likely invalidate a substantial portion of Docker's cache.
|
||||
- `PROXY_SKIP_TESTS` -- When set and non-empty, prevents the proxy's tests from being run
|
||||
during the build. Changing this setting will not invalidate Docker's cache.
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
```bash
|
||||
|
@ -353,12 +370,7 @@ hard-coded SHA's:
|
|||
- [`Gopkg.lock`](Gopkg.lock)
|
||||
- [`Dockerfile-go-deps`](Dockerfile-go-deps)
|
||||
|
||||
`gcr.io/runconduit/proxy-deps` depends on
|
||||
- [`Cargo.lock`](Cargo.lock)
|
||||
- [`proxy/Dockerfile-deps`](proxy/Dockerfile-deps)
|
||||
|
||||
The `bin/update-proxy-deps-shas` and `bin/update-go-deps-shas` must be run when their
|
||||
respective dependencies change.
|
||||
`bin/update-go-deps-shas` must be run when go dependencies change.
|
||||
|
||||
# Build Architecture
|
||||
|
||||
|
@ -376,7 +388,6 @@ build_architecture
|
|||
"cli/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||
"cli/Dockerfile-bin" [color=lightblue, style=filled, shape=rect];
|
||||
"proxy/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||
"proxy/Dockerfile-deps" [color=lightblue, style=filled, shape=rect];
|
||||
"proxy-init/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||
"proxy-init/integration-test/iptables/Dockerfile-tester" [color=lightblue, style=filled, shape=rect];
|
||||
"web/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||
|
@ -422,13 +433,8 @@ build_architecture
|
|||
"docker-build-proxy" -> "_docker.sh";
|
||||
"docker-build-proxy" -> "_tag.sh";
|
||||
"docker-build-proxy" -> "docker-build-base";
|
||||
"docker-build-proxy" -> "docker-build-go-deps";
|
||||
"docker-build-proxy" -> "proxy/Dockerfile";
|
||||
|
||||
"docker-build-proxy-deps" -> "_docker.sh";
|
||||
"docker-build-proxy-deps" -> "_tag.sh";
|
||||
"docker-build-proxy-deps" -> "proxy/Dockerfile-deps";
|
||||
|
||||
"docker-build-proxy-init" -> "_docker.sh";
|
||||
"docker-build-proxy-init" -> "_tag.sh";
|
||||
"docker-build-proxy-init" -> "docker-build-base";
|
||||
|
@ -483,9 +489,6 @@ build_architecture
|
|||
"update-go-deps-shas" -> "controller/Dockerfile";
|
||||
"update-go-deps-shas" -> "proxy-init/Dockerfile";
|
||||
"update-go-deps-shas" -> "web/Dockerfile";
|
||||
|
||||
"update-proxy-deps-shas" -> "_tag.sh";
|
||||
"update-proxy-deps-shas" -> "proxy/Dockerfile";
|
||||
}
|
||||
build_architecture
|
||||
</details>
|
||||
|
|
11
bin/_tag.sh
11
bin/_tag.sh
|
@ -6,10 +6,6 @@ git_sha_head() {
|
|||
git rev-parse --short=8 HEAD
|
||||
}
|
||||
|
||||
proxy_deps_sha() {
|
||||
cat Cargo.lock proxy/Dockerfile-deps | shasum - | awk '{print $1}' |cut -c 1-8
|
||||
}
|
||||
|
||||
go_deps_sha() {
|
||||
cat Gopkg.lock Dockerfile-go-deps | shasum - | awk '{print $1}' |cut -c 1-8
|
||||
}
|
||||
|
@ -66,14 +62,9 @@ validate_tag() {
|
|||
# These functions should be called by any docker-build-* script that relies on
|
||||
# Go or Rust dependencies. To confirm the set of scripts that should call this
|
||||
# function, run:
|
||||
# $ grep -ER 'docker-build-(go|proxy)-deps' .
|
||||
# $ grep -ER 'docker-build-go-deps' .
|
||||
|
||||
validate_go_deps_tag() {
|
||||
file="$1"
|
||||
validate_tag "$file" "gcr.io/runconduit/go-deps" "$(go_deps_sha)"
|
||||
}
|
||||
|
||||
validate_proxy_deps_tag() {
|
||||
file="$1"
|
||||
validate_tag "$file" "gcr.io/runconduit/proxy-deps" "$(proxy_deps_sha)"
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ fi
|
|||
|
||||
bin/docker-build-controller
|
||||
bin/docker-build-web
|
||||
bin/docker-build-proxy
|
||||
bin/docker-build-proxy-init
|
||||
bin/docker-build-cli
|
||||
|
||||
bin/docker-build-proxy
|
||||
|
|
|
@ -10,13 +10,6 @@ fi
|
|||
. bin/_docker.sh
|
||||
. bin/_tag.sh
|
||||
|
||||
dockerfile=proxy/Dockerfile
|
||||
|
||||
validate_proxy_deps_tag $dockerfile
|
||||
|
||||
(
|
||||
bin/docker-build-base
|
||||
bin/docker-build-proxy-deps
|
||||
) >/dev/null
|
||||
|
||||
docker_build proxy "$(head_root_tag)" $dockerfile --build-arg="RELEASE=${PROXY_RELEASE:-1}"
|
||||
docker_build proxy "$(head_root_tag)" proxy/Dockerfile \
|
||||
--build-arg="PROXY_SKIP_TESTS=${PROXY_SKIP_TESTS:-}" \
|
||||
--build-arg="PROXY_UNOPTIMIZED=${PROXY_UNOPTIMIZED:-}"
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Builds (or pulls) our proxy-deps docker image.
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
echo "no arguments allowed for $(basename $0), given: $@" >&2
|
||||
exit 64
|
||||
fi
|
||||
|
||||
. bin/_docker.sh
|
||||
. bin/_tag.sh
|
||||
|
||||
tag=$(proxy_deps_sha)
|
||||
|
||||
if (docker_pull proxy-deps "${tag}"); then
|
||||
echo "$(docker_repo proxy-deps):${tag}"
|
||||
else
|
||||
docker_build proxy-deps "${tag}" proxy/Dockerfile-deps
|
||||
fi
|
|
@ -22,4 +22,3 @@ docker_image cli "${tag}"
|
|||
docker_image cli-bin "${tag}"
|
||||
|
||||
docker_image go-deps "$(go_deps_sha)"
|
||||
docker_image proxy-deps "$(proxy_deps_sha)"
|
||||
|
|
|
@ -7,4 +7,3 @@ set -eu
|
|||
|
||||
docker_pull base 2017-10-30.01 || true
|
||||
docker_pull go-deps "$(go_deps_sha)" || true
|
||||
docker_pull proxy-deps "$(proxy_deps_sha)" || true
|
||||
|
|
|
@ -7,4 +7,3 @@ set -eu
|
|||
|
||||
docker_push base 2017-10-30.01
|
||||
docker_push go-deps "$(go_deps_sha)"
|
||||
docker_push proxy-deps "$(proxy_deps_sha)"
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
# Updates the tag for `runconduit/proxy-deps` across all Dockerfiles in this repository.
|
||||
|
||||
sha=$(. bin/_tag.sh ; proxy_deps_sha)
|
||||
|
||||
for f in $( grep -lR --include=Dockerfile\* proxy-deps: . ) ; do
|
||||
sed -E -i.bak -e "s|runconduit/proxy-deps:[^ ]+|runconduit/proxy-deps:${sha}|" "$f"
|
||||
rm "$f".bak
|
||||
done
|
|
@ -1,24 +1,74 @@
|
|||
# Proxy build and runtime
|
||||
#
|
||||
# Builds a slim runtime image with the conduit-proxy binary.
|
||||
|
||||
## Build the rust proxy into a binary.
|
||||
# When PROXY_UNOPTIMIZED is set and not empty, unoptimized rust artifacts are produced.
|
||||
# This reduces build time and produces binaries with debug symbols, at the expense of
|
||||
# runtime perforamnce.
|
||||
#
|
||||
# If the RELEASE arg is set and non-empty, a release artifact is built.
|
||||
FROM gcr.io/runconduit/proxy-deps:673c53de as build
|
||||
# When PROXY_SKIP_TESTS is set and not empty, tests are not run. Otherwise, tests are run
|
||||
# against either unoptimized or optimized proxy code, according to PROXY_UNOPTIMIZED.
|
||||
|
||||
ARG RUST_IMAGE=rust:1.23.0
|
||||
ARG RUNTIME_IMAGE=gcr.io/runconduit/base:2017-10-30.01
|
||||
|
||||
## Builds the proxy as incrementally as possible.
|
||||
FROM $RUST_IMAGE as build
|
||||
|
||||
WORKDIR /usr/src/conduit
|
||||
# Ranked roughly from least to most likely to change. Cargo.lock is the least likely
|
||||
# because it is supposed to be cached in the deps base image.
|
||||
COPY proto ./proto
|
||||
COPY proxy ./proxy
|
||||
ARG RELEASE
|
||||
RUN if [ -z "$RELEASE" ]; \
|
||||
then cargo build --frozen -p conduit-proxy && mv target/debug/conduit-proxy target/conduit-proxy ; \
|
||||
else cargo build --frozen -p conduit-proxy --release && mv target/release/conduit-proxy target/conduit-proxy ; \
|
||||
|
||||
# Fetch external dependencies.
|
||||
#
|
||||
# Mock out all local code and fetch external dependencies to ensure that external sources
|
||||
# are cached.
|
||||
RUN for d in proxy proxy/controller-grpc proxy/convert proxy/futures-mpsc-lossy proxy/router ; \
|
||||
do mkdir -p "${d}/src" && touch "${d}/src/lib.rs" ; \
|
||||
done
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY proxy/Cargo.toml proxy/Cargo.toml
|
||||
COPY proxy/controller-grpc/Cargo.toml proxy/controller-grpc/Cargo.toml
|
||||
COPY proxy/convert/Cargo.toml proxy/convert/Cargo.toml
|
||||
COPY proxy/futures-mpsc-lossy/Cargo.toml proxy/futures-mpsc-lossy/Cargo.toml
|
||||
COPY proxy/router/Cargo.toml proxy/router/Cargo.toml
|
||||
RUN cargo fetch --locked
|
||||
|
||||
# Build libraries, leaving the proxy and gRPC bindings mocked out.
|
||||
COPY proxy/convert proxy/convert
|
||||
COPY proxy/futures-mpsc-lossy proxy/futures-mpsc-lossy
|
||||
COPY proxy/router proxy/router
|
||||
ARG PROXY_UNOPTIMIZED
|
||||
RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \
|
||||
then cargo build --frozen ; \
|
||||
else cargo build --frozen --release ; \
|
||||
fi
|
||||
|
||||
# Build gRPC bindings, leaving the proxy mocked out.
|
||||
COPY proto proto
|
||||
COPY proxy/controller-grpc proxy/controller-grpc
|
||||
RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \
|
||||
then cargo build -p conduit-proxy-controller-grpc --features=arbitrary --frozen ; \
|
||||
else cargo build -p conduit-proxy-controller-grpc --features=arbitrary --frozen --release ; \
|
||||
fi
|
||||
|
||||
# Build the proxy binary using pre-built dependencies.
|
||||
COPY proxy/src proxy/src
|
||||
COPY proxy/tests proxy/tests
|
||||
RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \
|
||||
then cargo build -p conduit-proxy --bin conduit-proxy --frozen ; \
|
||||
else cargo build -p conduit-proxy --bin conduit-proxy --frozen --release ; \
|
||||
fi
|
||||
ARG PROXY_SKIP_TESTS
|
||||
RUN if [ -n "$PROXY_SKIP_TESTS" ]; \
|
||||
then echo "tests skipped" ; \
|
||||
elif [ -n "$PROXY_UNOPTIMIZED" ]; \
|
||||
then cargo test -p conduit-proxy --frozen ; \
|
||||
else cargo test -p conduit-proxy --frozen --release ; \
|
||||
fi
|
||||
RUN if [ -n "$PROXY_UNOPTIMIZED" ]; \
|
||||
then mv target/debug/conduit-proxy target/conduit-proxy ; \
|
||||
else mv target/release/conduit-proxy target/conduit-proxy ; \
|
||||
fi
|
||||
|
||||
## Install the proxy binary into the base runtime image.
|
||||
FROM gcr.io/runconduit/base:2017-10-30.01
|
||||
FROM $RUNTIME_IMAGE as runtime
|
||||
COPY --from=build /usr/src/conduit/target/conduit-proxy /usr/local/bin/conduit-proxy
|
||||
ENV CONDUIT_PROXY_LOG=info
|
||||
ENV CONDUIT_PROXY_LOG=warn,conduit_proxy=info
|
||||
ENTRYPOINT ["/usr/local/bin/conduit-proxy"]
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
# Proxy dependencies
|
||||
#
|
||||
# Fetches all required rust dependencies and caches library artifacts. All Conduit sources
|
||||
# are omitted from the resulting image so that artifacts may be built from source over
|
||||
# this image.
|
||||
#
|
||||
# When this file is changed, you must run `bin/update-proxy-deps-shas`.
|
||||
|
||||
# Compile the application to ensure we've obtained all build dependencies and that they
|
||||
# compile.
|
||||
FROM rust:1.23.0 as build
|
||||
WORKDIR /usr/src/conduit
|
||||
COPY Cargo.toml Cargo.lock ./
|
||||
COPY proto ./proto
|
||||
COPY proxy ./proxy
|
||||
RUN cargo fetch --locked
|
||||
|
||||
# Preserve dependency sources and build artifacts without maintaining conduit
|
||||
# sources/artifacts.
|
||||
FROM rust:1.23.0
|
||||
WORKDIR /usr/src/conduit
|
||||
COPY --from=build $CARGO_HOME $CARGO_HOME
|
||||
COPY --from=build /usr/src/conduit/Cargo.toml Cargo.toml
|
||||
COPY --from=build /usr/src/conduit/Cargo.lock Cargo.lock
|
Loading…
Reference in New Issue