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
|
for f in $( grep -lR --include=Dockerfile\* go-deps: . ) ; do
|
||||||
validate_go_deps_tag $f
|
validate_go_deps_tag $f
|
||||||
done
|
done
|
||||||
for f in $( grep -lR --include=Dockerfile\* proxy-deps: . ) ; do
|
|
||||||
validate_proxy_deps_tag $f
|
|
||||||
done
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Push container images to Google Container Registry.
|
# Push container images to Google Container Registry.
|
||||||
|
@ -123,10 +120,11 @@ jobs:
|
||||||
- |
|
- |
|
||||||
export CONDUIT_TAG=$(. bin/_tag.sh ; clean_head_root_tag)
|
export CONDUIT_TAG=$(. bin/_tag.sh ; clean_head_root_tag)
|
||||||
echo "CONDUIT_TAG=${CONDUIT_TAG}"
|
echo "CONDUIT_TAG=${CONDUIT_TAG}"
|
||||||
- export PROXY_RELEASE=1 BUILD_DEBUG=1 DOCKER_TRACE=1
|
- export BUILD_DEBUG=1 DOCKER_TRACE=1
|
||||||
|
|
||||||
script:
|
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:
|
after_success:
|
||||||
- bin/docker-push-deps
|
- 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
|
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
|
### Testing
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -353,12 +370,7 @@ hard-coded SHA's:
|
||||||
- [`Gopkg.lock`](Gopkg.lock)
|
- [`Gopkg.lock`](Gopkg.lock)
|
||||||
- [`Dockerfile-go-deps`](Dockerfile-go-deps)
|
- [`Dockerfile-go-deps`](Dockerfile-go-deps)
|
||||||
|
|
||||||
`gcr.io/runconduit/proxy-deps` depends on
|
`bin/update-go-deps-shas` must be run when go dependencies change.
|
||||||
- [`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.
|
|
||||||
|
|
||||||
# Build Architecture
|
# Build Architecture
|
||||||
|
|
||||||
|
@ -376,7 +388,6 @@ build_architecture
|
||||||
"cli/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
"cli/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||||
"cli/Dockerfile-bin" [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" [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/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||||
"proxy-init/integration-test/iptables/Dockerfile-tester" [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];
|
"web/Dockerfile" [color=lightblue, style=filled, shape=rect];
|
||||||
|
@ -422,13 +433,8 @@ build_architecture
|
||||||
"docker-build-proxy" -> "_docker.sh";
|
"docker-build-proxy" -> "_docker.sh";
|
||||||
"docker-build-proxy" -> "_tag.sh";
|
"docker-build-proxy" -> "_tag.sh";
|
||||||
"docker-build-proxy" -> "docker-build-base";
|
"docker-build-proxy" -> "docker-build-base";
|
||||||
"docker-build-proxy" -> "docker-build-go-deps";
|
|
||||||
"docker-build-proxy" -> "proxy/Dockerfile";
|
"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" -> "_docker.sh";
|
||||||
"docker-build-proxy-init" -> "_tag.sh";
|
"docker-build-proxy-init" -> "_tag.sh";
|
||||||
"docker-build-proxy-init" -> "docker-build-base";
|
"docker-build-proxy-init" -> "docker-build-base";
|
||||||
|
@ -483,9 +489,6 @@ build_architecture
|
||||||
"update-go-deps-shas" -> "controller/Dockerfile";
|
"update-go-deps-shas" -> "controller/Dockerfile";
|
||||||
"update-go-deps-shas" -> "proxy-init/Dockerfile";
|
"update-go-deps-shas" -> "proxy-init/Dockerfile";
|
||||||
"update-go-deps-shas" -> "web/Dockerfile";
|
"update-go-deps-shas" -> "web/Dockerfile";
|
||||||
|
|
||||||
"update-proxy-deps-shas" -> "_tag.sh";
|
|
||||||
"update-proxy-deps-shas" -> "proxy/Dockerfile";
|
|
||||||
}
|
}
|
||||||
build_architecture
|
build_architecture
|
||||||
</details>
|
</details>
|
||||||
|
|
11
bin/_tag.sh
11
bin/_tag.sh
|
@ -6,10 +6,6 @@ git_sha_head() {
|
||||||
git rev-parse --short=8 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() {
|
go_deps_sha() {
|
||||||
cat Gopkg.lock Dockerfile-go-deps | shasum - | awk '{print $1}' |cut -c 1-8
|
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
|
# 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
|
# Go or Rust dependencies. To confirm the set of scripts that should call this
|
||||||
# function, run:
|
# function, run:
|
||||||
# $ grep -ER 'docker-build-(go|proxy)-deps' .
|
# $ grep -ER 'docker-build-go-deps' .
|
||||||
|
|
||||||
validate_go_deps_tag() {
|
validate_go_deps_tag() {
|
||||||
file="$1"
|
file="$1"
|
||||||
validate_tag "$file" "gcr.io/runconduit/go-deps" "$(go_deps_sha)"
|
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-controller
|
||||||
bin/docker-build-web
|
bin/docker-build-web
|
||||||
bin/docker-build-proxy
|
|
||||||
bin/docker-build-proxy-init
|
bin/docker-build-proxy-init
|
||||||
bin/docker-build-cli
|
bin/docker-build-cli
|
||||||
|
|
||||||
|
bin/docker-build-proxy
|
||||||
|
|
|
@ -10,13 +10,6 @@ fi
|
||||||
. bin/_docker.sh
|
. bin/_docker.sh
|
||||||
. bin/_tag.sh
|
. bin/_tag.sh
|
||||||
|
|
||||||
dockerfile=proxy/Dockerfile
|
docker_build proxy "$(head_root_tag)" proxy/Dockerfile \
|
||||||
|
--build-arg="PROXY_SKIP_TESTS=${PROXY_SKIP_TESTS:-}" \
|
||||||
validate_proxy_deps_tag $dockerfile
|
--build-arg="PROXY_UNOPTIMIZED=${PROXY_UNOPTIMIZED:-}"
|
||||||
|
|
||||||
(
|
|
||||||
bin/docker-build-base
|
|
||||||
bin/docker-build-proxy-deps
|
|
||||||
) >/dev/null
|
|
||||||
|
|
||||||
docker_build proxy "$(head_root_tag)" $dockerfile --build-arg="RELEASE=${PROXY_RELEASE:-1}"
|
|
||||||
|
|
|
@ -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 cli-bin "${tag}"
|
||||||
|
|
||||||
docker_image go-deps "$(go_deps_sha)"
|
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 base 2017-10-30.01 || true
|
||||||
docker_pull go-deps "$(go_deps_sha)" || 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 base 2017-10-30.01
|
||||||
docker_push go-deps "$(go_deps_sha)"
|
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
|
# Proxy build and runtime
|
||||||
#
|
#
|
||||||
# Builds a slim runtime image with the conduit-proxy 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
|
||||||
## Build the rust proxy into a binary.
|
# runtime perforamnce.
|
||||||
#
|
#
|
||||||
# If the RELEASE arg is set and non-empty, a release artifact is built.
|
# When PROXY_SKIP_TESTS is set and not empty, tests are not run. Otherwise, tests are run
|
||||||
FROM gcr.io/runconduit/proxy-deps:673c53de as build
|
# 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
|
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.
|
# Fetch external dependencies.
|
||||||
COPY proto ./proto
|
#
|
||||||
COPY proxy ./proxy
|
# Mock out all local code and fetch external dependencies to ensure that external sources
|
||||||
ARG RELEASE
|
# are cached.
|
||||||
RUN if [ -z "$RELEASE" ]; \
|
RUN for d in proxy proxy/controller-grpc proxy/convert proxy/futures-mpsc-lossy proxy/router ; \
|
||||||
then cargo build --frozen -p conduit-proxy && mv target/debug/conduit-proxy target/conduit-proxy ; \
|
do mkdir -p "${d}/src" && touch "${d}/src/lib.rs" ; \
|
||||||
else cargo build --frozen -p conduit-proxy --release && mv target/release/conduit-proxy target/conduit-proxy ; \
|
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
|
fi
|
||||||
|
|
||||||
## Install the proxy binary into the base runtime image.
|
## 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
|
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"]
|
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