-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
391 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
FROM ubuntu:22.04 | ||
|
||
# see https://github.com/moby/moby/issues/4032#issuecomment-192327844 | ||
# It could be removed after we move on a version 23:04+ | ||
ARG DEBIAN_FRONTEND=noninteractive | ||
|
||
# ARG for quick switch to a given ubuntu mirror | ||
ARG apt_archive="http://archive.ubuntu.com" | ||
|
||
# We shouldn't use `apt upgrade` to not change the upstream image. It's updated biweekly | ||
|
||
# user/group precreated explicitly with fixed uid/gid on purpose. | ||
# It is especially important for rootless containers: in that case entrypoint | ||
# can't do chown and owners of mounted volumes should be configured externally. | ||
# We do that in advance at the begining of Dockerfile before any packages will be | ||
# installed to prevent picking those uid / gid by some unrelated software. | ||
# The same uid / gid (101) is used both for alpine and ubuntu. | ||
RUN sed -i "s|http://archive.ubuntu.com|${apt_archive}|g" /etc/apt/sources.list \ | ||
&& groupadd -r clickhouse --gid=101 \ | ||
&& useradd -r -g clickhouse --uid=101 --home-dir=/var/lib/clickhouse --shell=/bin/bash clickhouse \ | ||
&& apt-get update \ | ||
&& apt-get install --yes --no-install-recommends \ | ||
ca-certificates \ | ||
locales \ | ||
tzdata \ | ||
wget \ | ||
&& rm -rf /var/lib/apt/lists/* /var/cache/debconf /tmp/* | ||
|
||
ARG REPO_CHANNEL="stable" | ||
ARG REPOSITORY="deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb ${REPO_CHANNEL} main" | ||
ARG VERSION="24.10.1.2812" | ||
ARG PACKAGES="clickhouse-client clickhouse-server clickhouse-common-static" | ||
|
||
#docker-official-library:off | ||
# The part between `docker-official-library` tags is related to our builds | ||
|
||
# set non-empty deb_location_url url to create a docker image | ||
# from debs created by CI build, for example: | ||
# docker build . --network host --build-arg version="21.4.1.6282" --build-arg deb_location_url="https://..." -t ... | ||
ARG deb_location_url="" | ||
ARG DIRECT_DOWNLOAD_URLS="" | ||
|
||
# set non-empty single_binary_location_url to create docker image | ||
# from a single binary url (useful for non-standard builds - with sanitizers, for arm64). | ||
ARG single_binary_location_url="" | ||
|
||
ARG TARGETARCH | ||
|
||
# install from direct URL | ||
RUN if [ -n "${DIRECT_DOWNLOAD_URLS}" ]; then \ | ||
echo "installing from custom predefined urls with deb packages: ${DIRECT_DOWNLOAD_URLS}" \ | ||
&& rm -rf /tmp/clickhouse_debs \ | ||
&& mkdir -p /tmp/clickhouse_debs \ | ||
&& for url in $DIRECT_DOWNLOAD_URLS; do \ | ||
wget --progress=bar:force:noscroll "$url" -P /tmp/clickhouse_debs || exit 1 \ | ||
; done \ | ||
&& dpkg -i /tmp/clickhouse_debs/*.deb \ | ||
&& rm -rf /tmp/* ; \ | ||
fi | ||
|
||
# install from a web location with deb packages | ||
RUN arch="${TARGETARCH:-amd64}" \ | ||
&& if [ -n "${deb_location_url}" ]; then \ | ||
echo "installing from custom url with deb packages: ${deb_location_url}" \ | ||
&& rm -rf /tmp/clickhouse_debs \ | ||
&& mkdir -p /tmp/clickhouse_debs \ | ||
&& for package in ${PACKAGES}; do \ | ||
{ wget --progress=bar:force:noscroll "${deb_location_url}/${package}_${VERSION}_${arch}.deb" -P /tmp/clickhouse_debs || \ | ||
wget --progress=bar:force:noscroll "${deb_location_url}/${package}_${VERSION}_all.deb" -P /tmp/clickhouse_debs ; } \ | ||
|| exit 1 \ | ||
; done \ | ||
&& dpkg -i /tmp/clickhouse_debs/*.deb \ | ||
&& rm -rf /tmp/* ; \ | ||
fi | ||
|
||
# install from a single binary | ||
RUN if [ -n "${single_binary_location_url}" ]; then \ | ||
echo "installing from single binary url: ${single_binary_location_url}" \ | ||
&& rm -rf /tmp/clickhouse_binary \ | ||
&& mkdir -p /tmp/clickhouse_binary \ | ||
&& wget --progress=bar:force:noscroll "${single_binary_location_url}" -O /tmp/clickhouse_binary/clickhouse \ | ||
&& chmod +x /tmp/clickhouse_binary/clickhouse \ | ||
&& /tmp/clickhouse_binary/clickhouse install --user "clickhouse" --group "clickhouse" \ | ||
&& rm -rf /tmp/* ; \ | ||
fi | ||
|
||
# The rest is the same in the official docker and in our build system | ||
#docker-official-library:on | ||
|
||
# A fallback to installation from ClickHouse repository | ||
RUN if ! clickhouse local -q "SELECT ''" > /dev/null 2>&1; then \ | ||
apt-get update \ | ||
&& apt-get install --yes --no-install-recommends \ | ||
apt-transport-https \ | ||
dirmngr \ | ||
gnupg2 \ | ||
&& mkdir -p /etc/apt/sources.list.d \ | ||
&& GNUPGHOME=$(mktemp -d) \ | ||
&& GNUPGHOME="$GNUPGHOME" gpg --batch --no-default-keyring \ | ||
--keyring /usr/share/keyrings/clickhouse-keyring.gpg \ | ||
--keyserver hkp://keyserver.ubuntu.com:80 \ | ||
--recv-keys 3a9ea1193a97b548be1457d48919f6bd2b48d754 \ | ||
&& rm -rf "$GNUPGHOME" \ | ||
&& chmod +r /usr/share/keyrings/clickhouse-keyring.gpg \ | ||
&& echo "${REPOSITORY}" > /etc/apt/sources.list.d/clickhouse.list \ | ||
&& echo "installing from repository: ${REPOSITORY}" \ | ||
&& apt-get update \ | ||
&& for package in ${PACKAGES}; do \ | ||
packages="${packages} ${package}=${VERSION}" \ | ||
; done \ | ||
&& apt-get install --allow-unauthenticated --yes --no-install-recommends ${packages} || exit 1 \ | ||
&& rm -rf \ | ||
/var/lib/apt/lists/* \ | ||
/var/cache/debconf \ | ||
/tmp/* \ | ||
&& apt-get autoremove --purge -yq libksba8 \ | ||
&& apt-get autoremove -yq \ | ||
; fi | ||
|
||
# post install | ||
# we need to allow "others" access to clickhouse folder, because docker container | ||
# can be started with arbitrary uid (openshift usecase) | ||
RUN clickhouse-local -q 'SELECT * FROM system.build_options' \ | ||
&& mkdir -p /var/lib/clickhouse /var/log/clickhouse-server /etc/clickhouse-server /etc/clickhouse-client \ | ||
&& chmod ugo+Xrw -R /var/lib/clickhouse /var/log/clickhouse-server /etc/clickhouse-server /etc/clickhouse-client | ||
|
||
RUN locale-gen en_US.UTF-8 | ||
ENV LANG en_US.UTF-8 | ||
ENV LANGUAGE en_US:en | ||
ENV LC_ALL en_US.UTF-8 | ||
ENV TZ UTC | ||
|
||
RUN mkdir /docker-entrypoint-initdb.d | ||
|
||
COPY docker_related_config.xml /etc/clickhouse-server/config.d/ | ||
COPY entrypoint.sh /entrypoint.sh | ||
|
||
EXPOSE 9000 8123 9009 | ||
VOLUME /var/lib/clickhouse | ||
|
||
ENV CLICKHOUSE_CONFIG /etc/clickhouse-server/config.xml | ||
|
||
ENTRYPOINT ["/entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
flavor = tsan | ||
version = 24.11.1.1178%2B$(flavor) | ||
url = https://s3.amazonaws.com/clickhouse-builds/24.11/506b30fd4997c11273567cb96410fc0324d3bb12/package_$(flavor) | ||
docker_registry = us-central1-docker.pkg.dev/molten-verve-216720/clickhouse-repository/ | ||
|
||
all: | ||
docker build . -t clickhouse-server-$(flavor):latest --build-arg VERSION="$(version)" --build-arg deb_location_url="$(url)" | ||
docker tag clickhouse-server-$(flavor) $(docker_registry)/clickhouse-server-$(flavor):latest | ||
|
||
push: | ||
docker push $(docker_registry)/clickhouse-server-$(flavor):latest | ||
|
||
.PHONY: % |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<clickhouse> | ||
<!-- Listen wildcard address to allow accepting connections from other containers and host network. --> | ||
<listen_host>::</listen_host> | ||
<listen_host>0.0.0.0</listen_host> | ||
<listen_try>1</listen_try> | ||
|
||
<!-- | ||
<logger> | ||
<console>1</console> | ||
</logger> | ||
--> | ||
</clickhouse> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,221 @@ | ||
#!/bin/bash | ||
|
||
set -eo pipefail | ||
shopt -s nullglob | ||
|
||
DO_CHOWN=1 | ||
if [ "${CLICKHOUSE_DO_NOT_CHOWN:-0}" = "1" ]; then | ||
DO_CHOWN=0 | ||
fi | ||
|
||
CLICKHOUSE_UID="${CLICKHOUSE_UID:-"$(id -u clickhouse)"}" | ||
CLICKHOUSE_GID="${CLICKHOUSE_GID:-"$(id -g clickhouse)"}" | ||
|
||
# support --user | ||
if [ "$(id -u)" = "0" ]; then | ||
USER=$CLICKHOUSE_UID | ||
GROUP=$CLICKHOUSE_GID | ||
else | ||
USER="$(id -u)" | ||
GROUP="$(id -g)" | ||
DO_CHOWN=0 | ||
fi | ||
|
||
# set some vars | ||
CLICKHOUSE_CONFIG="${CLICKHOUSE_CONFIG:-/etc/clickhouse-server/config.xml}" | ||
|
||
# get CH directories locations | ||
DATA_DIR="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=path || true)" | ||
TMP_DIR="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=tmp_path || true)" | ||
USER_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=user_files_path || true)" | ||
LOG_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=logger.log || true)" | ||
LOG_DIR="" | ||
if [ -n "$LOG_PATH" ]; then LOG_DIR="$(dirname "$LOG_PATH")"; fi | ||
ERROR_LOG_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=logger.errorlog || true)" | ||
ERROR_LOG_DIR="" | ||
if [ -n "$ERROR_LOG_PATH" ]; then ERROR_LOG_DIR="$(dirname "$ERROR_LOG_PATH")"; fi | ||
FORMAT_SCHEMA_PATH="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=format_schema_path || true)" | ||
|
||
# There could be many disks declared in config | ||
readarray -t DISKS_PATHS < <(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key='storage_configuration.disks.*.path' || true) | ||
readarray -t DISKS_METADATA_PATHS < <(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key='storage_configuration.disks.*.metadata_path' || true) | ||
|
||
CLICKHOUSE_USER="${CLICKHOUSE_USER:-default}" | ||
CLICKHOUSE_PASSWORD_FILE="${CLICKHOUSE_PASSWORD_FILE:-}" | ||
if [[ -n "${CLICKHOUSE_PASSWORD_FILE}" && -f "${CLICKHOUSE_PASSWORD_FILE}" ]]; then | ||
CLICKHOUSE_PASSWORD="$(cat "${CLICKHOUSE_PASSWORD_FILE}")" | ||
fi | ||
CLICKHOUSE_PASSWORD="${CLICKHOUSE_PASSWORD:-}" | ||
CLICKHOUSE_DB="${CLICKHOUSE_DB:-}" | ||
CLICKHOUSE_ACCESS_MANAGEMENT="${CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT:-0}" | ||
|
||
function create_directory_and_do_chown() { | ||
local dir=$1 | ||
# check if variable not empty | ||
[ -z "$dir" ] && return | ||
# ensure directories exist | ||
if [ "$DO_CHOWN" = "1" ]; then | ||
mkdir="mkdir" | ||
else | ||
# if DO_CHOWN=0 it means that the system does not map root user to "admin" permissions | ||
# it mainly happens on NFS mounts where root==nobody for security reasons | ||
# thus mkdir MUST run with user id/gid and not from nobody that has zero permissions | ||
mkdir="/usr/bin/clickhouse su "${USER}:${GROUP}" mkdir" | ||
fi | ||
if ! $mkdir -p "$dir"; then | ||
echo "Couldn't create necessary directory: $dir" | ||
exit 1 | ||
fi | ||
|
||
if [ "$DO_CHOWN" = "1" ]; then | ||
# ensure proper directories permissions | ||
# but skip it for if directory already has proper premissions, cause recursive chown may be slow | ||
if [ "$(stat -c %u "$dir")" != "$USER" ] || [ "$(stat -c %g "$dir")" != "$GROUP" ]; then | ||
chown -R "$USER:$GROUP" "$dir" | ||
fi | ||
fi | ||
} | ||
|
||
create_directory_and_do_chown "$DATA_DIR" | ||
|
||
# Change working directory to $DATA_DIR in case there're paths relative to $DATA_DIR, also avoids running | ||
# clickhouse-server at root directory. | ||
cd "$DATA_DIR" | ||
|
||
for dir in "$ERROR_LOG_DIR" \ | ||
"$LOG_DIR" \ | ||
"$TMP_DIR" \ | ||
"$USER_PATH" \ | ||
"$FORMAT_SCHEMA_PATH" \ | ||
"${DISKS_PATHS[@]}" \ | ||
"${DISKS_METADATA_PATHS[@]}" | ||
do | ||
create_directory_and_do_chown "$dir" | ||
done | ||
|
||
# if clickhouse user is defined - create it (user "default" already exists out of box) | ||
if [ -n "$CLICKHOUSE_USER" ] && [ "$CLICKHOUSE_USER" != "default" ] || [ -n "$CLICKHOUSE_PASSWORD" ] || [ "$CLICKHOUSE_ACCESS_MANAGEMENT" != "0" ]; then | ||
echo "$0: create new user '$CLICKHOUSE_USER' instead 'default'" | ||
cat <<EOT > /etc/clickhouse-server/users.d/default-user.xml | ||
<clickhouse> | ||
<!-- Docs: <https://clickhouse.com/docs/en/operations/settings/settings_users/> --> | ||
<users> | ||
<!-- Remove default user --> | ||
<default remove="remove"> | ||
</default> | ||
<${CLICKHOUSE_USER}> | ||
<profile>default</profile> | ||
<networks> | ||
<ip>::/0</ip> | ||
</networks> | ||
<password><![CDATA[${CLICKHOUSE_PASSWORD//]]>/]]]]><![CDATA[>}]]></password> | ||
<quota>default</quota> | ||
<access_management>${CLICKHOUSE_ACCESS_MANAGEMENT}</access_management> | ||
</${CLICKHOUSE_USER}> | ||
</users> | ||
</clickhouse> | ||
EOT | ||
fi | ||
CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS="${CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS:-}" | ||
# checking $DATA_DIR for initialization | ||
if [ -d "${DATA_DIR%/}/data" ]; then | ||
DATABASE_ALREADY_EXISTS='true' | ||
fi | ||
# run initialization if flag CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS is not empty or data directory is empty | ||
if [[ -n "${CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS}" || -z "${DATABASE_ALREADY_EXISTS}" ]]; then | ||
RUN_INITDB_SCRIPTS='true' | ||
fi | ||
if [ -n "${RUN_INITDB_SCRIPTS}" ]; then | ||
if [ -n "$(ls /docker-entrypoint-initdb.d/)" ] || [ -n "$CLICKHOUSE_DB" ]; then | ||
# port is needed to check if clickhouse-server is ready for connections | ||
HTTP_PORT="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=http_port --try)" | ||
HTTPS_PORT="$(clickhouse extract-from-config --config-file "$CLICKHOUSE_CONFIG" --key=https_port --try)" | ||
if [ -n "$HTTP_PORT" ]; then | ||
URL="http://127.0.0.1:$HTTP_PORT/ping" | ||
else | ||
URL="https://127.0.0.1:$HTTPS_PORT/ping" | ||
fi | ||
# Listen only on localhost until the initialization is done | ||
/usr/bin/clickhouse su "${USER}:${GROUP}" /usr/bin/clickhouse-server --config-file="$CLICKHOUSE_CONFIG" -- --listen_host=127.0.0.1 & | ||
pid="$!" | ||
# check if clickhouse is ready to accept connections | ||
# will try to send ping clickhouse via http_port (max 1000 retries by default, with 1 sec timeout and 1 sec delay between retries) | ||
tries=${CLICKHOUSE_INIT_TIMEOUT:-1000} | ||
while ! wget --spider --no-check-certificate -T 1 -q "$URL" 2>/dev/null; do | ||
if [ "$tries" -le "0" ]; then | ||
echo >&2 'ClickHouse init process failed.' | ||
exit 1 | ||
fi | ||
tries=$(( tries-1 )) | ||
sleep 1 | ||
done | ||
clickhouseclient=( clickhouse-client --multiquery --host "127.0.0.1" -u "$CLICKHOUSE_USER" --password "$CLICKHOUSE_PASSWORD" ) | ||
echo | ||
# create default database, if defined | ||
if [ -n "$CLICKHOUSE_DB" ]; then | ||
echo "$0: create database '$CLICKHOUSE_DB'" | ||
"${clickhouseclient[@]}" -q "CREATE DATABASE IF NOT EXISTS $CLICKHOUSE_DB"; | ||
fi | ||
for f in /docker-entrypoint-initdb.d/*; do | ||
case "$f" in | ||
*.sh) | ||
if [ -x "$f" ]; then | ||
echo "$0: running $f" | ||
"$f" | ||
else | ||
echo "$0: sourcing $f" | ||
# shellcheck source=/dev/null | ||
. "$f" | ||
fi | ||
;; | ||
*.sql) echo "$0: running $f"; "${clickhouseclient[@]}" < "$f" ; echo ;; | ||
*.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${clickhouseclient[@]}"; echo ;; | ||
*) echo "$0: ignoring $f" ;; | ||
esac | ||
echo | ||
done | ||
if ! kill -s TERM "$pid" || ! wait "$pid"; then | ||
echo >&2 'Finishing of ClickHouse init process failed.' | ||
exit 1 | ||
fi | ||
fi | ||
else | ||
echo "ClickHouse Database directory appears to contain a database; Skipping initialization" | ||
fi | ||
# if no args passed to `docker run` or first argument start with `--`, then the user is passing clickhouse-server arguments | ||
if [[ $# -lt 1 ]] || [[ "$1" == "--"* ]]; then | ||
# Watchdog is launched by default, but does not send SIGINT to the main process, | ||
# so the container can't be finished by ctrl+c | ||
CLICKHOUSE_WATCHDOG_ENABLE=${CLICKHOUSE_WATCHDOG_ENABLE:-0} | ||
export CLICKHOUSE_WATCHDOG_ENABLE | ||
# An option for easy restarting and replacing clickhouse-server in a container, especially in Kubernetes. | ||
# For example, you can replace the clickhouse-server binary to another and restart it while keeping the container running. | ||
if [[ "${CLICKHOUSE_DOCKER_RESTART_ON_EXIT:-0}" -eq "1" ]]; then | ||
while true; do | ||
# This runs the server as a child process of the shell script: | ||
/usr/bin/clickhouse su "${USER}:${GROUP}" /usr/bin/clickhouse-server --config-file="$CLICKHOUSE_CONFIG" "$@" ||: | ||
echo >&2 'ClickHouse Server exited, and the environment variable CLICKHOUSE_DOCKER_RESTART_ON_EXIT is set to 1. Restarting the server.' | ||
done | ||
else | ||
# This replaces the shell script with the server: | ||
exec /usr/bin/clickhouse su "${USER}:${GROUP}" /usr/bin/clickhouse-server --config-file="$CLICKHOUSE_CONFIG" "$@" | ||
fi | ||
fi | ||
# Otherwise, we assume the user want to run his own process, for example a `bash` shell to explore this image | ||
exec "$@" |
Oops, something went wrong.