-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
github: rework Docker build, and publish new images
This reworks the `Dockerfile` to now build multiple images, including one for end users to run their own copy of Glean, and an updated version of the React demo database. It includes x86_64 and aarch64 Linux images using public GHA runners, which probably covers 98% of all realistic uses. (Using GHA runners means this workflow is trivially usable for public forks, too.) There is a new `bindist` target used by the Dockerfile that creates a directory of needed binaries and libraries, and properly packages them for usage in the container. There are now three containers published from the `Dockerfile`, all based on Ubuntu 24.04: - `glean/client`, which only contains the `glean` command, then - `glean/server`, including `glean-server`, then - `glean/demo`, including a precanned `glean-hyperlink` + react DB These containers are all size-optimized; the final images have no development tools installed and the absolute minimum necessary installed packages. For example, the new x86_64 `glean/demo` is only 486MB uncompressed, compared to the 2.4GB of the previous demo version. The `client` and `server` images are 251MB and 300MB, respectively. The `client` image should probably include `gen-schema` so that end users can generate code from their own non-upstream `.angle` files, but that can be added in a future patch. In theory, this new container could also be used to replace most of the junk in `ci.yml` in order to repeat ourselves less, but it would need another image in order to add more things so that the test suite can be run. That can happen in a future patch. Signed-off-by: Austin Seipp <[email protected]>
- Loading branch information
1 parent
c637787
commit 6623245
Showing
8 changed files
with
277 additions
and
227 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# https://docs.github.com/en/free-pro-team@latest/actions/reference/workflow-syntax-for-github-actions | ||
name: Build Docker Images | ||
on: | ||
# Manual trigger: | ||
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_dispatch | ||
workflow_dispatch: | ||
# Scheduled trigger: | ||
# https://docs.github.com/en/actions/reference/events-that-trigger-workflows#scheduled-events | ||
schedule: | ||
- cron: "0 1 * * mon" # every monday at 1am | ||
|
||
env: | ||
# We have to use 'glean' here, not 'Glean', because Docker does not allow | ||
# uppercase letters in image names, so the image push will inevitably fail | ||
BASE_IMAGE_NAME: ${{ github.repository_owner }}/glean | ||
REGISTRY: ghcr.io | ||
|
||
jobs: | ||
build-docker: | ||
name: Build and Push Docker Images | ||
strategy: | ||
matrix: | ||
os: [ubuntu-24.04, ubuntu-24.04-arm] | ||
runs-on: ${{ matrix.os }} | ||
permissions: | ||
contents: read | ||
packages: write | ||
steps: | ||
- name: Checkout Repository | ||
uses: actions/checkout@v4 | ||
with: | ||
persist-credentials: false | ||
|
||
- name: Log in to the Container registry | ||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2.1.0 | ||
with: | ||
registry: ${{ env.REGISTRY }} | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Derive image tags | ||
run: | | ||
DATE=$(date +%Y%m%d%H%M) | ||
echo "Using date: ${DATE}" | ||
echo "Using hash: ${GITHUB_SHA}" | ||
echo "IMAGE_DATE_TAG=${DATE}" >> $GITHUB_ENV | ||
echo "IMAGE_SHA_TAG=${GITHUB_SHA}" >> $GITHUB_ENV | ||
env: | ||
GITHUB_SHA: ${{ github.sha }} | ||
|
||
- name: Build and save Docker images | ||
run: | | ||
for x in server client demo; do | ||
docker build -t $x:latest --target $x . | ||
for v in latest ${IMAGE_DATE_TAG} ${IMAGE_SHA_TAG}; do | ||
docker tag $x:latest ${REGISTRY}/${BASE_IMAGE_NAME}/$x:$v | ||
done | ||
done | ||
env: | ||
REGISTRY: ${{ env.REGISTRY }} | ||
BASE_IMAGE_NAME: ${{ env.BASE_IMAGE_NAME }} | ||
IMAGE_DATE_TAG: ${{ env.IMAGE_DATE_TAG }} | ||
IMAGE_SHA_TAG: ${{ env.IMAGE_SHA_TAG }} | ||
|
||
- name: Test Docker image | ||
run: | | ||
docker run -it --rm \ | ||
--entrypoint /usr/local/bin/glean \ | ||
demo:latest \ | ||
shell --db-root /glean/db --schema dir:/glean/schema \ | ||
':describe' \ | ||
':db react/0' \ | ||
':stat' | ||
- name: Push image to the Container registry | ||
run: | | ||
set -x | ||
for x in server client demo; do | ||
for v in latest ${IMAGE_DATE_TAG} ${IMAGE_SHA_TAG}; do | ||
echo docker push $x:latest ${REGISTRY}/${BASE_IMAGE_NAME}/$x:$v | ||
done | ||
done | ||
env: | ||
REGISTRY: ${{ env.REGISTRY }} | ||
BASE_IMAGE_NAME: ${{ env.BASE_IMAGE_NAME }} | ||
IMAGE_DATE_TAG: ${{ env.IMAGE_DATE_TAG }} | ||
IMAGE_SHA_TAG: ${{ env.IMAGE_SHA_TAG }} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,96 +1,146 @@ | ||
FROM ghcr.io/facebookincubator/hsthrift/ci-base:latest as tools | ||
# remove any old stuff | ||
RUN rm -rf /usr/local/lib | ||
RUN rm -rf /usr/local/include | ||
RUN apt-get install -y ghc-8.10.2 cmake ninja-build libxxhash-dev wget unzip rsync libgmock-dev | ||
RUN cabal update | ||
RUN mkdir /glean-code | ||
WORKDIR /glean-code | ||
ADD https://api.github.com/repos/facebookincubator/hsthrift/compare/main...HEAD /dev/null | ||
ADD ./glean /glean-code/glean | ||
ADD ./thrift /glean-code/thrift | ||
ADD ./cabal.project /glean-code/ | ||
ADD ./Makefile /glean-code/ | ||
ADD ./mk /glean-code/mk | ||
ADD ./glean.cabal.in /glean-code/ | ||
ADD ./LICENSE /glean-code/ | ||
ADD ./Setup.hs /glean-code/ | ||
ADD ./install_deps.sh /glean-code/ | ||
RUN ./install_deps.sh | ||
# Nuke build artifacts to save space | ||
RUN rm -rf /tmp/fbcode_builder_getdeps-Z__wZGleanZGleanZhsthriftZbuildZfbcode_builder-root/ | ||
# MARK: build: deps+setup | ||
FROM ubuntu:24.04 AS build | ||
WORKDIR /build | ||
|
||
ENV LD_LIBRARY_PATH=/root/.hsthrift/lib | ||
ENV PKG_CONFIG_PATH=/root/.hsthrift/lib/pkgconfig | ||
ENV PATH=$PATH:/root/.hsthrift/bin | ||
# This is what is tested at Meta, so we use it here. | ||
ENV GHC_VER=9.2.8 | ||
# See: https://github.com/haskell/cabal/issues/10046 | ||
ENV CABAL_VER=3.10 | ||
# Major available version of Clang. | ||
ENV CLANG_VER=15 | ||
# Must be set for GHC, otherwise cabal will fail to build files with non-ASCII | ||
# characters (like lens). | ||
ENV LANG=en_US.UTF-8 | ||
|
||
RUN make | ||
RUN cp $(cabal exec --project-file=cabal.project -- which glean) ~/.cabal/bin/ | ||
RUN cp $(cabal exec --project-file=cabal.project -- which glean-server) ~/.cabal/bin/ | ||
RUN cp $(cabal exec --project-file=cabal.project -- which glean-hyperlink) ~/.cabal/bin/ | ||
RUN glean --help | ||
RUN wget https://github.com/facebook/flow/releases/download/v0.219.0/flow-linux64-v0.219.0.zip | ||
RUN unzip flow-linux64-v0.219.0.zip | ||
RUN mkdir -p /root/.hsthrift/bin && mv flow/flow /root/.hsthrift/bin/ && rm -rf flow-linux64-v0.219.0.zip flow/ | ||
WORKDIR / | ||
RUN git clone https://github.com/facebook/react.git --depth 1 react-code | ||
RUN cat /react-code/scripts/flow/config/flowconfig \ | ||
| grep -v REACT_RENDERER_FLOW_ \ | ||
| grep -v CI_MAX_WORKERS \ | ||
| grep -v FLOW_VERSION \ | ||
| sed '/^\[options\]/a exact_by_default=false' > /react-code/.flowconfig | ||
# Install base dependencies. | ||
RUN apt update \ | ||
&& apt install -y \ | ||
curl locales build-essential clang-$CLANG_VER git ninja-build make cmake libboost-all-dev \ | ||
libgmp-dev libaio-dev libbz2-dev libdouble-conversion-dev libdwarf-dev libgoogle-glog-dev libiberty-dev libjemalloc-dev \ | ||
libnuma-dev liblzma-dev liblz4-dev libsnappy-dev libsodium-dev libssl-dev libunwind-dev libzstd-dev libfast-float-dev \ | ||
pkg-config rsync libgmock-dev libpcre3-dev libtinfo-dev libxxhash-dev patchelf \ | ||
&& locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8 | ||
|
||
# Install GHC and Cabal via ghcup. | ||
RUN curl --proto '=https' --tlsv1.2 -sSf "https://downloads.haskell.org/~ghcup/$(uname -m)-linux-ghcup" -o /tmp/ghcup \ | ||
&& chmod +x /tmp/ghcup \ | ||
&& /tmp/ghcup install cabal $CABAL_VER --set \ | ||
&& /tmp/ghcup install ghc $GHC_VER --set | ||
|
||
FROM ubuntu:20.04 AS demo | ||
# Use Clang, not gcc. Note that this MUST happen *AFTER* installing GHC above. | ||
# Apparently `ghcup` presumably modifies the settings for GHC in some way, which | ||
# inevitably causes a link failure due to incompatible -fPIC vs non-fPIC build | ||
# settings... | ||
RUN apt remove -y gcc g++ && apt autoremove -y \ | ||
&& update-alternatives --install /usr/bin/cc cc /usr/bin/clang-$CLANG_VER 10 \ | ||
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-$CLANG_VER 10 \ | ||
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/clang-$CLANG_VER 10 \ | ||
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/clang++-$CLANG_VER 10 | ||
|
||
LABEL org.opencontainers.image.source="https://github.com/facebookincubator/Glean" | ||
# Run deps build (rocksdb, folly, hsthrift, etc). install_deps.sh needs some of | ||
# the source files, so copy the minimum amount needed so that we can skip this | ||
# step as much as possible (because these files are not changed) as frequently.) | ||
COPY ./mk ./mk | ||
COPY install_deps.sh Makefile cabal.project glean.cabal.in ./ | ||
RUN ./install_deps.sh --threads $(nproc) | ||
RUN rm -rf /tmp/fbcode_builder_getdeps-Z__wZGleanZGleanZhsthriftZbuildZfbcode_builder-root/ | ||
|
||
ENV PATH=/glean-demo/bin:$PATH | ||
ENV LD_LIBRARY_PATH=/usr/local/lib | ||
# MARK: build: main build | ||
COPY ./thrift/ ./thrift | ||
COPY ./glean ./glean | ||
RUN touch settings.mk \ | ||
&& echo "EXTRA_GHC_OPTS=-j$(nproc) +RTS -A128m -n2m -RTS" >> settings.mk \ | ||
&& echo "CABAL_CONFIG_FLAGS=-fclang -f-hack-tests -f-rust-tests -f-python-tests" >> settings.mk | ||
RUN true && \ | ||
( export LD_LIBRARY_PATH=$HOME/.hsthrift/lib:$LD_LIBRARY_PATH \ | ||
; export PKG_CONFIG_PATH=$HOME/.hsthrift/lib/pkgconfig:$PKG_CONFIG_PATH \ | ||
; export PATH=$HOME/.ghcup/bin:$HOME/.hsthrift/bin:$PATH \ | ||
; cabal update && make -j$(nproc) && make bindist \ | ||
) | ||
# Now patch the binaries to include /usr/local/lib in their rpath, as that's | ||
# where the final libraries will go anyway. | ||
RUN patchelf --add-rpath /usr/local/lib ./bindir/bin/* | ||
|
||
RUN apt-get update && apt-get install -y \ | ||
libicu66 \ | ||
libboost-context1.71.0 \ | ||
libboost-filesystem1.71.0 \ | ||
libboost-program-options1.71.0 \ | ||
libboost-regex1.71.0 \ | ||
libunwind8 \ | ||
libgoogle-glog0v5 \ | ||
libssl1.1 \ | ||
libsodium23 \ | ||
libdouble-conversion3 \ | ||
libmysqlclient21 \ | ||
libevent-2.1-7 \ | ||
libsnappy-dev \ | ||
libxxhash0 \ | ||
libatomic1 \ | ||
&& apt-get clean && rm -rf /var/lib/apt/lists/* | ||
# MARK: common: base image | ||
FROM ubuntu:24.04 AS common | ||
# This image only exists so that the client and server images can share it. | ||
COPY --from=build /build/bindir/lib/* /usr/local/lib | ||
RUN mkdir -p /glean/db /glean/schema \ | ||
&& apt update \ | ||
&& apt install -y \ | ||
libatomic1 \ | ||
libsnappy1v5 \ | ||
libpcre3 \ | ||
libunwind8 \ | ||
libgoogle-glog0v6t64 \ | ||
libicu74 \ | ||
libdouble-conversion3 \ | ||
libevent-2.1-7t64 \ | ||
libdwarf1 \ | ||
libsodium23 \ | ||
libaio1t64 \ | ||
libboost-context1.83.0 \ | ||
libboost-regex1.83.0 \ | ||
libboost-program-options1.83.0 \ | ||
libboost-system1.83.0 \ | ||
libboost-thread1.83.0 \ | ||
libboost-atomic1.83.0 \ | ||
libboost-filesystem1.83.0 | ||
|
||
WORKDIR /glean-demo | ||
# MARK: server+client | ||
FROM common AS client | ||
COPY --from=build /build/bindir/bin/glean /usr/local/bin | ||
CMD ["/usr/local/bin/glean", "--schema", "dir:/glean/schema"] | ||
|
||
RUN mkdir /glean-demo/bin | ||
FROM client AS server | ||
COPY --from=build /build/bindir/bin/glean-server /usr/local/bin | ||
CMD ["/usr/local/bin/glean-server", "--db-root", "/glean/db", "--schema", "dir:/glean/schema", "--port", "12345"] | ||
|
||
COPY --from=tools /root/.hsthrift/lib /usr/local/lib | ||
COPY --from=tools /root/.hsthrift/bin/flow /usr/local/bin | ||
COPY --from=tools /root/.cabal/bin/glean /glean-demo/bin | ||
COPY --from=tools /root/.cabal/bin/glean-server /glean-demo/bin | ||
COPY --from=tools /root/.cabal/bin/glean-hyperlink /glean-demo/bin | ||
COPY --from=tools /glean-code/glean/schema /glean-demo/schema | ||
COPY --from=tools /react-code /glean-demo/code | ||
ADD docker_entrypoint.sh docker_entrypoint.sh | ||
FROM common AS tools | ||
COPY --from=build /build/bindir/bin/glean /usr/local/bin | ||
COPY --from=build /build/bindir/bin/gen-schema /usr/local/bin/glean-gen-schema | ||
|
||
RUN mkdir -p db /tmp/flow-index-out | ||
# MARK: demo setup | ||
FROM common AS demo-build | ||
RUN apt update && apt install -y unzip git | ||
ADD https://github.com/facebook/flow/releases/download/v0.245.2/flow-linux64-v0.245.2.zip /tmp/flow-x86_64.zip | ||
ADD https://github.com/facebook/flow/releases/download/v0.245.2/flow-linux-arm64-v0.245.2.zip /tmp/flow-aarch64.zip | ||
RUN true && (cd /tmp; unzip flow-$(uname -m).zip) | ||
|
||
RUN flow glean code --output-dir /tmp/flow-index-out --write-root "" && \ | ||
glean --db-root db --schema dir:schema/source create --repo react/0 && \ | ||
glean --db-root db --schema dir:schema/source write --repo react/0 /tmp/flow-index-out/* && \ | ||
glean --db-root db --schema dir:schema/source derive --repo react/0 flow.FileXRef flow.FileDeclaration && \ | ||
glean --db-root db --schema dir:schema/source finish --repo react/0 && \ | ||
rm -Rf /tmp/flow-index-out | ||
RUN true \ | ||
&& git clone --depth 1 --branch v19.0.0 https://github.com/facebook/react.git /react-code \ | ||
&& rm -rf /react-code/.git | ||
RUN cat /react-code/scripts/flow/config/flowconfig \ | ||
| grep -v REACT_RENDERER_FLOW_ \ | ||
| grep -v FLOW_VERSION \ | ||
| sed '/^\[options\]/a exact_by_default=false' > /react-code/.flowconfig | ||
|
||
ENV REPO_NAME=react | ||
FROM server AS demo | ||
COPY --from=build /build/bindir/bin/glean-hyperlink /usr/local/bin | ||
COPY --from=build /build/glean/schema/source /glean/schema/ | ||
COPY --from=demo-build /tmp/flow/flow /usr/local/bin | ||
COPY --from=demo-build /react-code /glean/code/react | ||
|
||
EXPOSE 8888 | ||
WORKDIR /glean | ||
RUN mkdir -p /tmp/flow-index-out \ | ||
&& flow glean code/react --output-dir /tmp/flow-index-out --write-root "" \ | ||
&& glean --db-root db --schema dir:schema create --repo react/0 \ | ||
&& glean --db-root db --schema dir:schema write --repo react/0 /tmp/flow-index-out/* \ | ||
&& glean --db-root db --schema dir:schema derive --repo react/0 flow.FileXRef flow.FileDeclaration \ | ||
&& glean --db-root db --schema dir:schema finish --repo react/0 \ | ||
&& rm -rf /tmp/flow-index-out | ||
|
||
ENTRYPOINT ["./docker_entrypoint.sh"] | ||
# write out a simple inline script to start the demo app | ||
RUN touch /usr/local/bin/glean-demo \ | ||
&& chmod a+x /usr/local/bin/glean-demo \ | ||
&& echo "#!/usr/bin/env bash" >> /usr/local/bin/glean-demo \ | ||
&& echo "set -ex" >> /usr/local/bin/glean-demo \ | ||
&& echo "/usr/local/bin/glean-server --db-root /glean/db --schema dir:/glean/schema --port 12345 &" >> /usr/local/bin/glean-demo \ | ||
&& echo "sleep 3" >> /usr/local/bin/glean-demo \ | ||
&& echo "exec /usr/local/bin/glean-hyperlink --service localhost:12345 --repo react --root /glean/code/react --http 8888" >> /usr/local/bin/glean-demo \ | ||
# Add a dummy favicon.ico so that the web server doesn't complain. \ | ||
&& touch /glean/code/react/favicon.ico | ||
|
||
# docker run -ti -p8888:8888 ghcr.io/facebookincubator/glean/demo | ||
EXPOSE 8888 | ||
EXPOSE 12345 | ||
ENTRYPOINT ["/usr/local/bin/glean-demo"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.