From 04a309f562afc361625e68544b9771ec8563af56 Mon Sep 17 00:00:00 2001 From: Alexey Kondratov Date: Tue, 17 Aug 2021 15:12:22 +0300 Subject: [PATCH] Build zenithdb/zenith:latest in CI (zenithdb/console#18) --- .circleci/config.yml | 28 +++++++++++++ Dockerfile | 83 +++++++++++++++----------------------- Dockerfile.alpine | 95 ++++++++++++++++++++++++++++++++++++++++++++ Dockerfile.build | 15 +++++++ docker-entrypoint.sh | 2 +- 5 files changed, 172 insertions(+), 51 deletions(-) create mode 100644 Dockerfile.alpine create mode 100644 Dockerfile.build diff --git a/.circleci/config.yml b/.circleci/config.yml index 359b2d77d9..7414317fbd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -237,6 +237,23 @@ jobs: - store_test_results: path: /tmp/test_output + # Build zenithdb/zenith:latest image and push it to Docker hub + docker-image: + docker: + - image: cimg/base:2021.04 + steps: + - checkout + - setup_remote_docker: + docker_layer_caching: true + - run: + name: Init postgres submodule + command: git submodule update --init --depth 1 + - run: + name: Build and push Docker image + command: | + echo $DOCKER_PWD | docker login -u $DOCKER_LOGIN --password-stdin + docker build -t zenithdb/zenith:latest . && docker push zenithdb/zenith:latest + workflows: build_and_test: jobs: @@ -265,3 +282,14 @@ workflows: test_selection: batch_others requires: - build-zenith-<< matrix.build_type >> + - docker-image: + # Context gives an ability to login + context: Docker Hub + # Build image only for commits to main + filters: + branches: + only: + - main + requires: + - pg_regress tests release + - other tests release diff --git a/Dockerfile b/Dockerfile index a2a2fea1a4..0579059cc2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,94 +1,77 @@ # # Docker image for console integration testing. # -# We may also reuse it in CI to unify installation process and as a general binaries building -# tool for production servers. -# -# Dynamic linking is used for librocksdb and libstdc++ bacause librocksdb-sys calls -# bindgen with "dynamic" feature flag. This also prevents usage of dockerhub alpine-rust -# images which are statically linked and have guards against any dlopen. I would rather -# prefer all static binaries so we may change the way librocksdb-sys builds or wait until -# we will have our own storage and drop rockdb dependency. -# -# Cargo-chef is used to separate dependencies building from main binaries building. This -# way `docker build` will download and install dependencies only of there are changes to -# out Cargo.toml files. -# - # -# build postgres separately -- this layer will be rebuilt only if one of -# mentioned paths will get any changes +# Build Postgres separately --- this layer will be rebuilt only if one of +# mentioned paths will get any changes. # -FROM alpine:3.13 as pg-build -RUN apk add --update clang llvm compiler-rt compiler-rt-static lld musl-dev binutils \ - make bison flex readline-dev zlib-dev perl linux-headers libseccomp-dev -WORKDIR zenith +FROM zenithdb/build:buster AS pg-build +WORKDIR /zenith COPY ./vendor/postgres vendor/postgres COPY ./Makefile Makefile -# Build using clang and lld -RUN CC='clang' LD='lld' CFLAGS='-fuse-ld=lld --rtlib=compiler-rt' make postgres -j4 +RUN make -j $(getconf _NPROCESSORS_ONLN) -s postgres # # Calculate cargo dependencies. # This will always run, but only generate recipe.json with list of dependencies without # installing them. # -FROM alpine:20210212 as cargo-deps-inspect -RUN apk add --update rust cargo -RUN cargo install cargo-chef -WORKDIR zenith +FROM zenithdb/build:buster AS cargo-deps-inspect +WORKDIR /zenith COPY . . -RUN cargo chef prepare --recipe-path recipe.json +RUN cargo chef prepare --recipe-path /zenith/recipe.json # # Build cargo dependencies. -# This temp cantainner would be build only if recipe.json was changed. +# This temp cantainner should be rebuilt only if recipe.json was changed. # -FROM alpine:20210212 as deps-build -RUN apk add --update rust cargo openssl-dev clang build-base -# rust-rocksdb can be built against system-wide rocksdb -- that saves about -# 10 minutes during build. Rocksdb apk package is in testing now, but use it -# anyway. In case of any troubles we can download and build rocksdb here manually -# (to cache it as a docker layer). -RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb-dev -WORKDIR zenith +FROM zenithdb/build:buster AS deps-build +WORKDIR /zenith COPY --from=pg-build /zenith/tmp_install/include/postgresql/server tmp_install/include/postgresql/server -COPY --from=cargo-deps-inspect /root/.cargo/bin/cargo-chef /root/.cargo/bin/ +COPY --from=cargo-deps-inspect /usr/local/cargo/bin/cargo-chef /usr/local/cargo/bin/ COPY --from=cargo-deps-inspect /zenith/recipe.json recipe.json RUN ROCKSDB_LIB_DIR=/usr/lib/ cargo chef cook --release --recipe-path recipe.json # # Build zenith binaries # -FROM alpine:20210212 as build -RUN apk add --update rust cargo openssl-dev clang build-base -RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb-dev -WORKDIR zenith +FROM zenithdb/build:buster AS build +WORKDIR /zenith COPY . . # Copy cached dependencies COPY --from=pg-build /zenith/tmp_install/include/postgresql/server tmp_install/include/postgresql/server COPY --from=deps-build /zenith/target target -COPY --from=deps-build /root/.cargo /root/.cargo +COPY --from=deps-build /usr/local/cargo/ /usr/local/cargo/ RUN cargo build --release # # Copy binaries to resulting image. -# build-base hare to provide libstdc++ (it will also bring gcc, but leave it this way until we figure -# out how to statically link rocksdb or avoid it at all). # -FROM alpine:3.13 -RUN apk add --update openssl build-base libseccomp-dev -RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb +FROM debian:buster-slim +WORKDIR /data + +RUN apt-get update && apt-get -yq install librocksdb-dev libseccomp-dev openssl && \ + mkdir zenith_install + COPY --from=build /zenith/target/release/pageserver /usr/local/bin COPY --from=build /zenith/target/release/wal_acceptor /usr/local/bin COPY --from=build /zenith/target/release/proxy /usr/local/bin -COPY --from=pg-build /zenith/tmp_install /usr/local +COPY --from=pg-build /zenith/tmp_install postgres_install COPY docker-entrypoint.sh /docker-entrypoint.sh -RUN addgroup zenith && adduser -h /data -D -G zenith zenith +# Remove build artifacts (~ 500 MB) +RUN rm -rf postgres_install/build && \ + # 'Install' Postgres binaries locally + cp -r postgres_install/* /usr/local/ && \ + # Prepare an archive of Postgres binaries (should be around 11 MB) + # and keep it inside container for an ease of deploy pipeline. + cd postgres_install && tar -czf /data/postgres_install.tar.gz . && cd .. && \ + rm -rf postgres_install + +RUN useradd -m -d /data zenith + VOLUME ["/data"] -WORKDIR /data USER zenith EXPOSE 6400 ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/Dockerfile.alpine b/Dockerfile.alpine new file mode 100644 index 0000000000..a2a2fea1a4 --- /dev/null +++ b/Dockerfile.alpine @@ -0,0 +1,95 @@ +# +# Docker image for console integration testing. +# +# We may also reuse it in CI to unify installation process and as a general binaries building +# tool for production servers. +# +# Dynamic linking is used for librocksdb and libstdc++ bacause librocksdb-sys calls +# bindgen with "dynamic" feature flag. This also prevents usage of dockerhub alpine-rust +# images which are statically linked and have guards against any dlopen. I would rather +# prefer all static binaries so we may change the way librocksdb-sys builds or wait until +# we will have our own storage and drop rockdb dependency. +# +# Cargo-chef is used to separate dependencies building from main binaries building. This +# way `docker build` will download and install dependencies only of there are changes to +# out Cargo.toml files. +# + + +# +# build postgres separately -- this layer will be rebuilt only if one of +# mentioned paths will get any changes +# +FROM alpine:3.13 as pg-build +RUN apk add --update clang llvm compiler-rt compiler-rt-static lld musl-dev binutils \ + make bison flex readline-dev zlib-dev perl linux-headers libseccomp-dev +WORKDIR zenith +COPY ./vendor/postgres vendor/postgres +COPY ./Makefile Makefile +# Build using clang and lld +RUN CC='clang' LD='lld' CFLAGS='-fuse-ld=lld --rtlib=compiler-rt' make postgres -j4 + +# +# Calculate cargo dependencies. +# This will always run, but only generate recipe.json with list of dependencies without +# installing them. +# +FROM alpine:20210212 as cargo-deps-inspect +RUN apk add --update rust cargo +RUN cargo install cargo-chef +WORKDIR zenith +COPY . . +RUN cargo chef prepare --recipe-path recipe.json + +# +# Build cargo dependencies. +# This temp cantainner would be build only if recipe.json was changed. +# +FROM alpine:20210212 as deps-build +RUN apk add --update rust cargo openssl-dev clang build-base +# rust-rocksdb can be built against system-wide rocksdb -- that saves about +# 10 minutes during build. Rocksdb apk package is in testing now, but use it +# anyway. In case of any troubles we can download and build rocksdb here manually +# (to cache it as a docker layer). +RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb-dev +WORKDIR zenith +COPY --from=pg-build /zenith/tmp_install/include/postgresql/server tmp_install/include/postgresql/server +COPY --from=cargo-deps-inspect /root/.cargo/bin/cargo-chef /root/.cargo/bin/ +COPY --from=cargo-deps-inspect /zenith/recipe.json recipe.json +RUN ROCKSDB_LIB_DIR=/usr/lib/ cargo chef cook --release --recipe-path recipe.json + +# +# Build zenith binaries +# +FROM alpine:20210212 as build +RUN apk add --update rust cargo openssl-dev clang build-base +RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb-dev +WORKDIR zenith +COPY . . +# Copy cached dependencies +COPY --from=pg-build /zenith/tmp_install/include/postgresql/server tmp_install/include/postgresql/server +COPY --from=deps-build /zenith/target target +COPY --from=deps-build /root/.cargo /root/.cargo +RUN cargo build --release + +# +# Copy binaries to resulting image. +# build-base hare to provide libstdc++ (it will also bring gcc, but leave it this way until we figure +# out how to statically link rocksdb or avoid it at all). +# +FROM alpine:3.13 +RUN apk add --update openssl build-base libseccomp-dev +RUN apk --no-cache --update --repository https://dl-cdn.alpinelinux.org/alpine/edge/testing add rocksdb +COPY --from=build /zenith/target/release/pageserver /usr/local/bin +COPY --from=build /zenith/target/release/wal_acceptor /usr/local/bin +COPY --from=build /zenith/target/release/proxy /usr/local/bin +COPY --from=pg-build /zenith/tmp_install /usr/local +COPY docker-entrypoint.sh /docker-entrypoint.sh + +RUN addgroup zenith && adduser -h /data -D -G zenith zenith +VOLUME ["/data"] +WORKDIR /data +USER zenith +EXPOSE 6400 +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["pageserver"] diff --git a/Dockerfile.build b/Dockerfile.build new file mode 100644 index 0000000000..92b2c21ffd --- /dev/null +++ b/Dockerfile.build @@ -0,0 +1,15 @@ +# +# Image with all the required dependencies to build https://github.com/zenithdb/zenith +# and Postgres from https://github.com/zenithdb/postgres +# Also includes some rust development and build tools. +# +FROM rust:slim-buster +WORKDIR /zenith + +# Install postgres and zenith build dependencies +# clang is for rocksdb +RUN apt-get update && apt-get -yq install automake libtool build-essential bison flex libreadline-dev zlib1g-dev libxml2-dev \ + libseccomp-dev pkg-config libssl-dev librocksdb-dev clang + +# Install rust tools +RUN rustup component add clippy && cargo install cargo-chef cargo-audit diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index be57b29427..dcfd502d85 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,6 +1,6 @@ #!/bin/sh if [ "$1" = 'pageserver' ]; then - if [ ! -d "/data/timelines" ]; then + if [ ! -d "/data/tenants" ]; then echo "Initializing pageserver data directory" pageserver --init -D /data --postgres-distrib /usr/local fi