#!/bin/bash # # Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ # # Build, run or push a docker container for a Bubble launcher. Intended for developer use. # # bdocker [mode] [version] # # mode : build, run or push # 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 # term - open a bash terminal on a running container # clean - remove containers and images related to the version # # 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. # # When using the 'run' mode, you'll be asked for an email address to associate with any LetsEncrypt # certificates that will be created. # # Upon successful startup, the bubble launcher will be listening on port 8090 # If you'd prefer to use a different port, set the BUBBLE_PORT environment variable. # # If you want to run this unattended, set the LETSENCRYPT_EMAIL environment variable # in your ~/.bubble.env file or in your shell environment. # # By default, this does not use the docker cache. If you want to use the cache, # set the BUBBLE_DOCKER_CACHE environment variable to any value. # SCRIPT="${0}" SCRIPT_DIR="$(cd "$(dirname "${SCRIPT}")" && pwd)" . "${SCRIPT_DIR}"/bubble_common BUBBLE_DIR="$(cd "${SCRIPT_DIR}"/.. && pwd)" MODE=${1:?no mode specified, use: build, run, term, push or clean} 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')}" if [[ -z "${VERSION}" ]] ; then die "Error determining version from: ${META_FILE}" fi DOCKER_REPO="getbubble" if [[ -n "${BUBBLE_DOCKER_REPO}" ]] ; then DOCKER_REPO="${BUBBLE_DOCKER_REPO}" fi REPO_LAUNCHER="${DOCKER_REPO}/launcher" BUBBLE_TAG="${REPO_LAUNCHER}:${VERSION}" REPO_SLIM_LAUNCHER="${DOCKER_REPO}/slim-launcher" BUBBLE_SLIM_TAG="${REPO_SLIM_LAUNCHER}:${VERSION}" BUBBLE_ENV="${HOME}/.bubble.env" CACHE="--no-cache" if [[ -n "${BUBBLE_DOCKER_CACHE}" ]] ; then CACHE="" fi EXPOSE="" if [[ -z "${BUBBLE_PORT}" ]] ; then BUBBLE_PORT=8090 else EXPOSE="--expose ${BUBBLE_PORT}" fi if [[ "${MODE}" == "build" ]] ; then if [[ $(find bubble-server/target -type f -name "bubble-server-*-prod.jar" | wc -l | tr -d ' ') -eq 0 ]] ; then die "No bubble jar found in $(pwd)/bubble-server/target" fi docker build ${CACHE} -t "${BUBBLE_TAG}" . || die "Error building docker image" docker build ${CACHE} -f Dockerfile.slim -t "${BUBBLE_SLIM_TAG}" . || die "Error building slim docker image" elif [[ "${MODE}" == "run" ]] ; then # Copy existing env if found ENV_FILE=$(mktemp /tmp/.bubble.env.XXXXXXX) if [[ -z "${BUBBLE_ENV}" ]] ; then BUBBLE_ENV="${HOME}/.bubble.env" fi if [[ -f "${BUBBLE_ENV}" ]] ; then cat "${BUBBLE_ENV}" > "${ENV_FILE}" fi # Define API port echo " export BUBBLE_SERVER_PORT=${BUBBLE_PORT} export PUBLIC_BASE_URI=http://127.0.0.1:${BUBBLE_PORT} " >> "${ENV_FILE}" # Define LetsEncrypt email, from env var or stdin if [[ $(cat "${BUBBLE_ENV}" | grep -v '^#' | grep -c LETSENCRYPT_EMAIL) -eq 0 ]] ; then if [[ -z "${LETSENCRYPT_EMAIL}" ]] ; then echo ; echo -n "Email address for LetsEncrypt certificates: " read -r LETSENCRYPT_EMAIL fi echo " export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}" >> "${ENV_FILE}" fi if [[ -n "${BUBBLE_RUN_SLIM}" && "${BUBBLE_RUN_SLIM}" == "true" ]] ; then RUN_TAG="${BUBBLE_SLIM_TAG}" else RUN_TAG="${BUBBLE_TAG}" fi DOCKER_ENV_FILE=$(mktemp /tmp/.docker.env.XXXXXX) cat "${ENV_FILE}" | sed -e 's/export //' | tr -d '"' | tr -d "'" > "${DOCKER_ENV_FILE}" docker run ${EXPOSE} --env-file "${DOCKER_ENV_FILE}" -p ${BUBBLE_PORT}:${BUBBLE_PORT} -t "${RUN_TAG}" rm -f "${ENV_FILE}" "${DOCKER_ENV_FILE}" elif [[ "${MODE}" == "push" ]] ; then docker push "${BUBBLE_TAG}" || die "Error pushing docker image" docker push "${BUBBLE_SLIM_TAG}" || die "Error pushing slim docker image" elif [[ "${MODE}" == "term" ]] ; then # Expect only one container running that matches BUBBLE_TAG CONTAINER_CT="$(docker container ls | grep -c "${BUBBLE_TAG}" | tr -d ' ')" if [[ -z "${CONTAINER_CT}" || "${CONTAINER_CT}" == "0" ]] ; then die "No docker container found with tag ${BUBBLE_TAG}" fi if [[ ${CONTAINER_CT} -gt 1 ]] ; then die "Multiple docker containers found with tag ${BUBBLE_TAG}" fi # Run bash in that container exec docker exec -it "$(docker container ls | grep "${BUBBLE_TAG}" | awk '{print $1}')" /bin/bash elif [[ "${MODE}" == "clean" ]] ; then # Remove containers docker container ls | grep "${BUBBLE_TAG}" | awk '{print $1}' | xargs docker container rm -f docker container ls | grep "${BUBBLE_SLIM_TAG}" | awk '{print $1}' | xargs docker container rm -f # Remove images docker image ls | grep "${REPO_LAUNCHER}" | grep "${VERSION}" | awk '{print $3}' | xargs docker image rm -f docker image ls | grep "${REPO_SLIM_LAUNCHER}" | grep "${VERSION}" | awk '{print $3}' | xargs docker image rm -f else die "$("${0}" --help) ***** invalid mode: ${MODE}" fi