From 6865672d81f39cb8343cc024921898e0c6ffda25 Mon Sep 17 00:00:00 2001 From: ahmadk953 <103906421+ahmadk953@users.noreply.github.com> Date: Tue, 17 Jun 2025 20:24:57 -0400 Subject: [PATCH] chore: small script and file fixes --- .github/workflows/docker.yml | 4 +- .lintstagedrc.mjs | 10 +- docker-compose.yml | 29 ++- docker/pgbouncer/Dockerfile | 31 ++- docker/pgbouncer/README.md | 4 +- docker/pgbouncer/entrypoint.sh | 359 +++++++++++++++++++++++---------- drizzle.config.ts | 2 - generate-certs.sh | 8 +- src/util/helpers.ts | 4 +- 9 files changed, 310 insertions(+), 141 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index f30ed50..dcfb252 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -50,7 +50,7 @@ jobs: with: context: docker/pgbouncer file: docker/pgbouncer/Dockerfile - push: true + push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha,scope=pgbouncer @@ -60,4 +60,4 @@ jobs: env: TAGS: ${{ steps.meta.outputs.tags }} DIGEST: ${{ steps.build-and-push.outputs.digest }} - run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST} + run: echo "${TAGS}" | xargs -I {} cosign sign --yes "{}@${DIGEST}" diff --git a/.lintstagedrc.mjs b/.lintstagedrc.mjs index f0e6371..879f1a3 100644 --- a/.lintstagedrc.mjs +++ b/.lintstagedrc.mjs @@ -2,9 +2,13 @@ import path from 'path'; import process from 'process'; const buildEslintCommand = (filenames) => { - // only lint files under src/ - const srcFiles = filenames.filter((f) => f.startsWith('src/')); - if (srcFiles.length === 0) return ''; + const srcDir = path.resolve(process.cwd(), 'src'); + const srcFiles = filenames.filter((f) => { + const absolute = path.resolve(process.cwd(), f); + const relativeToSrc = path.relative(srcDir, absolute); + return !relativeToSrc.startsWith('..'); + }); + if (srcFiles.length === 0) return []; return `eslint ${srcFiles .map((f) => path.relative(process.cwd(), f)) .join(' ')}`; diff --git a/docker-compose.yml b/docker-compose.yml index 60203ea..5edbaa8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -17,7 +17,11 @@ services: -c ssl_cert_file=/var/lib/postgresql/server.crt -c ssl_key_file=/var/lib/postgresql/server.key healthcheck: - test: ['CMD-SHELL', 'pg_isready -U ${POSTGRES_USER}'] + test: + [ + 'CMD-SHELL', + 'PGPASSWORD=${POSTGRES_PASSWORD} pg_isready -U ${POSTGRES_USER} -h localhost -p 5432 --db=${POSTGRES_DB}', + ] interval: 10s timeout: 5s retries: 5 @@ -44,7 +48,20 @@ services: --tls-key-file /certs/server.key --tls-ca-cert-file /certs/ca.crt healthcheck: - test: ['CMD', 'valkey-cli', '-a', '${VALKEY_PASSWORD}', 'ping'] + test: [ + 'CMD-SHELL', + 'valkey-cli + -a + ${VALKEY_PASSWORD} + --tls + --cacert + /certs/ca.crt + --cert + /certs/server.crt + --key + /certs/server.key + ping', + ] interval: 10s timeout: 5s retries: 5 @@ -58,7 +75,7 @@ services: DB_USER: ${POSTGRES_USER} DB_PASSWORD: ${POSTGRES_PASSWORD} DB_HOST: postgres - # DB_NAME: ${POSTGRES_DB} + AUTH_USER: ${POSTGRES_USER} AUTH_TYPE: scram-sha-256 POOL_MODE: transaction ADMIN_USERS: ${POSTGRES_USER} @@ -76,7 +93,11 @@ services: - ./certs/pgbouncer-server.key:/certs/server.key:ro - ./certs/pgbouncer-ca.crt:/certs/ca.crt:ro healthcheck: - test: ['CMD', 'pg_isready', '-h', 'localhost'] + test: + [ + 'CMD-SHELL', + 'PGPASSWORD=${POSTGRES_PASSWORD} pg_isready -U ${POSTGRES_USER} -h localhost -p 5432 --db=${POSTGRES_DB}', + ] networks: - services diff --git a/docker/pgbouncer/Dockerfile b/docker/pgbouncer/Dockerfile index 7887f3e..99b0502 100644 --- a/docker/pgbouncer/Dockerfile +++ b/docker/pgbouncer/Dockerfile @@ -11,27 +11,24 @@ ARG C_ARES_VERSION=1.34.5 RUN apk add --no-cache autoconf autoconf-doc automake curl gcc git libc-dev libevent-dev libtool make openssl-dev pandoc pkgconfig -RUN curl -Lo /c-ares.tar.gz https://github.com/c-ares/c-ares/releases/download/v${C_ARES_VERSION}/c-ares-${C_ARES_VERSION}.tar.gz && \ - tar -xzf /c-ares.tar.gz && mv /c-ares-${C_ARES_VERSION} /c-ares - -RUN curl -Lo /pgbouncer.tar.gz https://pgbouncer.github.io/downloads/files/${PGBOUNCER_VERSION}/pgbouncer-${PGBOUNCER_VERSION}.tar.gz && \ - tar -xzf /pgbouncer.tar.gz && mv /pgbouncer-${PGBOUNCER_VERSION} /pgbouncer - -RUN cd /c-ares && ./configure && make && make install -RUN cd /pgbouncer && ./configure --with-cares && make && make install +RUN set -eux; \ + curl -Lo /c-ares.tar.gz https://github.com/c-ares/c-ares/releases/download/v${C_ARES_VERSION}/c-ares-${C_ARES_VERSION}.tar.gz && \ + tar -xzf /c-ares.tar.gz && mv /c-ares-${C_ARES_VERSION} /c-ares && \ + cd /c-ares && ./configure && make && make install && \ + curl -Lo /pgbouncer.tar.gz https://pgbouncer.github.io/downloads/files/${PGBOUNCER_VERSION}/pgbouncer-${PGBOUNCER_VERSION}.tar.gz && \ + tar -xzf /pgbouncer.tar.gz -C / && mv /pgbouncer-${PGBOUNCER_VERSION} /pgbouncer && \ + cd /pgbouncer && ./configure --with-cares && make && make install FROM alpine:3.22 -COPY entrypoint.sh /entrypoint.sh - -RUN apk add --no-cache busybox libevent postgresql-client \ - && mkdir -p /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer \ - && touch /etc/pgbouncer/userlist.txt \ - && addgroup -S -g 1100 pgbouncer \ - && adduser -S -u 1100 -G pgbouncer pgbouncer \ - && chown -R pgbouncer:pgbouncer /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer /entrypoint.sh \ - && chmod +x /entrypoint.sh +RUN apk add --no-cache busybox libevent postgresql-client libssl3 \ + && mkdir -p /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer \ + && touch /etc/pgbouncer/userlist.txt \ + && addgroup -S -g 1100 pgbouncer \ + && adduser -S -u 1100 -G pgbouncer pgbouncer \ + && chown -R pgbouncer:pgbouncer /etc/pgbouncer /var/log/pgbouncer /var/run/pgbouncer +COPY --chmod=+x entrypoint.sh /entrypoint.sh COPY --from=build /usr/local/bin /usr/local/bin COPY --from=build /usr/local/lib /usr/local/lib COPY --from=build /pgbouncer/etc/pgbouncer.ini /etc/pgbouncer/pgbouncer.ini.example diff --git a/docker/pgbouncer/README.md b/docker/pgbouncer/README.md index 14d6aa2..027c5bf 100644 --- a/docker/pgbouncer/README.md +++ b/docker/pgbouncer/README.md @@ -58,7 +58,7 @@ docker run --rm \ - **Dockerfile**: Modify build arguments or dependencies as needed. - **entrypoint.sh**: Adjust how the configuration file is generated and updated. -- **Environment Variables**: Almost all settings found in the `pgbouncer.ini` file can be set as environment variables with the exception of a few, system-specific configuration options. For an example, check out [the example Docker compose file](../../docker-compose.yml). For all configuration options, check the [pgbouncer configuration documentation](https://www.pgbouncer.org/config.html). +- **Environment Variables**: Almost all settings found in the `pgbouncer.ini` file can be set as environment variables, except for a few system-specific configuration options. For an example, check out [the example Docker compose file](../../docker-compose.yml). For all configuration options, check the [pgbouncer configuration documentation](https://www.pgbouncer.org/config.html). - **Configuration File**: You can specify your own `pgbouncer.ini` file by mounting it as a volume like so: ```sh docker run --rm \ @@ -67,7 +67,7 @@ docker run --rm \ -e DB_HOST=postgres-host \ -e DB_NAME=database \ -v pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini:ro \ - -p 5432:5432 + -p 5432:5432 \ ghcr.io/ahmadk953/poixpixel-discord-bot-pgbouncer ``` diff --git a/docker/pgbouncer/entrypoint.sh b/docker/pgbouncer/entrypoint.sh index 64df010..c5d27b3 100644 --- a/docker/pgbouncer/entrypoint.sh +++ b/docker/pgbouncer/entrypoint.sh @@ -22,7 +22,7 @@ fi # Parameters: # - The url we should parse # Returns (sets variables): DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_NAME -function parse_url() { +parse_url() { # Thanks to https://stackoverflow.com/a/17287984/146289 # Allow to pass values like dj-database-url / django-environ accept @@ -39,10 +39,10 @@ function parse_url() { fi # extract the host -- updated - hostport=`echo $url | sed -e s,$userpass@,,g | cut -d/ -f1` - port=`echo $hostport | grep : | cut -d: -f2` + hostport=$(echo $url | sed -e s,$userpass@,,g | cut -d/ -f1) + port=$(echo $hostport | grep : | cut -d: -f2) if [ -n "$port" ]; then - DB_HOST=`echo $hostport | grep : | cut -d: -f1` + DB_HOST=$(echo $hostport | grep : | cut -d: -f1) DB_PORT="${port}" else DB_HOST="${hostport}" @@ -52,31 +52,42 @@ function parse_url() { } # Grabs variables set by `parse_url` and adds them to the userlist if not already set in there. -function generate_userlist_if_needed() { - if [ -n "${DB_USER}" -a -n "${DB_PASSWORD}" -a -e "${_AUTH_FILE}" ] && ! grep -q "^\"${DB_USER}\"" "${_AUTH_FILE}"; then - if [ "${AUTH_TYPE}" == "plain" ] || [ "${AUTH_TYPE}" == "scram-sha-256" ]; then +generate_userlist_if_needed() { + if [ -n "${DB_USER}" ] && [ -n "${DB_PASSWORD}" ] && [ -e "${_AUTH_FILE}" ] && ! grep -q "^\"${DB_USER}\"" "${_AUTH_FILE}"; then + if [ "${AUTH_TYPE}" = "plain" ] || [ "${AUTH_TYPE}" = "scram-sha-256" ]; then pass="${DB_PASSWORD}" else - pass="md5$(echo -n "${DB_PASSWORD}${DB_USER}" | md5sum | cut -f 1 -d ' ')" + pass="md5$(printf '%s' "${DB_PASSWORD}${DB_USER}" | md5sum | cut -f 1 -d ' ')" fi - echo "\"${DB_USER}\" \"${pass}\"" >> "${_AUTH_FILE}" + echo "\"${DB_USER}\" \"${pass}\"" >>"${_AUTH_FILE}" echo "Wrote authentication credentials for '${DB_USER}' to ${_AUTH_FILE}" fi } # Grabs variables set by `parse_url` and adds them to the PG config file as a database entry. -function generate_config_db_entry() { - printf "\ -${DB_NAME:-*} = host=${DB_HOST:?"Setup pgbouncer config error! You must set DB_HOST env"} \ -port=${DB_PORT:-5432} auth_user=${DB_USER:-postgres} -${CLIENT_ENCODING:+client_encoding = ${CLIENT_ENCODING}\n}\ -" >> "${PG_CONFIG_FILE}" +generate_config_db_entry() { + # Prepare values + dbname=${DB_NAME:-*} + host=${DB_HOST:?"Setup pgbouncer config error! You must set DB_HOST env"} + port=${DB_PORT:-5432} + auth_user=${DB_USER:-postgres} + + # Print main entry + printf '%s = host=%s port=%s auth_user=%s\n' \ + "$dbname" "$host" "$port" "$auth_user" \ + >>"$PG_CONFIG_FILE" + + # Optional client_encoding + if [ -n "$CLIENT_ENCODING" ]; then + printf 'client_encoding = %s\n' "$CLIENT_ENCODING" \ + >>"$PG_CONFIG_FILE" + fi } # Write the password with MD5 encryption, to avoid printing it during startup. # Notice that `docker inspect` will show unencrypted env variables. if [ -n "${DATABASE_URLS}" ]; then - echo "${DATABASE_URLS}" | tr , '\n' | while read url; do + echo "${DATABASE_URLS}" | tr ',' '\n' | while IFS= read -r url; do parse_url "$url" generate_userlist_if_needed done @@ -87,19 +98,20 @@ else generate_userlist_if_needed fi -if [ ! -f "${PG_CONFIG_FILE}" ]; then +if [ ! -f "$PG_CONFIG_FILE" ]; then echo "Creating pgbouncer config in ${PG_CONFIG_DIR}" # Config file is in "ini" format. Section names are between "[" and "]". # Lines starting with ";" or "#" are taken as comments and ignored. # The characters ";" and "#" are not recognized when they appear later in the line. - printf "\ -################## Auto generated ################## -[databases] -" > "${PG_CONFIG_FILE}" + # write static header + printf '%s\n%s\n' \ + '################## Auto generated ##################' \ + '[databases]' \ + >"$PG_CONFIG_FILE" if [ -n "$DATABASE_URLS" ]; then - echo "$DATABASE_URLS" | tr , '\n' | while read url; do + echo "$DATABASE_URLS" | tr , '\n' | while read -r url; do parse_url "$url" generate_config_db_entry done @@ -110,94 +122,231 @@ if [ ! -f "${PG_CONFIG_FILE}" ]; then generate_config_db_entry fi - printf "\ -[pgbouncer] -listen_addr = ${LISTEN_ADDR:-0.0.0.0} -listen_port = ${LISTEN_PORT:-5432} -unix_socket_dir = ${UNIX_SOCKET_DIR} -user = pgbouncer -auth_file = ${_AUTH_FILE} -${AUTH_HBA_FILE:+auth_hba_file = ${AUTH_HBA_FILE}\n}\ -auth_type = ${AUTH_TYPE:-md5} -${AUTH_USER:+auth_user = ${AUTH_USER}\n}\ -${AUTH_QUERY:+auth_query = ${AUTH_QUERY}\n}\ -${AUTH_DBNAME:+auth_dbname = ${AUTH_DBNAME}\n}\ -${POOL_MODE:+pool_mode = ${POOL_MODE}\n}\ -${MAX_CLIENT_CONN:+max_client_conn = ${MAX_CLIENT_CONN}\n}\ -${POOL_SIZE:+pool_size = ${POOL_SIZE}\n}\ -${DEFAULT_POOL_SIZE:+default_pool_size = ${DEFAULT_POOL_SIZE}\n}\ -${MIN_POOL_SIZE:+min_pool_size = ${MIN_POOL_SIZE}\n}\ -${RESERVE_POOL_SIZE:+reserve_pool_size = ${RESERVE_POOL_SIZE}\n}\ -${RESERVE_POOL_TIMEOUT:+reserve_pool_timeout = ${RESERVE_POOL_TIMEOUT}\n}\ -${MAX_DB_CONNECTIONS:+max_db_connections = ${MAX_DB_CONNECTIONS}\n}\ -${MAX_USER_CONNECTIONS:+max_user_connections = ${MAX_USER_CONNECTIONS}\n}\ -${SERVER_ROUND_ROBIN:+server_round_robin = ${SERVER_ROUND_ROBIN}\n}\ -ignore_startup_parameters = ${IGNORE_STARTUP_PARAMETERS:-extra_float_digits} -${DISABLE_PQEXEC:+disable_pqexec = ${DISABLE_PQEXEC}\n}\ -${APPLICATION_NAME_ADD_HOST:+application_name_add_host = ${APPLICATION_NAME_ADD_HOST}\n}\ -${TIMEZONE:+timezone = ${TIMEZONE}\n}\ -${MAX_PREPARED_STATEMENTS:+max_prepared_statements = ${MAX_PREPARED_STATEMENTS}\n}\ + # write [pgbouncer] section with a constant format string + { + printf '%s\n' '[pgbouncer]' + printf 'listen_addr = %s\n' "${LISTEN_ADDR:-0.0.0.0}" + printf 'listen_port = %s\n' "${LISTEN_PORT:-5432}" + printf 'unix_socket_dir = %s\n' "${UNIX_SOCKET_DIR}" + printf 'user = %s\n' "pgbouncer" + printf 'auth_file = %s\n' "${_AUTH_FILE}" + } >>"$PG_CONFIG_FILE" -# Log settings -${LOG_CONNECTIONS:+log_connections = ${LOG_CONNECTIONS}\n}\ -${LOG_DISCONNECTIONS:+log_disconnections = ${LOG_DISCONNECTIONS}\n}\ -${LOG_POOLER_ERRORS:+log_pooler_errors = ${LOG_POOLER_ERRORS}\n}\ -${LOG_STATS:+log_stats = ${LOG_STATS}\n}\ -${STATS_PERIOD:+stats_period = ${STATS_PERIOD}\n}\ -${VERBOSE:+verbose = ${VERBOSE}\n}\ -admin_users = ${ADMIN_USERS:-postgres} -${STATS_USERS:+stats_users = ${STATS_USERS}\n}\ + # now handle each optional setting in its own if-block: + if [ -n "${AUTH_HBA_FILE}" ]; then + printf 'auth_hba_file = %s\n' "${AUTH_HBA_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${AUTH_TYPE}" ]; then + printf 'auth_type = %s\n' "${AUTH_TYPE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${AUTH_USER}" ]; then + printf 'auth_user = %s\n' "${AUTH_USER}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${AUTH_QUERY}" ]; then + printf 'auth_query = %s\n' "${AUTH_QUERY}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${AUTH_DBNAME}" ]; then + printf 'auth_dbname = %s\n' "${AUTH_DBNAME}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${POOL_MODE}" ]; then + printf 'pool_mode = %s\n' "${POOL_MODE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MAX_CLIENT_CONN}" ]; then + printf 'max_client_conn = %s\n' "${MAX_CLIENT_CONN}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${POOL_SIZE}" ]; then + printf 'pool_size = %s\n' "${POOL_SIZE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${DEFAULT_POOL_SIZE}" ]; then + printf 'default_pool_size = %s\n' "${DEFAULT_POOL_SIZE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MIN_POOL_SIZE}" ]; then + printf 'min_pool_size = %s\n' "${MIN_POOL_SIZE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${RESERVE_POOL_SIZE}" ]; then + printf 'reserve_pool_size = %s\n' "${RESERVE_POOL_SIZE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${RESERVE_POOL_TIMEOUT}" ]; then + printf 'reserve_pool_timeout = %s\n' "${RESERVE_POOL_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MAX_DB_CONNECTIONS}" ]; then + printf 'max_db_connections = %s\n' "${MAX_DB_CONNECTIONS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MAX_USER_CONNECTIONS}" ]; then + printf 'max_user_connections = %s\n' "${MAX_USER_CONNECTIONS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_ROUND_ROBIN}" ]; then + printf 'server_round_robin = %s\n' "${SERVER_ROUND_ROBIN}" >>"$PG_CONFIG_FILE" + fi + printf 'ignore_startup_parameters = %s\n' "${IGNORE_STARTUP_PARAMETERS:-extra_float_digits}" >>"$PG_CONFIG_FILE" + if [ -n "${DISABLE_PQEXEC}" ]; then + printf 'disable_pqexec = %s\n' "${DISABLE_PQEXEC}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${APPLICATION_NAME_ADD_HOST}" ]; then + printf 'application_name_add_host = %s\n' "${APPLICATION_NAME_ADD_HOST}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TIMEZONE}" ]; then + printf 'timezone = %s\n' "${TIMEZONE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MAX_PREPARED_STATEMENTS}" ]; then + printf 'max_prepared_statements = %s\n' "${MAX_PREPARED_STATEMENTS}" >>"$PG_CONFIG_FILE" + fi -# Connection sanity checks, timeouts -${SERVER_RESET_QUERY:+server_reset_query = ${SERVER_RESET_QUERY}\n}\ -${SERVER_RESET_QUERY_ALWAYS:+server_reset_query_always = ${SERVER_RESET_QUERY_ALWAYS}\n}\ -${SERVER_CHECK_DELAY:+server_check_delay = ${SERVER_CHECK_DELAY}\n}\ -${SERVER_CHECK_QUERY:+server_check_query = ${SERVER_CHECK_QUERY}\n}\ -${SERVER_LIFETIME:+server_lifetime = ${SERVER_LIFETIME}\n}\ -${SERVER_IDLE_TIMEOUT:+server_idle_timeout = ${SERVER_IDLE_TIMEOUT}\n}\ -${SERVER_CONNECT_TIMEOUT:+server_connect_timeout = ${SERVER_CONNECT_TIMEOUT}\n}\ -${SERVER_LOGIN_RETRY:+server_login_retry = ${SERVER_LOGIN_RETRY}\n}\ -${CLIENT_LOGIN_TIMEOUT:+client_login_timeout = ${CLIENT_LOGIN_TIMEOUT}\n}\ -${AUTODB_IDLE_TIMEOUT:+autodb_idle_timeout = ${AUTODB_IDLE_TIMEOUT}\n}\ -${DNS_MAX_TTL:+dns_max_ttl = ${DNS_MAX_TTL}\n}\ -${DNS_NXDOMAIN_TTL:+dns_nxdomain_ttl = ${DNS_NXDOMAIN_TTL}\n}\ + # Log settings + if [ -n "${LOG_CONNECTIONS}" ]; then + printf 'log_connections = %s\n' "${LOG_CONNECTIONS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${LOG_DISCONNECTIONS}" ]; then + printf 'log_disconnections = %s\n' "${LOG_DISCONNECTIONS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${LOG_POOLER_ERRORS}" ]; then + printf 'log_pooler_errors = %s\n' "${LOG_POOLER_ERRORS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${LOG_STATS}" ]; then + printf 'log_stats = %s\n' "${LOG_STATS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${STATS_PERIOD}" ]; then + printf 'stats_period = %s\n' "${STATS_PERIOD}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${VERBOSE}" ]; then + printf 'verbose = %s\n' "${VERBOSE}" >>"$PG_CONFIG_FILE" + fi + printf 'admin_users = %s\n' "${ADMIN_USERS:-postgres}" >>"$PG_CONFIG_FILE" + if [ -n "${STATS_USERS}" ]; then + printf 'stats_users = %s\n' "${STATS_USERS}" >>"$PG_CONFIG_FILE" + fi -# TLS settings -${CLIENT_TLS_SSLMODE:+client_tls_sslmode = ${CLIENT_TLS_SSLMODE}\n}\ -${CLIENT_TLS_KEY_FILE:+client_tls_key_file = ${CLIENT_TLS_KEY_FILE}\n}\ -${CLIENT_TLS_CERT_FILE:+client_tls_cert_file = ${CLIENT_TLS_CERT_FILE}\n}\ -${CLIENT_TLS_CA_FILE:+client_tls_ca_file = ${CLIENT_TLS_CA_FILE}\n}\ -${CLIENT_TLS_PROTOCOLS:+client_tls_protocols = ${CLIENT_TLS_PROTOCOLS}\n}\ -${CLIENT_TLS_CIPHERS:+client_tls_ciphers = ${CLIENT_TLS_CIPHERS}\n}\ -${CLIENT_TLS_ECDHCURVE:+client_tls_ecdhcurve = ${CLIENT_TLS_ECDHCURVE}\n}\ -${CLIENT_TLS_DHEPARAMS:+client_tls_dheparams = ${CLIENT_TLS_DHEPARAMS}\n}\ -${SERVER_TLS_SSLMODE:+server_tls_sslmode = ${SERVER_TLS_SSLMODE}\n}\ -${SERVER_TLS_CA_FILE:+server_tls_ca_file = ${SERVER_TLS_CA_FILE}\n}\ -${SERVER_TLS_KEY_FILE:+server_tls_key_file = ${SERVER_TLS_KEY_FILE}\n}\ -${SERVER_TLS_CERT_FILE:+server_tls_cert_file = ${SERVER_TLS_CERT_FILE}\n}\ -${SERVER_TLS_PROTOCOLS:+server_tls_protocols = ${SERVER_TLS_PROTOCOLS}\n}\ -${SERVER_TLS_CIPHERS:+server_tls_ciphers = ${SERVER_TLS_CIPHERS}\n}\ + # Connection sanity checks, timeouts + if [ -n "${SERVER_RESET_QUERY}" ]; then + printf 'server_reset_query = %s\n' "${SERVER_RESET_QUERY}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_RESET_QUERY_ALWAYS}" ]; then + printf 'server_reset_query_always = %s\n' "${SERVER_RESET_QUERY_ALWAYS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_CHECK_DELAY}" ]; then + printf 'server_check_delay = %s\n' "${SERVER_CHECK_DELAY}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_CHECK_QUERY}" ]; then + printf 'server_check_query = %s\n' "${SERVER_CHECK_QUERY}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_LIFETIME}" ]; then + printf 'server_lifetime = %s\n' "${SERVER_LIFETIME}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_IDLE_TIMEOUT}" ]; then + printf 'server_idle_timeout = %s\n' "${SERVER_IDLE_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_CONNECT_TIMEOUT}" ]; then + printf 'server_connect_timeout = %s\n' "${SERVER_CONNECT_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_LOGIN_RETRY}" ]; then + printf 'server_login_retry = %s\n' "${SERVER_LOGIN_RETRY}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_LOGIN_TIMEOUT}" ]; then + printf 'client_login_timeout = %s\n' "${CLIENT_LOGIN_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${AUTODB_IDLE_TIMEOUT}" ]; then + printf 'autodb_idle_timeout = %s\n' "${AUTODB_IDLE_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${DNS_MAX_TTL}" ]; then + printf 'dns_max_ttl = %s\n' "${DNS_MAX_TTL}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${DNS_NXDOMAIN_TTL}" ]; then + printf 'dns_nxdomain_ttl = %s\n' "${DNS_NXDOMAIN_TTL}" >>"$PG_CONFIG_FILE" + fi -# Dangerous timeouts -${QUERY_TIMEOUT:+query_timeout = ${QUERY_TIMEOUT}\n}\ -${QUERY_WAIT_TIMEOUT:+query_wait_timeout = ${QUERY_WAIT_TIMEOUT}\n}\ -${CLIENT_IDLE_TIMEOUT:+client_idle_timeout = ${CLIENT_IDLE_TIMEOUT}\n}\ -${IDLE_TRANSACTION_TIMEOUT:+idle_transaction_timeout = ${IDLE_TRANSACTION_TIMEOUT}\n}\ -${PKT_BUF:+pkt_buf = ${PKT_BUF}\n}\ -${MAX_PACKET_SIZE:+max_packet_size = ${MAX_PACKET_SIZE}\n}\ -${LISTEN_BACKLOG:+listen_backlog = ${LISTEN_BACKLOG}\n}\ -${SBUF_LOOPCNT:+sbuf_loopcnt = ${SBUF_LOOPCNT}\n}\ -${SUSPEND_TIMEOUT:+suspend_timeout = ${SUSPEND_TIMEOUT}\n}\ -${TCP_DEFER_ACCEPT:+tcp_defer_accept = ${TCP_DEFER_ACCEPT}\n}\ -${TCP_KEEPALIVE:+tcp_keepalive = ${TCP_KEEPALIVE}\n}\ -${TCP_KEEPCNT:+tcp_keepcnt = ${TCP_KEEPCNT}\n}\ -${TCP_KEEPIDLE:+tcp_keepidle = ${TCP_KEEPIDLE}\n}\ -${TCP_KEEPINTVL:+tcp_keepintvl = ${TCP_KEEPINTVL}\n}\ -${TCP_USER_TIMEOUT:+tcp_user_timeout = ${TCP_USER_TIMEOUT}\n}\ -################## end file ################## -" >> "${PG_CONFIG_FILE}" + # TLS settings + if [ -n "${CLIENT_TLS_SSLMODE}" ]; then + printf 'client_tls_sslmode = %s\n' "${CLIENT_TLS_SSLMODE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_KEY_FILE}" ]; then + printf 'client_tls_key_file = %s\n' "${CLIENT_TLS_KEY_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_CERT_FILE}" ]; then + printf 'client_tls_cert_file = %s\n' "${CLIENT_TLS_CERT_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_CA_FILE}" ]; then + printf 'client_tls_ca_file = %s\n' "${CLIENT_TLS_CA_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_PROTOCOLS}" ]; then + printf 'client_tls_protocols = %s\n' "${CLIENT_TLS_PROTOCOLS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_CIPHERS}" ]; then + printf 'client_tls_ciphers = %s\n' "${CLIENT_TLS_CIPHERS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_ECDHCURVE}" ]; then + printf 'client_tls_ecdhcurve = %s\n' "${CLIENT_TLS_ECDHCURVE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_TLS_DHEPARAMS}" ]; then + printf 'client_tls_dheparams = %s\n' "${CLIENT_TLS_DHEPARAMS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_SSLMODE}" ]; then + printf 'server_tls_sslmode = %s\n' "${SERVER_TLS_SSLMODE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_CA_FILE}" ]; then + printf 'server_tls_ca_file = %s\n' "${SERVER_TLS_CA_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_KEY_FILE}" ]; then + printf 'server_tls_key_file = %s\n' "${SERVER_TLS_KEY_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_CERT_FILE}" ]; then + printf 'server_tls_cert_file = %s\n' "${SERVER_TLS_CERT_FILE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_PROTOCOLS}" ]; then + printf 'server_tls_protocols = %s\n' "${SERVER_TLS_PROTOCOLS}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SERVER_TLS_CIPHERS}" ]; then + printf 'server_tls_ciphers = %s\n' "${SERVER_TLS_CIPHERS}" >>"$PG_CONFIG_FILE" + fi + + # Dangerous timeouts + if [ -n "${QUERY_TIMEOUT}" ]; then + printf 'query_timeout = %s\n' "${QUERY_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${QUERY_WAIT_TIMEOUT}" ]; then + printf 'query_wait_timeout = %s\n' "${QUERY_WAIT_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${CLIENT_IDLE_TIMEOUT}" ]; then + printf 'client_idle_timeout = %s\n' "${CLIENT_IDLE_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${IDLE_TRANSACTION_TIMEOUT}" ]; then + printf 'idle_transaction_timeout = %s\n' "${IDLE_TRANSACTION_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${PKT_BUF}" ]; then + printf 'pkt_buf = %s\n' "${PKT_BUF}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${MAX_PACKET_SIZE}" ]; then + printf 'max_packet_size = %s\n' "${MAX_PACKET_SIZE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${LISTEN_BACKLOG}" ]; then + printf 'listen_backlog = %s\n' "${LISTEN_BACKLOG}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SBUF_LOOPCNT}" ]; then + printf 'sbuf_loopcnt = %s\n' "${SBUF_LOOPCNT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${SUSPEND_TIMEOUT}" ]; then + printf 'suspend_timeout = %s\n' "${SUSPEND_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_DEFER_ACCEPT}" ]; then + printf 'tcp_defer_accept = %s\n' "${TCP_DEFER_ACCEPT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_KEEPALIVE}" ]; then + printf 'tcp_keepalive = %s\n' "${TCP_KEEPALIVE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_KEEPCNT}" ]; then + printf 'tcp_keepcnt = %s\n' "${TCP_KEEPCNT}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_KEEPIDLE}" ]; then + printf 'tcp_keepidle = %s\n' "${TCP_KEEPIDLE}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_KEEPINTVL}" ]; then + printf 'tcp_keepintvl = %s\n' "${TCP_KEEPINTVL}" >>"$PG_CONFIG_FILE" + fi + if [ -n "${TCP_USER_TIMEOUT}" ]; then + printf 'tcp_user_timeout = %s\n' "${TCP_USER_TIMEOUT}" >>"$PG_CONFIG_FILE" + fi + printf '\n################## end file ##################\n' >>"$PG_CONFIG_FILE" cat "${PG_CONFIG_FILE}" fi echo "Starting $*..." -exec "$@" \ No newline at end of file +exec "$@" diff --git a/drizzle.config.ts b/drizzle.config.ts index 89cc62e..fc258df 100644 --- a/drizzle.config.ts +++ b/drizzle.config.ts @@ -1,5 +1,3 @@ -/* eslint-disable */ - import fs from 'node:fs'; import path from 'node:path'; import { defineConfig } from 'drizzle-kit'; diff --git a/generate-certs.sh b/generate-certs.sh index eebdac0..32ecd19 100755 --- a/generate-certs.sh +++ b/generate-certs.sh @@ -45,9 +45,9 @@ sudo cp certs/pgbouncer-server.key certs/pgbouncer-client.key sudo cp certs/cache-server.key certs/cache-client.key # Change Client Key Ownership -sudo chown $_uid:$_gid certs/pgbouncer-client.key -sudo chown $_uid:$_gid certs/cache-client.key +sudo chown "${_uid}:${_gid}" certs/pgbouncer-client.key +sudo chown "${_uid}:${_gid}" certs/cache-client.key # Change Client Key Permissions -sudo chmod +r certs/pgbouncer-client.key -sudo chmod +r certs/cache-client.key +sudo chmod 0600 certs/pgbouncer-client.key +sudo chmod 0600 certs/cache-client.key diff --git a/src/util/helpers.ts b/src/util/helpers.ts index e1f7d95..5b7b2e7 100644 --- a/src/util/helpers.ts +++ b/src/util/helpers.ts @@ -19,7 +19,7 @@ import { moderationTable } from '@/db/schema.js'; import { db, getMember, handleDbError, updateMember } from '@/db/db.js'; import logAction from './logging/logAction.js'; -const __dirname = path.resolve(); +const PROJECT_ROOT = path.resolve(); /** * Turns a duration string into milliseconds @@ -68,7 +68,7 @@ export async function generateMemberBanner({ height, }: generateMemberBannerTypes): Promise { const welcomeBackground = path.join( - __dirname, + PROJECT_ROOT, 'assets', 'images', 'welcome-bg.png',