From 8c90f653915b1587a2fcc3f227a791a421f832ad Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Tue, 27 Jun 2023 22:36:07 -0400 Subject: [PATCH] refactor(docker): allow more flexible zebra configuration (#7045) * fix(docker): use `entrypoint.sh` as default for users * ref(entrypoint): allow more flexible configurations This changes allow users to: - Mount their own configuration file - Allow for Zebra to be exposed outside the container or not - Allow the user to turn off sync - Allow to enable `metrics` and `tracing`, exposing them or not Having the `-x` option prints variable expasions, so we don't have to echo each value. * chore(docker): remove unused ARGs from the Dockerfile ARGs are not available at build time, so we don't require this ARGs as their ENV variables counterparts are being set in the `entrypoint`, at runtime. * revert: keep old naming * fix: renaming mistake :) * Apply suggestions from code review Co-authored-by: teor * fix(docker): revert some breaking changes * imp(docker): allow more flexibility with FEATURES config * chore(docker): remove confusing port on `EXPOSE` * chore(docker): remove unused command * fix(docker): handle quotes while building the conf file --------- Co-authored-by: teor Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- docker/Dockerfile | 48 +------------------ docker/runtime-entrypoint.sh | 92 ++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 81 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 3b636339..4f15b3bf 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -58,6 +58,7 @@ RUN if [ "$(uname -m)" != "aarch64" ]; then \ && \ rm -rf /var/lib/apt/lists/* /tmp/* +# TODO: just keep the backtrace, colorbt, rust_log, and cargo_home variables as those are the only needed at build time. # Build arguments and variables set to change how tests are run, tracelog levels, # and Network to be used (Mainnet or Testnet) # @@ -179,53 +180,8 @@ RUN apt-get update && \ ARG NETWORK ENV NETWORK ${NETWORK:-Mainnet} -# Set this to enable the RPC port -ARG RPC_PORT -ENV RPC_PORT ${RPC_PORT} - -# Set this to log to a file, if not set, logs to standard output -ARG LOG_FILE -ENV LOG_FILE ${LOG_FILE} - -# Set this to change the default cached state directory -ARG ZEBRA_CACHED_STATE_DIR -ENV ZEBRA_CACHED_STATE_DIR ${ZEBRA_CACHED_STATE_DIR:-/var/cache/zebrad-cache} - -# Zebra automatically detects if it is attached to a terminal, and uses colored output. -# Set this to 'true' to force using color even if the output is not a terminal. -# Set this to 'false' to disable using color even if the output is a terminal. -ARG LOG_COLOR -ENV LOG_COLOR ${LOG_COLOR} - # Expose configured ports - -EXPOSE 8233 18233 $RPC_PORT - -# Config location - -# Use a configurable dir and file for the zebrad configuration file -ARG ZEBRA_CONF_DIR -ENV ZEBRA_CONF_DIR ${ZEBRA_CONF_DIR:-/etc/zebra} - -ARG ZEBRA_CONF_FILE -ENV ZEBRA_CONF_FILE ${ZEBRA_CONF_FILE:-zebrad.toml} - -ARG ZEBRA_CONF_PATH -ENV ZEBRA_CONF_PATH ${ZEBRA_CONF_PATH:-$ZEBRA_CONF_DIR/$ZEBRA_CONF_FILE} - -# Other settings - -ARG SHORT_SHA -ENV SHORT_SHA ${SHORT_SHA} - -# Set this to send sentry reports when Zebra crashes -ARG SENTRY_DSN -ENV SENTRY_DSN ${SENTRY_DSN} - -# Create a default config file based on the Docker build arguments, -# and report the available zebrad arguments. -# (--help is used as a dummy command.) -RUN /runtime-entrypoint.sh --help +EXPOSE 8233 18233 # Update the config file based on the Docker run variables, # and launch zebrad with it diff --git a/docker/runtime-entrypoint.sh b/docker/runtime-entrypoint.sh index 98b1c944..5eaeb7a4 100755 --- a/docker/runtime-entrypoint.sh +++ b/docker/runtime-entrypoint.sh @@ -1,73 +1,93 @@ #!/usr/bin/env bash -# show the commands we are executing +# Show the commands we are executing set -x -# exit if a command fails +# Exit if a command fails set -e -# exit if any command in a pipeline fails +# Exit if any command in a pipeline fails set -o pipefail -echo "Config variables:" -echo "NETWORK=$NETWORK" -echo "RPC_PORT=$RPC_PORT" -echo "LOG_FILE=$LOG_FILE" +# Set this to change the default cached state directory +# Path and name of the config file +: "${ZEBRA_CONF_DIR:=/etc/zebrad}" +: "${ZEBRA_CONF_FILE:=zebrad.toml}" +if [[ -n "$ZEBRA_CONF_DIR" ]] && [[ -n "$ZEBRA_CONF_FILE" ]]; then + ZEBRA_CONF_PATH="$ZEBRA_CONF_DIR/$ZEBRA_CONF_FILE" +fi -echo "Config location:" -echo "ZEBRA_CONF_DIR=$ZEBRA_CONF_DIR" -echo "ZEBRA_CONF_FILE=$ZEBRA_CONF_FILE" -echo "ZEBRA_CONF_PATH=$ZEBRA_CONF_PATH" +# [network] +: "${NETWORK:=Mainnet}" +: "${ZEBRA_LISTEN_ADDR:=0.0.0.0}" +# [consensus] +: "${ZEBRA_CHECKPOINT_SYNC:=true}" +# [state] +: "${ZEBRA_CACHED_STATE_DIR:=/var/cache/zebrad-cache}" +# [metrics] +: "${METRICS_ENDPOINT_ADDR:=0.0.0.0}" +: "${METRICS_ENDPOINT_PORT:=9999}" +# [tracing] +: "${LOG_COLOR:=false}" +: "${TRACING_ENDPOINT_ADDR:=0.0.0.0}" +: "${TRACING_ENDPOINT_PORT:=3000}" +# [rpc] +: "${RPC_LISTEN_ADDR:=0.0.0.0}" -echo "Other variables:" -echo "SHORT_SHA=$SHORT_SHA" -echo "SENTRY_DSN=$SENTRY_DSN" - -# Create the conf path and file if it does not exist. -mkdir -p "$ZEBRA_CONF_DIR" -touch "$ZEBRA_CONF_PATH" # Populate `zebrad.toml` before starting zebrad, using the environmental -# variables set by the Dockerfile. +# variables set by the Dockerfile or the user. If the user has already created a config, don't replace it. # # We disable most ports by default, so the default config is secure. # Users have to opt-in to additional functionality by setting environmental variables. -# -# TODO: -# - make `cache_dir`, `metrics.endpoint_addr`, and `tracing.endpoint_addr` into Docker arguments -# - add an $EXTRA_CONFIG or $REPLACEMENT_CONFIG environmental variable +if [[ -n "$ZEBRA_CONF_PATH" ]] && [[ ! -f "$ZEBRA_CONF_PATH" ]]; then + +# Create the conf path and file +mkdir -p "$ZEBRA_CONF_DIR" +touch "$ZEBRA_CONF_PATH" + +# Populate the conf file cat < "$ZEBRA_CONF_PATH" [network] network = "$NETWORK" -listen_addr = "0.0.0.0" - +listen_addr = "$ZEBRA_LISTEN_ADDR" [state] cache_dir = "$ZEBRA_CACHED_STATE_DIR" - -[metrics] -#endpoint_addr = "0.0.0.0:9999" EOF -if [[ -n "$RPC_PORT" ]]; then +if [[ " $FEATURES " =~ " prometheus " ]]; then # spaces are important here to avoid partial matches +cat <> "$ZEBRA_CONF_PATH" +[metrics] +endpoint_addr = "${METRICS_ENDPOINT_ADDR}:${METRICS_ENDPOINT_PORT}" +EOF +fi + +# Set this to enable the RPC port +if [[ " $FEATURES " =~ " getblocktemplate-rpcs " ]]; then # spaces are important here to avoid partial matches cat <> "$ZEBRA_CONF_PATH" [rpc] -listen_addr = "0.0.0.0:${RPC_PORT}" +listen_addr = "${RPC_LISTEN_ADDR}:${RPC_PORT}" EOF fi -if [[ -n "$LOG_FILE" ]] || [[ -n "$LOG_COLOR" ]]; then +if [[ -n "$LOG_FILE" ]] || [[ -n "$LOG_COLOR" ]] || [[ -n "$TRACING_ENDPOINT_ADDR" ]]; then cat <> "$ZEBRA_CONF_PATH" [tracing] -#endpoint_addr = "0.0.0.0:3000" +EOF +if [[ " $FEATURES " =~ " filter-reload " ]]; then # spaces are important here to avoid partial matches +cat <> "$ZEBRA_CONF_PATH" +endpoint_addr = "${TRACING_ENDPOINT_ADDR}:${TRACING_ENDPOINT_PORT}" EOF fi - +# Set this to log to a file, if not set, logs to standard output if [[ -n "$LOG_FILE" ]]; then -mkdir -p $(dirname "$LOG_FILE") - +mkdir -p "$(dirname "$LOG_FILE")" cat <> "$ZEBRA_CONF_PATH" log_file = "${LOG_FILE}" EOF fi +# Zebra automatically detects if it is attached to a terminal, and uses colored output. +# Set this to 'true' to force using color even if the output is not a terminal. +# Set this to 'false' to disable using color even if the output is a terminal. if [[ "$LOG_COLOR" = "true" ]]; then cat <> "$ZEBRA_CONF_PATH" force_use_color = true @@ -77,6 +97,8 @@ cat <> "$ZEBRA_CONF_PATH" use_color = false EOF fi +fi +fi echo "Using zebrad.toml:" cat "$ZEBRA_CONF_PATH"