Skip to content

Instantly share code, notes, and snippets.

@nicholasaiello
Last active January 23, 2022 16:46
Show Gist options
  • Save nicholasaiello/7fede7d1fd947a1e12746ee440899f4d to your computer and use it in GitHub Desktop.
Save nicholasaiello/7fede7d1fd947a1e12746ee440899f4d to your computer and use it in GitHub Desktop.
Multi-platform build support (Dockerfile), and fix protoc download url for aarch64 platforms (map aarch64 -> aarch_64)

Multi-platform Support

--platform

By default, the image is built using the same architecture as the host/build machine. To override that, pass a valid platform string:

# build for arm64
$ docker build -t harmony --platform linux/arm64 .

# build for amd64
$ docker build -t harmony --platform linux/amd64 .

Override Version of Go

The default version is set to 1.16.3. To override this with another 1.16.x distro, pass --build-arg GOLANG_VERSION=x.x.x. Example:

$ docker build --build-arg GOLANG_VERSION=1.16.13 -t harmony .
FROM --platform=$TARGETPLATFORM ubuntu:18.04
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG TARGETARCH
ARG TARGETOS
ARG TARGETPLATFORM
ARG GOLANG_VERSION="1.16.3"
SHELL ["/bin/bash", "-c"]
RUN apt update && apt upgrade -y
ENV GOPATH=/root/go
ENV GO111MODULE=on
ENV HMY_PATH=${GOPATH}/src/github.com/harmony-one
ENV OPENSSL_DIR=/usr/lib/ssl
ENV MCL_DIR=${HMY_PATH}/mcl
ENV BLS_DIR=${HMY_PATH}/bls
ENV CGO_CFLAGS="-I${BLS_DIR}/include -I${MCL_DIR}/include"
ENV CGO_LDFLAGS="-L${BLS_DIR}/lib"
ENV LD_LIBRARY_PATH=${BLS_DIR}/lib:${MCL_DIR}/lib
ENV GIMME_GO_VERSION=$GOLANG_VERSION
ENV PATH="/root/bin:${PATH}"
RUN apt-get update -y && \
apt install libgmp-dev libssl-dev curl git \
psmisc dnsutils jq make gcc g++ bash tig tree sudo vim \
silversearcher-ag unzip emacs-nox nano bash-completion -y
RUN mkdir ~/bin && \
curl -sL -o ~/bin/gimme \
https://raw.githubusercontent.com/travis-ci/gimme/master/gimme && \
chmod +x ~/bin/gimme
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})"
RUN mkdir /root/workspace
RUN git clone https://github.com/harmony-one/harmony.git ${HMY_PATH}/harmony
RUN git clone https://github.com/harmony-one/bls.git ${HMY_PATH}/bls
RUN git clone https://github.com/harmony-one/mcl.git ${HMY_PATH}/mcl
RUN git clone https://github.com/harmony-one/go-sdk.git ${HMY_PATH}/go-sdk
RUN cd ${HMY_PATH}/bls && make -j8 BLS_SWAP_G=1
RUN touch /root/.bash_profile && \
gimme ${GIMME_GO_VERSION} >> /root/.bash_profile && \
echo "GIMME_GO_VERSION='${GIMME_GO_VERSION}'" >> /root/.bash_profile && \
echo "GO111MODULE='on'" >> /root/.bash_profile && \
echo ". ~/.bash_profile" >> /root/.profile && \
echo ". ~/.bash_profile" >> /root/.bashrc
ENV GOPATH='/root/go'
ENV PATH="/root/.gimme/versions/go${GIMME_GO_VERSION}.${TARGETOS}.${TARGETARCH}/bin:${GOPATH}/bin:${PATH}"
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; . ~/.bash_profile; \
go get -u golang.org/x/tools/cmd/goimports; \
go get -u golang.org/x/lint/golint ; \
go get -u github.com/rogpeppe/godef ; \
go get -u github.com/go-delve/delve/cmd/dlv; \
go get -u github.com/golang/mock/mockgen; \
go get -u github.com/stamblerre/gocode; \
go get -u golang.org/x/tools/...
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; . ~/.bash_profile; \
go get -u honnef.co/go/tools/cmd/staticcheck/...
WORKDIR ${HMY_PATH}/harmony
# TODO remove once `install_protoc.sh` changes are committed
COPY scripts scripts
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; scripts/install_build_tools.sh
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; go mod tidy
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; scripts/go_executable_build.sh -S
RUN eval "$(~/bin/gimme ${GIMME_GO_VERSION})" ; cd ${HMY_PATH}/go-sdk && \
make -j8 && \
cp hmy /root/bin
ARG K1=one1tq4hy947c9gr8qzv06yxz4aeyhc9vn78al4rmu
ARG K2=one1y5gmmzumajkm5mx3g2qsxtza2d3haq0zxyg47r
ARG K3=one1qrqcfek6sc29sachs3glhs4zny72mlad76lqcp
ARG KS1=8d222cffa99eb1fb86c581d9dfe7d60dd40ec62aa29056b7ff48028385270541
ARG KS2=da1800da5dedf02717696675c7a7e58383aff90b1014dfa1ab5b7bd1ce3ef535
ARG KS3=f4267bb5a2f0e65b8f5792bb6992597fac2b35ebfac9885ce0f4152c451ca31a
RUN hmy keys import-private-key ${KS1}
RUN hmy keys import-private-key ${KS2}
RUN hmy keys import-private-key ${KS3}
RUN hmy keys generate-bls-key > keys.json
RUN jq '.["encrypted-private-key-path"]' -r keys.json > /root/keypath && cp keys.json /root && \
echo "export BLS_KEY_PATH=$(cat /root/keypath)" >> /root/.bashrc && \
echo "export BLS_KEY=$(jq '.["public-key"]' -r keys.json)" >> /root/.bashrc && \
echo "printf '${K1}, ${K2}, ${K3} are imported accounts in hmy for local dev\n\n'" >> /root/.bashrc && \
echo "printf 'test with: hmy blockchain validator information ${K1}\n\n'" >> /root/.bashrc && \
echo "echo "$(jq '.["public-key"]' -r keys.json)" is an extern bls key" >> /root/.bashrc && \
echo ". /etc/bash_completion" >> /root/.bashrc && \
echo ". <(hmy completion)" >> /root/.bashrc
# replace gimmego with tagged images: https://hub.docker.com/_/golang/
FROM --platform=$TARGETPLATFORM golang:1.16-buster AS builder
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG BUILDPLATFORM
ARG TARGETPLATFORM
ARG GOPATH=/root/go
SHELL ["/bin/bash", "-c"]
ENV GOPATH=$GOPATH
ENV GO111MODULE=on
ENV HMY_PATH=${GOPATH}/src/github.com/harmony-one
ENV OPENSSL_DIR=/usr/lib/ssl
ENV MCL_DIR=${HMY_PATH}/mcl
ENV BLS_DIR=${HMY_PATH}/bls
ENV CGO_CFLAGS="-I${BLS_DIR}/include -I${MCL_DIR}/include"
ENV CGO_LDFLAGS="-L${BLS_DIR}/lib"
ENV LD_LIBRARY_PATH=${BLS_DIR}/lib:${MCL_DIR}/lib
ENV PATH="/root/bin:${PATH}"
RUN set -eux; \
DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get upgrade -y && \
apt install -y libgmp-dev libssl-dev curl git \
psmisc dnsutils jq make gcc g++ bash tig tree sudo vim \
silversearcher-ag unzip emacs-nox nano bash-completion
RUN mkdir ~/bin && \
mkdir /root/workspace
RUN git clone https://github.com/harmony-one/harmony.git ${HMY_PATH}/harmony
RUN git clone https://github.com/harmony-one/bls.git ${HMY_PATH}/bls
RUN git clone https://github.com/harmony-one/mcl.git ${HMY_PATH}/mcl
RUN git clone https://github.com/harmony-one/go-sdk.git ${HMY_PATH}/go-sdk
RUN cd ${HMY_PATH}/bls && make -j8 BLS_SWAP_G=1
RUN touch /root/.bash_profile && \
echo "GO111MODULE='on'" >> /root/.bash_profile && \
echo ". ~/.bash_profile" >> /root/.profile && \
echo ". ~/.bash_profile" >> /root/.bashrc
ENV GOPATH=$GOPATH
ENV PATH="${GOPATH}/bin:${PATH}"
RUN . ~/.bash_profile; \
go get -u golang.org/x/tools/cmd/goimports; \
go get -u golang.org/x/lint/golint ; \
go get -u github.com/rogpeppe/godef ; \
go get -u github.com/go-delve/delve/cmd/dlv; \
go get -u github.com/golang/mock/mockgen; \
go get -u github.com/stamblerre/gocode; \
go get -u golang.org/x/tools/...
RUN . ~/.bash_profile; \
go get -u honnef.co/go/tools/cmd/staticcheck/...
WORKDIR ${HMY_PATH}/harmony
# TODO remove once `install_protoc.sh` changes are committed
COPY scripts scripts
RUN scripts/install_build_tools.sh
RUN go mod tidy
RUN scripts/go_executable_build.sh -S
RUN cd ${HMY_PATH}/go-sdk && \
make -j8 && \
cp hmy /root/bin
ARG K1=one1tq4hy947c9gr8qzv06yxz4aeyhc9vn78al4rmu
ARG K2=one1y5gmmzumajkm5mx3g2qsxtza2d3haq0zxyg47r
ARG K3=one1qrqcfek6sc29sachs3glhs4zny72mlad76lqcp
ARG KS1=8d222cffa99eb1fb86c581d9dfe7d60dd40ec62aa29056b7ff48028385270541
ARG KS2=da1800da5dedf02717696675c7a7e58383aff90b1014dfa1ab5b7bd1ce3ef535
ARG KS3=f4267bb5a2f0e65b8f5792bb6992597fac2b35ebfac9885ce0f4152c451ca31a
RUN hmy keys import-private-key ${KS1}
RUN hmy keys import-private-key ${KS2}
RUN hmy keys import-private-key ${KS3}
RUN hmy keys generate-bls-key > keys.json
RUN jq '.["encrypted-private-key-path"]' -r keys.json > /root/keypath && cp keys.json /root && \
echo "export BLS_KEY_PATH=$(cat /root/keypath)" >> /root/.bashrc && \
echo "export BLS_KEY=$(jq '.["public-key"]' -r keys.json)" >> /root/.bashrc && \
echo "printf '${K1}, ${K2}, ${K3} are imported accounts in hmy for local dev\n\n'" >> /root/.bashrc && \
echo "printf 'test with: hmy blockchain validator information ${K1}\n\n'" >> /root/.bashrc && \
echo "echo "$(jq '.["public-key"]' -r keys.json)" is an extern bls key" >> /root/.bashrc && \
echo ". /etc/bash_completion" >> /root/.bashrc && \
echo ". <(hmy completion)" >> /root/.bashrc
#!/usr/bin/env bash
set -eu
unset -v opt OPTIND OPTARG version platform destdir
version=
platform=
destdir=/usr/local
usage() {
case $# in
[1-9]*) echo "$@" >&2;;
esac
cat <<- ENDEND
usage: install_protoc.sh [-P platform] [-d destdir] -V version
options:
-V version protobuf version
-P platform fetch and use given platform (default: autodetect)
-d destdir install into the given dir (default: /usr/local)
-h print this help
ENDEND
exit 64
}
while getopts :V:P:d:h opt
do
case "${opt}" in
V) version="${OPTARG}";;
P) platform="${OPTARG}";;
d) destdir="${OPTARG}";;
h) usage;;
"?") usage "unrecognized option -${OPTARG}";;
":") usage "missing argument for -${OPTARG}";;
*) echo "unhandled option -${OPTARG}" >&2; exit 70;;
esac
done
shift $((${OPTIND} - 1))
case "${version}" in
"") usage "protobuf version (-V) not specified";;
esac
case "${platform}" in
"")
platform=$(uname -s)
case "${platform}" in
Darwin) platform=osx;;
Linux) platform=linux;;
*) echo "unsupported OS name (${platform})" >&2; exit 69;;
esac
arch=$(uname -m)
case "${arch}" in
aarch64) arch=aarch_64;;
esac
platform="${platform}-${arch}"
;;
esac
unset -v tmpdir
trap 'case "${tmpdir-}" in ?*) rm -rf "${tmpdir}";; esac' EXIT
tmpdir=$(mktemp -d)
cd "${tmpdir}"
unset -v filename url
filename="protoc-${version}-${platform}.zip"
url="https://github.com/protocolbuffers/protobuf/releases/download/v${version}/${filename}"
echo "Downloading protoc v${version} for ${platform}..."
curl -s -S -L -o "${filename}" "${url}"
echo "Downloaded as ${filename}; unzipping into ${destdir}..."
sudo unzip -o -d "${destdir}" "${filename}"
echo "protoc v${version} has been installed in ${destdir}."
sudo chmod +x "${destdir}/bin/protoc"
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment