diff --git a/.circleci/config.yml b/.circleci/config.yml index 22655a3974..1b6e5d0836 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -169,9 +169,17 @@ jobs: at: ~/project - setup_remote_docker - run: - name: hadoLint + name: hadoLint_openjdk_11 command: | - docker run --rm -i hadolint/hadolint < docker/Dockerfile + docker run --rm -i hadolint/hadolint < docker/openjdk-11/Dockerfile + - run: + name: hadoLint_openjdk_latest + command: | + docker run --rm -i hadolint/hadolint < docker/openjdk-latest/Dockerfile + - run: + name: hadoLint_graalvm + command: | + docker run --rm -i hadolint/hadolint < docker/graalvm/Dockerfile - run: name: build image command: | diff --git a/build.gradle b/build.gradle index f96f3b5c6f..1dd48b8e88 100644 --- a/build.gradle +++ b/build.gradle @@ -544,6 +544,12 @@ distZip { } } +def dockerVariants = [ + "openjdk-11", + "graalvm", + "openjdk-latest" +] + // rename the top level dir from besu- to besu and this makes it really // simple for use in docker tasks.register("dockerDistUntar") { @@ -563,46 +569,60 @@ tasks.register("dockerDistUntar") { } } -task distDocker(type: Exec) { +task distDocker { dependsOn dockerDistUntar + inputs.dir("build/docker-besu/") def dockerBuildVersion = project.hasProperty('release.releaseVersion') ? project.property('release.releaseVersion') : "${rootProject.version}" - def imageName = "hyperledger/besu" - def image = "${imageName}:${dockerBuildVersion}" def dockerBuildDir = "build/docker-besu/" - workingDir "${dockerBuildDir}" + def imageName = "hyperledger/besu" - doFirst { - copy { - from file("${projectDir}/docker/Dockerfile") - into(workingDir) + doLast { + for (def variant in dockerVariants) { + copy { + from file("${projectDir}/docker/${variant}/Dockerfile") + into(dockerBuildDir) + } + exec { + def image = "${imageName}:${dockerBuildVersion}-${variant}" + executable "sh" + workingDir dockerBuildDir + args "-c", "docker build --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${getCheckedOutGitCommitHash()} -t ${image} ." + } + } + // tag the "default" (which is the variant in the zero position) + exec { + executable "sh" + args "-c", "docker tag '${imageName}:${dockerBuildVersion}-${dockerVariants[0]}' '${imageName}:${dockerBuildVersion}'" } } - - executable "sh" - args "-c", "docker build --build-arg BUILD_DATE=${buildTime()} --build-arg VERSION=${dockerBuildVersion} --build-arg VCS_REF=${getCheckedOutGitCommitHash()} -t ${image} ." } -task testDocker(type: Exec) { +task testDocker { dependsOn distDocker def dockerReportsDir = "docker/reports/" - def image = project.hasProperty('release.releaseVersion') ? "hyperledger/besu:" + project.property('release.releaseVersion') : "hyperledger/besu:${project.version}" - workingDir "docker" doFirst { new File(dockerReportsDir).mkdir() } - executable "sh" - args "-c", "bash test.sh ${image}" + doLast { + for (def variant in dockerVariants) { + exec { + def image = project.hasProperty('release.releaseVersion') ? "hyperledger/besu:" + project.property('release.releaseVersion') : "hyperledger/besu:${project.version}" + workingDir "docker/${variant}" + executable "sh" + args "-c", "bash ../test.sh ${image}-${variant}" + } + } + } } -task dockerUpload(type: Exec) { +task dockerUpload { dependsOn distDocker def dockerBuildVersion = project.hasProperty('release.releaseVersion') ? project.property('release.releaseVersion') : "${rootProject.version}" def imageName = "hyperledger/besu" def azureImageName = "hyperledger.azurecr.io/besu" def image = "${imageName}:${dockerBuildVersion}" - def cmd = "docker push '${image}'" def additionalTags = [] if (project.hasProperty('branch') && project.property('branch') == 'master') { @@ -614,12 +634,29 @@ task dockerUpload(type: Exec) { additionalTags.add(dockerBuildVersion.split(/\./)[0..1].join('.')) } - additionalTags.each { tag -> - cmd += " && docker tag '${image}' '${imageName}:${tag.trim()}' && docker push '${imageName}:${tag.trim()}'" - cmd += " && docker tag '${image}' '${azureImageName}:${tag.trim()}' && docker push '${azureImageName}:${tag.trim()}'" + doLast { + for (def variant in dockerVariants) { + def variantImage = "${image}-${variant}" + exec { + def cmd = "docker push '${variantImage}'" + additionalTags.each { tag -> + cmd += " && docker tag '${variantImage}' '${imageName}:${tag.trim()}-${variant}' && docker push '${imageName}:${tag.trim()}-${variant}'" + } + executable "sh" + args "-c", cmd + } + } + + exec { + def cmd = "docker push '${image}'" + additionalTags.each { tag -> + cmd += " && docker tag '${image}' '${imageName}:${tag.trim()}' && docker push '${imageName}:${tag.trim()}'" + cmd += " && docker tag '${image}' '${azureImageName}:${tag.trim()}' && docker push '${azureImageName}:${tag.trim()}'" + } + executable "sh" + args "-c", cmd + } } - executable "sh" - args "-c", cmd } task checkSpdxHeader(type: CheckSpdxHeader) { diff --git a/docker/graalvm/Dockerfile b/docker/graalvm/Dockerfile new file mode 100644 index 0000000000..c12c259bbe --- /dev/null +++ b/docker/graalvm/Dockerfile @@ -0,0 +1,41 @@ + +FROM oracle/graalvm-ce:20.1.0-java11 + +RUN adduser --home /opt/besu besu && \ + chown besu:besu /opt/besu + +USER besu +WORKDIR /opt/besu + +COPY --chown=besu:besu besu /opt/besu/ + +# Expose services ports +# 8545 HTTP JSON-RPC +# 8546 WS JSON-RPC +# 8547 HTTP GraphQL +# 30303 P2P +EXPOSE 8545 8546 8547 30303 + +# defaults for host interfaces +ENV BESU_RPC_HTTP_HOST 0.0.0.0 +ENV BESU_RPC_WS_HOST 0.0.0.0 +ENV BESU_GRAPHQL_HTTP_HOST 0.0.0.0 +ENV BESU_PID_PATH "/tmp/pid" + +ENV PATH="/opt/besu/bin:${PATH}" +ENTRYPOINT ["besu"] +HEALTHCHECK --start-period=5s --interval=5s --timeout=1s --retries=10 CMD bash -c "[ -f /tmp/pid ]" + +# Build-time metadata as defined at http://label-schema.org +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="Besu" \ + org.label-schema.description="Enterprise Ethereum client" \ + org.label-schema.url="https://besu.hyperledger.org/" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/hyperledger/besu.git" \ + org.label-schema.vendor="Hyperledger" \ + org.label-schema.version=$VERSION \ + org.label-schema.schema-version="1.0" \ No newline at end of file diff --git a/docker/Dockerfile b/docker/openjdk-11/Dockerfile similarity index 100% rename from docker/Dockerfile rename to docker/openjdk-11/Dockerfile diff --git a/docker/openjdk-latest/Dockerfile b/docker/openjdk-latest/Dockerfile new file mode 100644 index 0000000000..69f7ae0d6f --- /dev/null +++ b/docker/openjdk-latest/Dockerfile @@ -0,0 +1,41 @@ + +FROM openjdk:slim-buster + +RUN adduser --disabled-password --gecos "" --home /opt/besu besu && \ + chown besu:besu /opt/besu + +USER besu +WORKDIR /opt/besu + +COPY --chown=besu:besu besu /opt/besu/ + +# Expose services ports +# 8545 HTTP JSON-RPC +# 8546 WS JSON-RPC +# 8547 HTTP GraphQL +# 30303 P2P +EXPOSE 8545 8546 8547 30303 + +# defaults for host interfaces +ENV BESU_RPC_HTTP_HOST 0.0.0.0 +ENV BESU_RPC_WS_HOST 0.0.0.0 +ENV BESU_GRAPHQL_HTTP_HOST 0.0.0.0 +ENV BESU_PID_PATH "/tmp/pid" + +ENV PATH="/opt/besu/bin:${PATH}" +ENTRYPOINT ["besu"] +HEALTHCHECK --start-period=5s --interval=5s --timeout=1s --retries=10 CMD bash -c "[ -f /tmp/pid ]" + +# Build-time metadata as defined at http://label-schema.org +ARG BUILD_DATE +ARG VCS_REF +ARG VERSION +LABEL org.label-schema.build-date=$BUILD_DATE \ + org.label-schema.name="Besu" \ + org.label-schema.description="Enterprise Ethereum client" \ + org.label-schema.url="https://besu.hyperledger.org/" \ + org.label-schema.vcs-ref=$VCS_REF \ + org.label-schema.vcs-url="https://github.com/hyperledger/besu.git" \ + org.label-schema.vendor="Hyperledger" \ + org.label-schema.version=$VERSION \ + org.label-schema.schema-version="1.0" \ No newline at end of file diff --git a/docker/test.sh b/docker/test.sh index 41bad75ef9..8058a0400a 100755 --- a/docker/test.sh +++ b/docker/test.sh @@ -1,6 +1,7 @@ #!/bin/bash -export GOSS_PATH=tests/goss-linux-amd64 +export TEST_PATH=../tests +export GOSS_PATH=$TEST_PATH/goss-linux-amd64 export GOSS_OPTS="$GOSS_OPTS --format junit" export GOSS_FILES_STRATEGY=cp DOCKER_IMAGE=$1 @@ -9,21 +10,21 @@ DOCKER_FILE="${2:-$PWD/Dockerfile}" i=0 ## Checks on the Dockerfile -GOSS_FILES_PATH=tests/00 \ -bash tests/dgoss dockerfile $DOCKER_IMAGE $DOCKER_FILE \ -> ./reports/00.xml || i=`expr $i + 1` +GOSS_FILES_PATH=$TEST_PATH/00 \ +bash $TEST_PATH/dgoss dockerfile $DOCKER_IMAGE $DOCKER_FILE \ +> ../reports/00.xml || i=`expr $i + 1` # fail fast if we dont pass static checks if [[ $i != 0 ]]; then exit $i; fi # Test for normal startup with ports opened # we test that things listen on the right interface/port, not what interface the advertise # hence we dont set p2p-host=0.0.0.0 because this sets what its advertising to devp2p; the important piece is that it defaults to listening on all interfaces -GOSS_FILES_PATH=tests/01 \ -bash tests/dgoss run $DOCKER_IMAGE \ +GOSS_FILES_PATH=$TEST_PATH/01 \ +bash $TEST_PATH/dgoss run $DOCKER_IMAGE \ --network=dev \ --rpc-http-enabled \ --rpc-ws-enabled \ --graphql-http-enabled \ -> ./reports/01.xml || i=`expr $i + 1` +> ../reports/01.xml || i=`expr $i + 1` exit $i