diff --git a/scripts/deploy-zabbix.sh b/scripts/deploy-zabbix.sh index 4c3cf64..633304c 100755 --- a/scripts/deploy-zabbix.sh +++ b/scripts/deploy-zabbix.sh @@ -23,7 +23,6 @@ STAMP="$(date '+%Y%m%d-%H%M%S')" BACKUP_DIR="${BACKUP_ROOT}/${STAMP}" DB_BACKUP_DIR="${BACKUP_DIR}/database" - DB_BACKUP_FILE="${DB_BACKUP_DIR}/zabbix.dump" SERVER_START_TIMEOUT=1800 @@ -66,7 +65,7 @@ fail() extract_version() { grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | - head -n1 + head -n1 } @@ -75,7 +74,7 @@ image_version() local IMAGE="$1" printf '%s\n' "${IMAGE}" | - sed -nE 's/.*:alpine-([0-9]+\.[0-9]+\.[0-9]+)$/\1/p' + sed -nE 's/.*:alpine-([0-9]+\.[0-9]+\.[0-9]+)$/\1/p' } @@ -88,8 +87,8 @@ version_less_than() [[ "$( printf '%s\n%s\n' "${A}" "${B}" | - sort -V | - head -n1 + sort -V | + head -n1 )" == "${A}" ]] } @@ -145,6 +144,8 @@ restore_old_services() if [[ -f "${BACKUP_DIR}/docker-compose.yml" ]]; then + echo "Restoring previous docker-compose.yml" + cp \ "${BACKUP_DIR}/docker-compose.yml" \ "${LIVE}/docker-compose.yml" @@ -160,10 +161,245 @@ restore_old_services() up -d \ zabbix-server \ zabbix-web + ) || true } +check_zabbix_server_tcp() +{ + local HOST="${1:-127.0.0.1}" + local PORT="${2:-10051}" + local ATTEMPTS=30 + local DELAY=2 + + echo + echo "Checking Zabbix server TCP ${HOST}:${PORT}..." + + + for ((i=1; i<=ATTEMPTS; i++)) + do + + if timeout 2 \ + bash -c \ + "exec 3<>/dev/tcp/${HOST}/${PORT}" \ + 2>/dev/null + then + + echo "Zabbix server TCP ${HOST}:${PORT}: available" + + return 0 + + fi + + + echo \ + "Waiting for TCP ${HOST}:${PORT}... (${i}/${ATTEMPTS})" + + sleep "${DELAY}" + + done + + + fail \ + "Zabbix server does not accept TCP connections on ${HOST}:${PORT}" +} + + +wait_for_zabbix_server() +{ + local ELAPSED=0 + + echo + echo "Waiting for Zabbix server startup..." + + + while (( ELAPSED < SERVER_START_TIMEOUT )) + do + + RUNNING="$( + docker inspect \ + -f '{{.State.Running}}' \ + zabbix-server-pgsql \ + 2>/dev/null || + echo false + )" + + + if [[ "${RUNNING}" != "true" ]]; then + + echo + echo "--- Zabbix server logs ---" + + docker logs \ + --since "${UPGRADE_STARTED}" \ + zabbix-server-pgsql \ + || true + + fail "Zabbix server container stopped during startup" + + fi + + + SERVER_LOG="$( + docker logs \ + --since "${UPGRADE_STARTED}" \ + zabbix-server-pgsql \ + 2>&1 || + true + )" + + + # ---------------------------------------------------- + # Explicit database upgrade failures + # ---------------------------------------------------- + + if echo "${SERVER_LOG}" | + grep -Eqi \ + 'database upgrade.*(failed|failure)|cannot upgrade database|database version.*newer' + then + + echo "${SERVER_LOG}" + + fail "Zabbix database upgrade failed" + + fi + + + # ---------------------------------------------------- + # Standard Zabbix startup marker + # ---------------------------------------------------- + + if echo "${SERVER_LOG}" | + grep -q 'server #0 started' + then + + echo + echo "Zabbix server main process started." + + return 0 + + fi + + + # ---------------------------------------------------- + # Functional fallback: + # TCP/10051 is already accepting connections + # ---------------------------------------------------- + + if timeout 2 \ + bash -c \ + 'exec 3<>/dev/tcp/127.0.0.1/10051' \ + 2>/dev/null + then + + echo + echo "Zabbix server TCP/10051 is available." + + return 0 + + fi + + + sleep "${SERVER_CHECK_INTERVAL}" + + ELAPSED=$((ELAPSED + SERVER_CHECK_INTERVAL)) + + echo "Waiting... ${ELAPSED}s" + + done + + + echo + echo "--- Zabbix server logs ---" + + docker logs \ + --since "${UPGRADE_STARTED}" \ + zabbix-server-pgsql \ + || true + + + fail \ + "Timeout waiting for Zabbix server after ${SERVER_START_TIMEOUT}s" +} + + +wait_for_zabbix_web() +{ + local ELAPSED=0 + + echo + echo "Waiting for Zabbix web health=healthy..." + + + while (( ELAPSED < WEB_START_TIMEOUT )) + do + + RUNNING="$( + docker inspect \ + -f '{{.State.Running}}' \ + zabbix-web-nginx-pgsql \ + 2>/dev/null || + echo false + )" + + + if [[ "${RUNNING}" != "true" ]]; then + + echo + echo "--- Zabbix web logs ---" + + docker logs \ + --tail 200 \ + zabbix-web-nginx-pgsql \ + || true + + fail "Zabbix web container stopped" + + fi + + + HEALTH="$( + docker inspect \ + -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' \ + zabbix-web-nginx-pgsql + )" + + + echo "Zabbix web health: ${HEALTH} (${ELAPSED}s)" + + + if [[ "${HEALTH}" == "healthy" ]]; then + + echo + echo "Zabbix web is healthy." + + return 0 + + fi + + + sleep "${WEB_CHECK_INTERVAL}" + + ELAPSED=$((ELAPSED + WEB_CHECK_INTERVAL)) + + done + + + echo + echo "--- Zabbix web logs ---" + + docker logs \ + --tail 200 \ + zabbix-web-nginx-pgsql \ + || true + + + fail \ + "Timeout waiting for Zabbix web health=healthy after ${WEB_START_TIMEOUT}s" +} + + on_error() { rc=$? @@ -185,12 +421,12 @@ on_error() fi + # -------------------------------------------------------- + # If new Zabbix server has NOT been started yet, + # DB migration cannot have started. # - # До старта нового zabbix-server схема БД точно - # не могла измениться. - # - # Поэтому старую версию можно безопасно вернуть. - # + # In this case restoring the old Compose/services is safe. + # -------------------------------------------------------- if [[ "${SERVICES_STOPPED}" == "true" ]] && [[ "${MIGRATION_STARTED}" != "true" ]] @@ -198,7 +434,7 @@ on_error() echo echo "Database migration has NOT started." - echo "Restoring previous containers." + echo "Restoring previous Zabbix containers." restore_old_services @@ -211,8 +447,8 @@ on_error() echo echo "Reason:" - echo " new Zabbix server has already been started;" - echo " database schema migration may have begun." + echo " New Zabbix server has already been started." + echo " Database schema migration may have begun." echo echo "Rollback requires restoration of the" echo "pre-upgrade PostgreSQL dump." @@ -226,163 +462,6 @@ on_error() } -wait_for_zabbix_server() -{ - local elapsed=0 - - echo - echo "Waiting for Zabbix server startup..." - - - while (( elapsed < SERVER_START_TIMEOUT )) - do - - RUNNING="$( - docker inspect \ - -f '{{.State.Running}}' \ - zabbix-server-pgsql 2>/dev/null || - echo false - )" - - - if [[ "${RUNNING}" != "true" ]]; then - - echo - echo "--- Zabbix server logs ---" - - docker logs \ - --since "${UPGRADE_STARTED}" \ - zabbix-server-pgsql || true - - fail "Zabbix server container stopped during startup" - - fi - - - SERVER_LOG="$( - docker logs \ - --since "${UPGRADE_STARTED}" \ - zabbix-server-pgsql 2>&1 || true - )" - - - # - # Successful server start means mandatory DB schema - # is compatible. Zabbix does not start if required - # patches failed. - # - - if echo "${SERVER_LOG}" | - grep -q 'server #0 started \[main process\]' - then - - echo - echo "Zabbix server main process started." - - return 0 - - fi - - - if echo "${SERVER_LOG}" | - grep -Eqi \ - 'database upgrade.*(failed|failure)|cannot upgrade database|database version.*newer' - then - - echo "${SERVER_LOG}" - - fail "Zabbix database upgrade failed" - - fi - - - sleep "${SERVER_CHECK_INTERVAL}" - - elapsed=$((elapsed + SERVER_CHECK_INTERVAL)) - - echo "Waiting... ${elapsed}s" - - done - - - echo - echo "--- Zabbix server logs ---" - - docker logs \ - --since "${UPGRADE_STARTED}" \ - zabbix-server-pgsql || true - - - fail \ - "Timeout waiting for Zabbix server after ${SERVER_START_TIMEOUT}s" -} - - -wait_for_zabbix_web() -{ - local elapsed=0 - - echo - echo "Waiting for Zabbix web health=healthy..." - - - while (( elapsed < WEB_START_TIMEOUT )) - do - - RUNNING="$( - docker inspect \ - -f '{{.State.Running}}' \ - zabbix-web-nginx-pgsql 2>/dev/null || - echo false - )" - - - if [[ "${RUNNING}" != "true" ]]; then - - echo - echo "--- Zabbix web logs ---" - - docker logs \ - zabbix-web-nginx-pgsql || true - - fail "Zabbix web container stopped" - - fi - - - HEALTH="$( - docker inspect \ - -f '{{if .State.Health}}{{.State.Health.Status}}{{else}}none{{end}}' \ - zabbix-web-nginx-pgsql - )" - - - echo "Zabbix web health: ${HEALTH} (${elapsed}s)" - - - if [[ "${HEALTH}" == "healthy" ]]; then - - return 0 - - fi - - - sleep "${WEB_CHECK_INTERVAL}" - - elapsed=$((elapsed + WEB_CHECK_INTERVAL)) - - done - - - docker logs \ - zabbix-web-nginx-pgsql || true - - - fail \ - "Timeout waiting for Zabbix web health=healthy" -} - - trap on_error ERR @@ -402,7 +481,8 @@ for CMD in \ sed \ sort \ find \ - awk + awk \ + timeout do command -v "${CMD}" >/dev/null 2>&1 || \ @@ -441,8 +521,6 @@ mkdir -p "${BACKUP_ROOT}" # ============================================================ # Load production environment -# -# .env must be shell compatible. # ============================================================ set -a @@ -453,6 +531,19 @@ source "${ENV_FILE}" set +a +# ============================================================ +# Normalize PostgreSQL connection settings +# +# Preferred Zabbix variables: +# +# DB_SERVER_HOST +# DB_SERVER_PORT +# +# Legacy fallback: +# +# POSTGRES_HOST +# POSTGRES_PORT +# ============================================================ DB_HOST="${DB_SERVER_HOST:-${POSTGRES_HOST:-}}" DB_PORT="${DB_SERVER_PORT:-${POSTGRES_PORT:-5432}}" @@ -467,7 +558,8 @@ DB_PASSWORD="${POSTGRES_PASSWORD:-}" : "${DB_USER:?POSTGRES_USER not defined}" : "${DB_PASSWORD:?POSTGRES_PASSWORD not defined}" -export PGPASSWORD="${POSTGRES_PASSWORD}" + +export PGPASSWORD="${DB_PASSWORD}" export PGCONNECT_TIMEOUT=10 @@ -487,7 +579,7 @@ echo "Docker Compose configuration is valid." # ============================================================ -# Detect target images +# Detect target Zabbix images # ============================================================ log "Detect target Zabbix images" @@ -514,7 +606,6 @@ NEW_WEB_IMAGE="$( [[ -n "${NEW_SERVER_IMAGE}" ]] || \ fail "Could not detect target Zabbix server image" - [[ -n "${NEW_WEB_IMAGE}" ]] || \ fail "Could not detect target Zabbix web image" @@ -530,13 +621,10 @@ TARGET_WEB_VERSION="$( [[ -n "${TARGET_SERVER_VERSION}" ]] || \ - fail \ - "Zabbix server must use a pinned alpine-X.Y.Z tag" - + fail "Zabbix server must use pinned tag alpine-X.Y.Z" [[ -n "${TARGET_WEB_VERSION}" ]] || \ - fail \ - "Zabbix web must use a pinned alpine-X.Y.Z tag" + fail "Zabbix web must use pinned tag alpine-X.Y.Z" [[ "${TARGET_SERVER_VERSION}" == "${TARGET_WEB_VERSION}" ]] || \ @@ -566,7 +654,6 @@ echo " ${TARGET_VERSION}" docker inspect zabbix-server-pgsql >/dev/null 2>&1 || \ fail "Current Zabbix server container does not exist" - docker inspect zabbix-web-nginx-pgsql >/dev/null 2>&1 || \ fail "Current Zabbix web container does not exist" @@ -588,13 +675,12 @@ WEB_RUNNING="$( [[ "${SERVER_RUNNING}" == "true" ]] || \ fail "Current Zabbix server is not running" - [[ "${WEB_RUNNING}" == "true" ]] || \ fail "Current Zabbix web is not running" # ============================================================ -# Current actual Zabbix version +# Detect current actual Zabbix version # ============================================================ log "Detect current Zabbix version" @@ -610,7 +696,7 @@ CURRENT_VERSION_OUTPUT="$( CURRENT_VERSION="$( printf '%s\n' "${CURRENT_VERSION_OUTPUT}" | - extract_version + extract_version )" @@ -645,7 +731,7 @@ echo " ${OLD_WEB_IMAGE}" # ============================================================ -# Version validation +# Validate version transition # ============================================================ log "Validate version transition" @@ -662,8 +748,7 @@ then fi -if [[ "${CURRENT_VERSION}" != "${TARGET_VERSION}" ]] -then +if [[ "${CURRENT_VERSION}" != "${TARGET_VERSION}" ]]; then VERSION_CHANGED=true @@ -676,7 +761,7 @@ echo "Version changed: ${VERSION_CHANGED}" # ============================================================ -# Pull target images before downtime +# Pull target images before any downtime # ============================================================ log "Pull target Docker images" @@ -687,14 +772,14 @@ docker pull "${NEW_WEB_IMAGE}" # ============================================================ -# VERSION UPDATE +# ZABBIX VERSION UPDATE # ============================================================ if [[ "${VERSION_CHANGED}" == "true" ]] then # ======================================================== - # Prepare backup directory before shutdown + # Prepare backup directory # ======================================================== log "Prepare Zabbix pre-upgrade backup" @@ -703,11 +788,22 @@ then mkdir -p "${DB_BACKUP_DIR}" + # -------------------------------------------------------- + # Backup current compose + # + # Do NOT use cp -a because current NFS does not support + # preserving all POSIX metadata. + # -------------------------------------------------------- + cp \ "${LIVE}/docker-compose.yml" \ "${BACKUP_DIR}/docker-compose.yml" + # -------------------------------------------------------- + # Metadata + # -------------------------------------------------------- + cat > "${BACKUP_DIR}/metadata.txt" < "${DB_BACKUP_DIR}/postgresql-version.txt" @@ -795,7 +900,7 @@ EOF PG_DUMP_VERSION="$( pg_dump --version | - sed -E 's/.* ([0-9]+(\.[0-9]+)?).*/\1/' + sed -E 's/.* ([0-9]+(\.[0-9]+)?).*/\1/' )" @@ -809,8 +914,7 @@ EOF echo " ${PG_DUMP_VERSION}" - if (( PG_DUMP_MAJOR < SERVER_MAJOR )) - then + if (( PG_DUMP_MAJOR < SERVER_MAJOR )); then fail \ "pg_dump ${PG_DUMP_VERSION} is older than PostgreSQL server ${SERVER_VERSION}" @@ -819,26 +923,30 @@ EOF # ======================================================== - # DB size + # Database size # ======================================================== DB_SIZE="$( psql \ -h "${DB_HOST}" \ -p "${DB_PORT}" \ - -U "${POSTGRES_USER}" \ - -d "${POSTGRES_DB}" \ + -U "${DB_USER}" \ + -d "${DB_NAME}" \ -Atqc \ 'SELECT pg_size_pretty(pg_database_size(current_database()));' )" + echo + echo "Database:" + echo " ${DB_NAME}" + echo "Database size:" echo " ${DB_SIZE}" # ======================================================== - # pg_dump + # PostgreSQL dump # ======================================================== log "Create PostgreSQL backup" @@ -847,8 +955,8 @@ EOF pg_dump \ -h "${DB_HOST}" \ -p "${DB_PORT}" \ - -U "${POSTGRES_USER}" \ - -d "${POSTGRES_DB}" \ + -U "${DB_USER}" \ + -d "${DB_NAME}" \ --format=custom \ --no-owner \ --no-privileges \ @@ -873,7 +981,7 @@ EOF [[ -s "${DB_BACKUP_DIR}/zabbix.dump.list" ]] || \ - fail "pg_restore could not validate dump" + fail "pg_restore could not validate PostgreSQL dump" # ======================================================== @@ -894,7 +1002,7 @@ EOF DB_BACKUP_SIZE="$( du -h "${DB_BACKUP_FILE}" | - awk '{print $1}' + awk '{print $1}' )" @@ -902,16 +1010,27 @@ EOF echo "PostgreSQL backup successful." echo - echo "Backup:" + echo "Backup directory:" + echo " ${BACKUP_DIR}" + + echo + echo "Database dump:" echo " ${DB_BACKUP_FILE}" echo echo "Dump size:" echo " ${DB_BACKUP_SIZE}" + echo + echo "SHA256:" + cat "${DB_BACKUP_DIR}/zabbix.dump.sha256" + # ======================================================== # Retention + # + # Old backups are deleted only after the new dump + # has been created and validated successfully. # ======================================================== cleanup_old_backups @@ -933,10 +1052,10 @@ EOF # ======================================================== - # Start NEW server only + # Start new Zabbix server only # - # From this point DB migration may start. - # No automatic rollback after this flag. + # After this point DB migration may begin. + # Automatic rollback is therefore disabled. # ======================================================== log "Start new Zabbix server" @@ -958,7 +1077,7 @@ EOF # ======================================================== - # Wait for automatic DB schema upgrade + server startup + # Wait for DB upgrade / server startup # ======================================================== log "Wait for Zabbix database upgrade and server startup" @@ -968,13 +1087,14 @@ EOF # ======================================================== - # Upgrade log + # Capture startup log # ======================================================== SERVER_LOG="$( docker logs \ --since "${UPGRADE_STARTED}" \ - zabbix-server-pgsql 2>&1 + zabbix-server-pgsql \ + 2>&1 )" @@ -984,7 +1104,7 @@ EOF if echo "${SERVER_LOG}" | - grep -q 'database upgrade fully completed' + grep -q 'database upgrade fully completed' then echo @@ -996,15 +1116,16 @@ EOF echo echo "Database schema upgrade marker:" echo " not present" + echo - echo "This is normal when the target release" - echo "does not require a schema change." + echo "This can be normal if the target Zabbix release" + echo "does not require a database schema change." fi # ======================================================== - # Verify new server version + # Verify running server version # ======================================================== log "Validate Zabbix server version" @@ -1020,17 +1141,28 @@ EOF RUNNING_VERSION="$( printf '%s\n' "${RUNNING_VERSION_OUTPUT}" | - extract_version + extract_version )" + [[ -n "${RUNNING_VERSION}" ]] || \ + fail "Could not determine running Zabbix version" + + + echo "Expected version:" + echo " ${TARGET_VERSION}" + + echo "Running version:" + echo " ${RUNNING_VERSION}" + + [[ "${RUNNING_VERSION}" == "${TARGET_VERSION}" ]] || \ fail \ "Running Zabbix version ${RUNNING_VERSION} does not match ${TARGET_VERSION}" # ======================================================== - # Start web after server/DB upgrade is complete + # Start Web only after server/DB migration succeeds # ======================================================== log "Start Zabbix web" @@ -1047,7 +1179,7 @@ EOF # ============================================================ -# NO VERSION CHANGE +# NO ZABBIX VERSION CHANGE # ============================================================ else @@ -1055,6 +1187,18 @@ else log "No Zabbix version change" + echo "Current version:" + echo " ${CURRENT_VERSION}" + + + # -------------------------------------------------------- + # Deploy changed Compose. + # + # Even without a version change Docker Compose may need + # to recreate containers because environment, networks, + # volumes, healthchecks, resources, etc. changed. + # -------------------------------------------------------- + cp \ "${SRC}/docker-compose.yml" \ "${LIVE}/docker-compose.yml" @@ -1063,30 +1207,121 @@ else cd "${LIVE}" + echo + echo "--- Pull images ---" + + docker compose \ --env-file "${ENV_FILE}" \ pull + echo + echo "--- Apply Docker Compose ---" + + docker compose \ --env-file "${ENV_FILE}" \ up -d \ --remove-orphans - UPGRADE_STARTED="$( - date -u -d '10 minutes ago' '+%Y-%m-%dT%H:%M:%SZ' + # ======================================================== + # Check server container + # ======================================================== + + echo + echo "--- Check Zabbix server container ---" + + + SERVER_RUNNING="$( + docker inspect \ + -f '{{.State.Running}}' \ + zabbix-server-pgsql \ + 2>/dev/null || + echo false )" - wait_for_zabbix_server + if [[ "${SERVER_RUNNING}" != "true" ]]; then + + echo + echo "--- Zabbix server logs ---" + + docker logs \ + --tail 200 \ + zabbix-server-pgsql \ + || true + + fail "Zabbix server container is not running" + + fi + + + echo "Zabbix server container: running" + + + # ======================================================== + # Functional server check + # + # Do NOT search for old startup messages here: + # container may have been running before this pipeline. + # ======================================================== + + check_zabbix_server_tcp \ + 127.0.0.1 \ + 10051 + + + # ======================================================== + # Verify running version + # ======================================================== + + echo + echo "--- Validate running Zabbix version ---" + + + RUNNING_VERSION_OUTPUT="$( + docker exec \ + zabbix-server-pgsql \ + zabbix_server \ + -V + )" + + + RUNNING_VERSION="$( + printf '%s\n' "${RUNNING_VERSION_OUTPUT}" | + extract_version + )" + + + [[ -n "${RUNNING_VERSION}" ]] || \ + fail "Could not determine running Zabbix version" + + + echo "Expected version:" + echo " ${TARGET_VERSION}" + + echo "Running version:" + echo " ${RUNNING_VERSION}" + + + [[ "${RUNNING_VERSION}" == "${TARGET_VERSION}" ]] || \ + fail \ + "Running Zabbix version ${RUNNING_VERSION} does not match ${TARGET_VERSION}" + + + # ======================================================== + # Verify Web + # ======================================================== + wait_for_zabbix_web fi # ============================================================ -# Final server state +# Final Zabbix server checks # ============================================================ log "Final Zabbix server checks" @@ -1103,6 +1338,19 @@ SERVER_RUNNING="$( fail "Zabbix server is not running" +# ------------------------------------------------------------ +# TCP readiness +# ------------------------------------------------------------ + +check_zabbix_server_tcp \ + 127.0.0.1 \ + 10051 + + +# ------------------------------------------------------------ +# Version +# ------------------------------------------------------------ + FINAL_VERSION_OUTPUT="$( docker exec \ zabbix-server-pgsql \ @@ -1113,19 +1361,26 @@ FINAL_VERSION_OUTPUT="$( FINAL_VERSION="$( printf '%s\n' "${FINAL_VERSION_OUTPUT}" | - extract_version + extract_version )" +[[ -n "${FINAL_VERSION}" ]] || \ + fail "Could not determine final Zabbix version" + + [[ "${FINAL_VERSION}" == "${TARGET_VERSION}" ]] || \ fail \ "Final Zabbix version mismatch: ${FINAL_VERSION} != ${TARGET_VERSION}" # ============================================================ -# Final web state +# Final Web checks # ============================================================ +log "Final Zabbix web checks" + + WEB_RUNNING="$( docker inspect \ -f '{{.State.Running}}' \ @@ -1148,6 +1403,13 @@ WEB_HEALTH="$( fail "Zabbix web is not healthy" +echo "Zabbix web container:" +echo " running" + +echo "Zabbix web health:" +echo " ${WEB_HEALTH}" + + # ============================================================ # Running images # ============================================================ @@ -1193,8 +1455,7 @@ echo "Web health:" echo " ${WEB_HEALTH}" -if [[ "${VERSION_CHANGED}" == "true" ]] -then +if [[ "${VERSION_CHANGED}" == "true" ]]; then echo echo "Pre-upgrade backup:" @@ -1216,4 +1477,5 @@ fi # ============================================================ unset PGPASSWORD -unset POSTGRES_PASSWORD +unset DB_PASSWORD +unset POSTGRES_PASSWORD \ No newline at end of file