diff --git a/.github/workflows/cd-release.yaml b/.github/workflows/cd-release.yaml index e5b575c191..9435e9c209 100644 --- a/.github/workflows/cd-release.yaml +++ b/.github/workflows/cd-release.yaml @@ -38,15 +38,17 @@ jobs: FILE: ${{ format('{0}/go/cmd/dolt/dolt.go', github.workspace) }} NEW_VERSION: ${{ needs.format-version.outputs.version }} - name: Update Dockerfile - run: sed -i -e 's/ARG DOLT_VERSION=.*/ARG DOLT_VERSION='"$NEW_VERSION"'/' "$AMD64" "$ARM64" + run: sed -i -e 's/ARG DOLT_VERSION=.*/ARG DOLT_VERSION='"$NEW_VERSION"'/' "$AMD64" "$ARM64" "$SERVERAMD64" "$SERVERARM64" env: AMD64: ${{ format('{0}/docker/Dockerfile', github.workspace) }} ARM64: ${{ format('{0}/docker/Dockerfile.arm64', github.workspace) }} + SERVERAMD64: ${{ format('{0}/docker/serverDockerfile', github.workspace) }} + SERVERARM64: ${{ format('{0}/docker/serverDockerfile.arm64', github.workspace) }} NEW_VERSION: ${{ needs.format-version.outputs.version }} - uses: EndBug/add-and-commit@v9.1.1 with: message: ${{ format('[ga-bump-release] Update Dolt version to {0} and release v{0}', needs.format-version.outputs.version) }} - add: ${{ format('[{0}/go/cmd/dolt/dolt.go,{0}/docker/Dockerfile,{0}/docker/Dockerfile.arm64]', github.workspace) }} + add: ${{ format('[{0}/go/cmd/dolt/dolt.go,{0}/docker/Dockerfile,{0}/docker/Dockerfile.arm64,{0}/docker/serverDockerfile,{0}/docker/serverDockerfile.arm64]', github.workspace) }} cwd: "." pull: "--ff" - name: Build Binaries diff --git a/docker/README.md b/docker/README.md index a2ca580843..c72a462bde 100644 --- a/docker/README.md +++ b/docker/README.md @@ -32,5 +32,18 @@ For example, we support `linux/amd64` and `linux/arm64`, so we need build for ta `0.50.4-arm64`, if the current release version is '0.50.4'. --- `COPY docker/qemu-aarch64-static /usr/bin/` is required for building (non x86 architecture image) in x86 host -before any RUN commands. \ No newline at end of file +-- `COPY docker/qemu-aarch64-static /usr/bin/` is required for building (non x86 architecture image) in x86 host +before any RUN commands. + + +--- WHY WE HAVE FIXED HOST=0.0.0.0 AND PORT=3306 --- + +Setting the localhost to either `localhost` or `127.0.0.1` does not allow connection from outside the container. + +According to MySQL ( https://dev.mysql.com/blog-archive/the-bind-address-option-now-supports-multiple-addresses/ ), +`Wildcard address values here means one of the following string values: '*', '::' and '0.0.0.0'` + +The default bind-address is `::` which Dolt does not support currently. It is the same as host `0.0.0.0`, which Dolt +supports. This means that any host remote connections will be allowed to connect to the server in the container. +User needs to use port-mapping to expose a certain port from the container using `-p 3307:3306`, which means port 3306 +in the container is mapped to port 3307 in host system. diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 0000000000..2e31bd4119 --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,162 @@ +#!/bin/bash +set -eo pipefail + +# logging functions +mysql_log() { + local type="$1"; shift + # accept argument string or stdin + local text="$*"; if [ "$#" -eq 0 ]; then text="$(cat)"; fi + local dt; dt="$(date --rfc-3339=seconds)" + printf '%s [%s] [Entrypoint]: %s\n' "$dt" "$type" "$text" +} +mysql_note() { + mysql_log Note "$@" +} +mysql_warn() { + mysql_log Warn "$@" >&2 +} +mysql_error() { + mysql_log ERROR "$@" >&2 + exit 1 +} + +CONTAINER_DATA_DIR="/var/lib/dolt" +DOLT_CONFIG_DIR="/etc/dolt/doltcfg.d" +SERVER_CONFIG_DIR="/etc/dolt/servercfg.d" +DOLT_ROOT_PATH="/.dolt" + +# create all dirs in path +_create_dir() { + local path="$1" + mkdir -p "$path" +} + +check_for_dolt() { + mysql_log "Verifying dolt executable..." + local dolt_bin=$(which dolt) + if [ ! -x "$dolt_bin" ]; then + mysql_error "dolt binary executable not found" + fi +} + +# check arguments for an option that would cause mysqld to stop +# return true if there is one +_mysql_want_help() { + local arg + for arg; do + case "$arg" in + -'?'|-h|--help) + return 0 + ;; + esac + done + return 1 +} + +# arg $1 is the directory to search in +# arg $2 is the type file to search for +get_config_file_path_if_exists() { + CONFIG_PROVIDED= + CONFIG_DIR=$1 + FILE_TYPE=$2 + if [ -d "$CONFIG_DIR" ]; then + mysql_log "Checking for config provided in $CONFIG_DIR" + number_of_files_found=( `find .$CONFIG_DIR -type f -name "*.$FILE_TYPE" | wc -l` ) + if [ $number_of_files_found -gt 1 ]; then + CONFIG_PROVIDED= + mysql_warn "multiple config file found in $CONFIG_DIR, using default config" + elif [ $number_of_files_found -eq 1 ]; then + files_found=( `ls $CONFIG_DIR/*$FILE_TYPE` ) + mysql_log "$files_found file is found" + CONFIG_PROVIDED=$files_found + else + CONFIG_PROVIDED= + fi + fi +} + +# taken from https://github.com/docker-library/mysql/blob/master/8.0/docker-entrypoint.sh +# this function will run files found in /docker-entrypoint-initdb.d directory AFTER server is started +# usage: docker_process_init_files [file [file [...]]] +# ie: docker_process_init_files /always-initdb.d/* +# process initializer files, based on file extensions +docker_process_init_files() { + echo + local f + for f; do + case "$f" in + *.sh) + # https://github.com/docker-library/postgres/issues/450#issuecomment-393167936 + # https://github.com/docker-library/postgres/pull/452 + if [ -x "$f" ]; then + mysql_note "$0: running $f" + "$f" + else + mysql_note "$0: sourcing $f" + . "$f" + fi + ;; + *.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;; + *.sql.bz2) mysql_note "$0: running $f"; bunzip2 -c "$f" | docker_process_sql; echo ;; + *.sql.gz) mysql_note "$0: running $f"; gunzip -c "$f" | docker_process_sql; echo ;; + *.sql.xz) mysql_note "$0: running $f"; xzcat "$f" | docker_process_sql; echo ;; + *.sql.zst) mysql_note "$0: running $f"; zstd -dc "$f" | docker_process_sql; echo ;; + *) mysql_warn "$0: ignoring $f" ;; + esac + echo + done +} + +start_server() { + # start the server in fixed data directory at /var/lib/dolt + cd $CONTAINER_DATA_DIR + "$@" +} + +# if there is config file provided through /etc/dolt/doltcfg.d, +# we overwrite $HOME/.dolt/config_global.json file with this file. +set_dolt_config_if_defined() { + get_config_file_path_if_exists "$DOLT_CONFIG_DIR" "json" + if [ ! -z $CONFIG_PROVIDED ]; then + /bin/cp -rf $CONFIG_PROVIDED $HOME/$DOLT_ROOT_PATH/config_global.json + fi +} + +_main() { + # check for dolt binary executable + check_for_dolt + + if [ "${1:0:1}" = '-' ]; then + # if there is any command line argument defined we use + # them with default command `dolt sql-server --host=0.0.0.0 --port=3306` + # why we use fixed host=0.0.0.0 and port=3306 in README + set -- dolt sql-server --host=0.0.0.0 --port=3306 "$@" + fi + + if [ "$1" = 'dolt' ] && [ "$2" = 'sql-server' ] && ! _mysql_want_help "$@"; then + local dolt_version=$(dolt version | grep 'dolt version' | cut -f3 -d " ") + mysql_note "Entrypoint script for Dolt Server $dolt_version starting." + + declare -g CONFIG_PROVIDED + + # dolt config will be set if user provided a single json file in /etc/dolt/doltcfg.d directory. + # It will overwrite config_global.json file in $HOME/.dolt + set_dolt_config_if_defined + + # if there is a single yaml provided in /etc/dolt/servercfg.d directory, + # it will be used to start the server with --config flag + get_config_file_path_if_exists "$SERVER_CONFIG_DIR" "yaml" + if [ ! -z $CONFIG_PROVIDED ]; then + set -- "$@" --config=$CONFIG_PROVIDED + fi + start_server + + # run any file provided in /docker-entrypoint-initdb.d directory after the server starts + docker_process_init_files /docker-entrypoint-initdb.d/* + + mysql_note "Dolt Server $dolt_version is started." + fi + exec "$@" +} + +_main "$@" diff --git a/docker/hooks/post_checkout b/docker/hooks/post_checkout index 57aa949c31..1a5d3ef1b5 100644 --- a/docker/hooks/post_checkout +++ b/docker/hooks/post_checkout @@ -7,6 +7,9 @@ BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2) [ "${BUILD_ARCH}" == "docker/Dockerfile" ] && \ { echo 'qemu-user-static: Download not required for current arch'; exit 0; } +[ "${BUILD_ARCH}" == "docker/serverDockerfile" ] && \ + { echo 'qemu-user-static: Download not required for current arch'; exit 0; } + case ${BUILD_ARCH} in amd64 ) QEMU_ARCH="x86_64" ;; arm64 ) QEMU_ARCH="aarch64" ; diff --git a/docker/hooks/pre_build b/docker/hooks/pre_build index 17bb08dcc5..1ecb2caa28 100644 --- a/docker/hooks/pre_build +++ b/docker/hooks/pre_build @@ -6,4 +6,7 @@ BUILD_ARCH=$(echo "${DOCKERFILE_PATH}" | cut -d '.' -f 2) [ "${BUILD_ARCH}" == "docker/Dockerfile" ] && \ { echo 'qemu-user-static: Registration not required for current arch'; exit 0; } +[ "${BUILD_ARCH}" == "docker/serverDockerfile" ] && \ + { echo 'qemu-user-static: Registration not required for current arch'; exit 0; } + docker run --rm --privileged multiarch/qemu-user-static:register --reset diff --git a/docker/serverDockerfile b/docker/serverDockerfile new file mode 100644 index 0000000000..8288cd0e1b --- /dev/null +++ b/docker/serverDockerfile @@ -0,0 +1,22 @@ +# syntax=docker/dockerfile:1.3-labs +FROM --platform=linux/amd64 ubuntu:22.04 as builder + +ARG DOLT_VERSION=0.50.8 + +ADD https://github.com/dolthub/dolt/releases/download/v${DOLT_VERSION}/dolt-linux-amd64.tar.gz dolt-linux-amd64.tar.gz +RUN tar zxvf dolt-linux-amd64.tar.gz && \ + cp dolt-linux-amd64/bin/dolt /usr/local/bin && \ + rm -rf dolt-linux-amd64 dolt-linux-amd64.tar.gz \ + + +FROM --platform=linux/amd64 builder + +RUN mkdir /docker-entrypoint-initdb.d +VOLUME /var/lib/dolt + +COPY docker/docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 3306 33060 +CMD [ "dolt", "sql-server", "--host=0.0.0.0" , "--port=3306" ] diff --git a/docker/serverDockerfile.arm64 b/docker/serverDockerfile.arm64 new file mode 100644 index 0000000000..3abbc19663 --- /dev/null +++ b/docker/serverDockerfile.arm64 @@ -0,0 +1,23 @@ +# syntax=docker/dockerfile:1.3-labs +FROM --platform=linux/arm64 ubuntu:22.04 as builder +COPY docker/qemu-aarch64-static /usr/bin/ + +ARG DOLT_VERSION=0.50.8 + +ADD https://github.com/dolthub/dolt/releases/download/v${DOLT_VERSION}/dolt-linux-arm64.tar.gz dolt-linux-arm64.tar.gz +RUN tar zxvf dolt-linux-arm64.tar.gz && \ + cp dolt-linux-arm64/bin/dolt /usr/local/bin && \ + rm -rf dolt-linux-arm64 dolt-linux-arm64.tar.gz + + +FROM --platform=linux/arm64 builder + +RUN mkdir /docker-entrypoint-initdb.d +VOLUME /var/lib/dolt + +COPY docker/docker-entrypoint.sh /usr/local/bin/ +RUN chmod +x /usr/local/bin/docker-entrypoint.sh +ENTRYPOINT ["docker-entrypoint.sh"] + +EXPOSE 3306 33060 +CMD [ "dolt", "sql-server", "--host=0.0.0.0" , "--port=3306" ]