From 73242111ad32eb1d3a9fb8a6f3689625970b41d7 Mon Sep 17 00:00:00 2001 From: Jonathan Cobb Date: Thu, 3 Dec 2020 22:48:03 -0500 Subject: [PATCH] add docker slim image --- Dockerfile | 1 - Dockerfile.slim | 72 +++++++++++++++++++ bin/install_packer.sh | 2 +- bin/jenkins/push_docker | 36 ++++++---- .../META-INF/bubble/bubble.properties | 2 +- docker/bubble.sh | 33 ++++++--- docker/run_bubble_slim.sh | 23 ++++++ 7 files changed, 144 insertions(+), 25 deletions(-) create mode 100644 Dockerfile.slim create mode 100755 docker/run_bubble_slim.sh diff --git a/Dockerfile b/Dockerfile index b61ec67d..c17daa59 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,6 @@ LABEL license="https://getbubblenow.com/license" RUN apt update -y RUN DEBIAN_FRONTEND=noninteractive apt upgrade -y --no-install-recommends RUN DEBIAN_FRONTEND=noninteractive apt install openjdk-11-jre-headless postgresql redis-server jq python3 python3-pip curl unzip -y --no-install-recommends -RUN DEBIAN_FRONTEND=noninteractive apt install xtail -y --no-install-recommends RUN pip3 install setuptools psycopg2-binary ################# diff --git a/Dockerfile.slim b/Dockerfile.slim new file mode 100644 index 00000000..4bf4cde7 --- /dev/null +++ b/Dockerfile.slim @@ -0,0 +1,72 @@ +# +# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ +# +# Creates a Docker image that runs the Bubble Launcher. You shouldn't have to use this file directly. +# +# This is the "slim" version, which is about 200MB smaller than the full version. +# +# Slim means: +# - We don't run `apt upgrade` and continue on with default packages (slightly risky) +# - We don't install packer. it gets installed the first time the image is run +# - We don't install the Bubble jar. it gets downloaded and installed the first time the image is run +# +FROM phusion/baseimage:focal-1.0.0alpha1-amd64 +MAINTAINER jonathan@getbubblenow.com +LABEL maintainer="jonathan@getbubblenow.com" +LABEL license="https://getbubblenow.com/license" + +# Install packages +RUN apt update -y +#RUN DEBIAN_FRONTEND=noninteractive apt upgrade -y --no-install-recommends +RUN DEBIAN_FRONTEND=noninteractive apt install openjdk-11-jre-headless postgresql redis-server jq python3 python3-pip curl unzip -y --no-install-recommends +RUN pip3 install setuptools psycopg2-binary + +################# +### Redis +################# +# Ensure redis runs in foreground +RUN bash -c "sed -i -e 's/daemonize yes/daemonize no/g' /etc/redis/redis.conf" + +# Setup redis service +RUN mkdir /etc/service/redis +COPY docker/run_redis.sh /etc/service/redis/run + +################# +### PostgreSQL +################# +# trust local postgresql users +RUN bash -c "sed -i -e 's/ md5/ trust/g' $(find /etc/postgresql -mindepth 1 -maxdepth 1 -type d | sort | tail -1)/main/pg_hba.conf" + +# Create "root" postgres user and bubble database +RUN bash -c "service postgresql start && sleep 5s && service postgresql status && \ + su - postgres bash -c 'createuser -h 127.0.0.1 -U postgres --createdb --createrole --superuser root' && \ + su - postgres bash -c 'createuser -h 127.0.0.1 -U postgres --createdb bubble'" + +# Setup PostgreSQL service +RUN mkdir /etc/service/postgresql +COPY docker/run_postgresql.sh /etc/service/postgresql/run + +################# +### Bubble +################# +# Install packer +RUN mkdir /bubble +COPY bin/install_packer.sh /usr/local/bin/ +#RUN /usr/local/bin/install_packer.sh + +# Install API jar and env file +#COPY bubble-server/target/bubble-server-*.jar /bubble/bubble.jar +COPY docker/bubble.env /bubble/bubble.env + +# Setup Bubble service +RUN mkdir /etc/service/bubble +COPY docker/run_bubble_slim.sh /etc/service/bubble/run + +################# +### Main stuff +################# +# Expose bubble port +EXPOSE 8090 + +# Phusion baseimage runs the services created above +CMD ["/sbin/my_init"] diff --git a/bin/install_packer.sh b/bin/install_packer.sh index 10b0902e..0c36860b 100755 --- a/bin/install_packer.sh +++ b/bin/install_packer.sh @@ -42,7 +42,7 @@ if [[ ! -f ${HOME}/.packer.d/plugins/packer-builder-vultr ]] ; then fi PACKER_VULTR_URL=https://github.com/vultr/packer-builder-vultr/releases/download/v${PACKER_VULTR_VERSION}/${PACKER_VULTR_FILE} mkdir -p ${HOME}/.packer.d/plugins && cd ${HOME}/.packer.d/plugins && curl -L ${PACKER_VULTR_URL} -o ${PACKER_VULTR_FILE} && tar xzf ${PACKER_VULTR_FILE} || die "Error installing packer vultr plugin" - echo "Packer Vult plugin successfully installed" + echo "Packer Vultr plugin successfully installed" else echo "Packer vultr plugin already installed" fi diff --git a/bin/jenkins/push_docker b/bin/jenkins/push_docker index 6d55f962..cc054ce3 100755 --- a/bin/jenkins/push_docker +++ b/bin/jenkins/push_docker @@ -48,30 +48,40 @@ set +x THISDIR="$(cd "$(dirname "${0}")" && pwd)" BUBBLE_DIR="$(cd "${THISDIR}/../.." && pwd)" -echo "Logging in to docker ..." +echo ">>> Logging in to docker ..." echo -n "${BUBBLE_DOCKER_PASS}" | docker login -u "${BUBBLE_DOCKER_USER}" --password-stdin || die "Error logging in to docker" -echo "Determining Bubble version ..." +echo ">>> Determining Bubble version ..." META_FILE="${BUBBLE_DIR}/bubble-server/src/main/resources/META-INF/bubble/bubble.properties" VERSION="$(cat "${META_FILE}" | grep bubble.version | awk -F '=' '{print $2}' | awk -F ' ' '{print $NF}' | awk '{$1=$1};1')" if [[ -z "${VERSION}" ]] ; then die "Error determining version from: ${META_FILE}" fi -echo "Found Bubble version ${VERSION}" +echo ">>> Found Bubble version ${VERSION}" -echo "Building docker bubble version ${VERSION} ..." +echo ">>> Building docker bubble version ${VERSION} ..." BUBBLE_DOCKER="${BUBBLE_DIR}/docker/bubble.sh" ${BUBBLE_DOCKER} build || die "Error building docker image" -echo "Checking to see if version ${VERSION} already exists on dockerhub..." ensure_docker_experimental_enabled -if docker manifest inspect "getbubble/launcher:${VERSION}" > /dev/null 2> /dev/null ; then - echo "Version ${VERSION} already exists on dockerhub, not re-publishing" - exit 0 -fi - -echo "Version ${VERSION} does not exist on dockerhub, pushing it ..." +BUBBLE_TAG="getbubble/launcher:${VERSION}" +BUBBLE_SLIM_TAG="getbubble/slim-launcher:${VERSION}" -${BUBBLE_DOCKER} push || die "Error pushing docker image" +echo ">>> Checking to see if ${BUBBLE_TAG} already exists on dockerhub..." +if docker manifest inspect "${BUBBLE_TAG}" > /dev/null 2> /dev/null ; then + echo ">>> ${BUBBLE_TAG} already exists on dockerhub, not re-publishing" +else + echo ">>> ${BUBBLE_TAG} does not exist on dockerhub, pushing it ..." + ${BUBBLE_DOCKER} push "${BUBBLE_TAG}" || die "Error pushing ${BUBBLE_TAG}" + echo ">>> Successfully pushed to dockerhub: ${BUBBLE_TAG}" +fi -echo "Successfully pushed to dockerhub: ${VERSION}" +echo ">>> Checking to see if ${BUBBLE_SLIM_TAG} already exists on dockerhub..." +if docker manifest inspect "${BUBBLE_SLIM_TAG}" > /dev/null 2> /dev/null ; then + echo ">>> ${BUBBLE_SLIM_TAG} already exists on dockerhub, not re-publishing" + exit 0 +else + echo ">>> ${BUBBLE_SLIM_TAG} does not exist on dockerhub, pushing it ..." + ${BUBBLE_DOCKER} push "${BUBBLE_SLIM_TAG}" || die "Error pushing docker ${BUBBLE_SLIM_TAG}" + echo ">>> Successfully pushed to dockerhub: slim ${VERSION}" +fi diff --git a/bubble-server/src/main/resources/META-INF/bubble/bubble.properties b/bubble-server/src/main/resources/META-INF/bubble/bubble.properties index 82ca7cdd..66ff2e75 100644 --- a/bubble-server/src/main/resources/META-INF/bubble/bubble.properties +++ b/bubble-server/src/main/resources/META-INF/bubble/bubble.properties @@ -1 +1 @@ -bubble.version=Adventure 1.4.43 +bubble.version=Adventure 1.4.46 diff --git a/docker/bubble.sh b/docker/bubble.sh index d8db8d0a..8c24aa73 100755 --- a/docker/bubble.sh +++ b/docker/bubble.sh @@ -7,14 +7,21 @@ # bubble.sh [mode] [version] # # mode : build, run or push -# build - build the docker image -# run - run the docker image -# push - push to docker hub +# build - build the docker images +# run - run a docker image. set the BUBBLE_RUN_SLIM env var to `true` to run the slim image. +# push - push images docker hub # # version : version to use, default is read from bubble-server/src/main/resources/META-INF/bubble/bubble.properties # # The docker tag used will be getbubble/launcher:version # +# We build two images, a full one and a slim one. +# The full image is larger (will take longer to download), but will startup faster. +# The slim image is smaller (will be faster to download), but will take longer to start up. +# +# The full image has the Bubble jar, updated packages and packer pre-installed. +# The slim image has default packages and installs packer and the Bubble jar when it first runs. +# # If you want to change the "getbubble/launcher" part of the Docker tag, set the BUBBLE_DOCKER_REPO # environment variable in your shell environment. # @@ -36,15 +43,16 @@ BUBBLE_DIR="$(cd "${THISDIR}/.." && pwd)" MODE=${1:?no mode specified, use build or run} META_FILE="${BUBBLE_DIR}/bubble-server/src/main/resources/META-INF/bubble/bubble.properties" -VERSION="${2:-$(cat ${META_FILE} | grep bubble.version | awk -F '=' '{print $2}' | awk -F ' ' '{print $NF}' | awk '{$1=$1};1')}" +VERSION="${2:-$(cat "${META_FILE}" | grep bubble.version | awk -F '=' '{print $2}' | awk -F ' ' '{print $NF}' | awk '{$1=$1};1')}" if [[ -z "${VERSION}" ]] ; then die "Error determining version from: ${META_FILE}" fi -DOCKER_REPO="getbubble/launcher" +DOCKER_REPO="getbubble" if [[ ! -z "${BUBBLE_DOCKER_REPO}" ]] ; then DOCKER_REPO="${BUBBLE_DOCKER_REPO}" fi -BUBBLE_TAG="${DOCKER_REPO}:${VERSION}" +BUBBLE_TAG="${DOCKER_REPO}/launcher:${VERSION}" +BUBBLE_SLIM_TAG="${DOCKER_REPO}/slim-launcher:${VERSION}" BUBBLE_ENV="${HOME}/.bubble.env" @@ -52,7 +60,8 @@ if [[ "${MODE}" == "build" ]] ; then if [[ $(find bubble-server/target -type f -name "bubble-server-*.jar" | wc -l | tr -d ' ') -eq 0 ]] ; then die "No bubble jar found in $(pwd)/bubble-server/target" fi - docker build -t ${BUBBLE_TAG} . || die "Error building docker image" + docker build -t "${BUBBLE_TAG}" . || die "Error building docker image" + docker build -f Dockerfile.slim -t "${BUBBLE_SLIM_TAG}" . || die "Error building slim docker image" elif [[ "${MODE}" == "run" ]] ; then if [[ $(cat "${BUBBLE_ENV}" | grep -v '^#' | grep -c LETSENCRYPT_EMAIL) -eq 0 ]] ; then @@ -64,10 +73,16 @@ elif [[ "${MODE}" == "run" ]] ; then export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} " >> "${BUBBLE_ENV}" fi - docker run --env-file <(cat "${BUBBLE_ENV}" | sed -e 's/export //' | tr -d '"' | tr -d "'") -p 8090:8090 -t ${BUBBLE_TAG} || die "Error running docker container" + if [[ ! -z "${BUBBLE_RUN_SLIM}" && "${BUBBLE_RUN_SLIM}" == "true" ]] ; then + RUN_TAG="${BUBBLE_SLIM_TAG}" + else + RUN_TAG="${BUBBLE_TAG}" + fi + docker run --env-file <(cat "${BUBBLE_ENV}" | sed -e 's/export //' | tr -d '"' | tr -d "'") -p 8090:8090 -t "${RUN_TAG}" || die "Error running docker container" elif [[ "${MODE}" == "push" ]] ; then - docker push ${BUBBLE_TAG} || die "Error pushing docker image" + docker push "${BUBBLE_TAG}" || die "Error pushing docker image" + docker push "${BUBBLE_SLIM_TAG}" || die "Error pushing slim docker image" else die "Invalid mode (expected build or run): ${MODE}" diff --git a/docker/run_bubble_slim.sh b/docker/run_bubble_slim.sh new file mode 100755 index 00000000..d9691773 --- /dev/null +++ b/docker/run_bubble_slim.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ +# + +/usr/local/bin/install_packer.sh || (echo "Error ensuring Packer is installed" ; exit 1) + +LATEST_BUBBLE_JAR_URL=https://jenkins.bubblev.org/public/releases/bubble/latest/bubble.zip +BUBBLE_JAR=/bubble/bubble.jar + +if [[ ! -f ${BUBBLE_JAR} ]] ; then + BUBBLE_JAR_TEMP="$(mktemp ${BUBBLE_JAR}.temp.XXXXXX)" + curl -s ${LATEST_BUBBLE_JAR_URL} > "${BUBBLE_JAR_TEMP}" || (echo "Error downloading bubble.jar from ${LATEST_BUBBLE_JAR_URL}" ; exit 1) + unzip "${BUBBLE_JAR_TEMP}" '**/bubble.jar' -d /bubble || (echo "Error extracting bubble.jar" ; exit 1) + mv "$(find /bubble -type f -name bubble.jar)" ${BUBBLE_JAR} || (echo "Error moving bubble.jar into place" ; exit 1) +fi + +/usr/bin/java \ + -Dfile.encoding=UTF-8 -Djava.net.preferIPv4Stack=true -Dbubble.listenAll=true \ + -XX:+UseG1GC -XX:MaxGCPauseMillis=400 \ + -cp /bubble/bubble.jar \ + bubble.server.BubbleServer \ + /bubble/bubble.env