├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ └── verify-templating.yml ├── .gitignore ├── 3.13 ├── alpine │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ │ └── Dockerfile └── ubuntu │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ └── Dockerfile ├── 4.0 ├── alpine │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ │ └── Dockerfile └── ubuntu │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ └── Dockerfile ├── 4.1 ├── alpine │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ │ └── Dockerfile └── ubuntu │ ├── 10-defaults.conf │ ├── 20-management_agent.disable_metrics_collector.conf │ ├── Dockerfile │ ├── docker-entrypoint.sh │ └── management │ └── Dockerfile ├── Dockerfile-alpine.template ├── Dockerfile-management.template ├── Dockerfile-ubuntu.template ├── LICENSE ├── README.md ├── apply-templates.sh ├── conf.d ├── 10-defaults.conf └── 20-management_agent.disable_metrics_collector.conf ├── docker-entrypoint.sh ├── generate-stackbrew-library.sh ├── update.sh ├── versions.json └── versions.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | /*/**/*.conf linguist-generated 2 | /*/**/Dockerfile linguist-generated 3 | /*/**/docker-entrypoint.sh linguist-generated 4 | /Dockerfile*.template linguist-language=Dockerfile 5 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: GitHub CI 2 | 3 | on: 4 | pull_request: 5 | push: 6 | workflow_dispatch: 7 | schedule: 8 | - cron: 0 0 * * 0 9 | 10 | defaults: 11 | run: 12 | shell: 'bash -Eeuo pipefail -x {0}' 13 | 14 | concurrency: 15 | group: ${{ github.ref }} 16 | cancel-in-progress: true 17 | 18 | jobs: 19 | 20 | generate-jobs: 21 | name: Generate Jobs 22 | runs-on: ubuntu-latest 23 | outputs: 24 | strategy: ${{ steps.generate-jobs.outputs.strategy }} 25 | steps: 26 | - uses: actions/checkout@v4 27 | - uses: docker-library/bashbrew@HEAD 28 | - id: generate-jobs 29 | name: Generate Jobs 30 | run: | 31 | strategy="$("$BASHBREW_SCRIPTS/github-actions/generate.sh")" 32 | 33 | strategy="$("$BASHBREW_SCRIPTS/github-actions/munge-i386.sh" -c <<<"$strategy")" 34 | 35 | strategy="$(jq -c '.matrix.include |= [ .[] | select(.name | (test("i386") | not) or test("alpine")) ]' <<<"$strategy")" # Ubuntu no longer supports i386 (so we can only build test Alpine there; qemu-user-static is too slow for other arches) 36 | 37 | EOF="EOF-$RANDOM-$RANDOM-$RANDOM" 38 | echo "strategy<<$EOF" >> "$GITHUB_OUTPUT" 39 | jq <<<"$strategy" . | tee -a "$GITHUB_OUTPUT" 40 | echo "$EOF" >> "$GITHUB_OUTPUT" 41 | 42 | test: 43 | needs: generate-jobs 44 | strategy: ${{ fromJson(needs.generate-jobs.outputs.strategy) }} 45 | name: ${{ matrix.name }} 46 | runs-on: ${{ matrix.os }} 47 | steps: 48 | - uses: actions/checkout@v4 49 | - name: Prepare Environment 50 | run: ${{ matrix.runs.prepare }} 51 | - name: Pull Dependencies 52 | run: ${{ matrix.runs.pull }} 53 | - name: Build ${{ matrix.name }} 54 | run: ${{ matrix.runs.build }} 55 | - name: History ${{ matrix.name }} 56 | run: ${{ matrix.runs.history }} 57 | - name: Test ${{ matrix.name }} 58 | run: ${{ matrix.runs.test }} 59 | - name: '"docker images"' 60 | run: ${{ matrix.runs.images }} 61 | -------------------------------------------------------------------------------- /.github/workflows/verify-templating.yml: -------------------------------------------------------------------------------- 1 | name: Verify Templating 2 | 3 | on: 4 | pull_request: 5 | push: 6 | workflow_dispatch: 7 | 8 | defaults: 9 | run: 10 | shell: 'bash -Eeuo pipefail -x {0}' 11 | 12 | jobs: 13 | apply-templates: 14 | name: Check For Uncomitted Changes 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - run: ./apply-templates.sh 19 | - run: git diff --exit-code 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .jq-template.awk 2 | -------------------------------------------------------------------------------- /3.13/alpine/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /3.13/alpine/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /3.13/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # Alpine Linux is not officially supported by the RabbitMQ team -- use at your own risk! 8 | FROM alpine:3.22 as build-base 9 | 10 | RUN apk add --no-cache \ 11 | build-base \ 12 | dpkg-dev \ 13 | dpkg \ 14 | gnupg \ 15 | libc-dev \ 16 | linux-headers \ 17 | ncurses-dev 18 | 19 | FROM build-base as openssl-builder 20 | 21 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 22 | 23 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 24 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 25 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 26 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:3.13 --build-arg PGP_KEYSERVER=pgpkeys.eu 3.13/ubuntu 27 | # For context, see https://github.com/docker-library/official-images/issues/4252 28 | 29 | ENV OPENSSL_VERSION 3.1.8 30 | ENV OPENSSL_SOURCE_SHA256="d319da6aecde3aa6f426b44bbf997406d95275c5c59ab6f6ef53caaa079f456f" 31 | # https://www.openssl.org/source/ 32 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 33 | 34 | ENV OTP_VERSION 26.2.5.12 35 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 36 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 37 | ENV OTP_SOURCE_SHA256="5738e05890777716d3f38863aab391988f62529bba7a6299f39d14bc45410412" 38 | 39 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 40 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 41 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 42 | 43 | # Install dependencies required to build Erlang/OTP from source 44 | # https://erlang.org/doc/installation_guide/INSTALL.html 45 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 46 | # gnupg: Required to verify OpenSSL artefacts 47 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 48 | RUN set -eux; \ 49 | # /usr/local/src doesn't exist in Alpine by default 50 | mkdir -p /usr/local/src; \ 51 | \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum -c -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 73 | apkArch="$(apk --print-arch)"; \ 74 | # https://dl-cdn.alpinelinux.org/alpine/edge/main/ 75 | case "$apkArch" in \ 76 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 77 | aarch64) opensslMachine='linux-aarch64' ;; \ 78 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 79 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 80 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv6+fp' ;; \ 81 | armv7) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 82 | ppc64le) opensslMachine='linux-ppc64le' ;; \ 83 | riscv64) opensslMachine='linux64-riscv64' ;; \ 84 | s390x) opensslMachine='linux64-s390x' ;; \ 85 | x86) opensslMachine='linux-x86' ;; \ 86 | x86_64) opensslMachine='linux-x86_64' ;; \ 87 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 88 | esac; \ 89 | MACHINE="$opensslMachine" \ 90 | RELEASE="4.x.y-z" \ 91 | SYSTEM='Linux' \ 92 | BUILD='???' \ 93 | ./Configure \ 94 | "$opensslMachine" \ 95 | enable-fips \ 96 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 97 | --openssldir="$OPENSSL_CONFIG_DIR" \ 98 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 99 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 100 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 101 | ${opensslExtraConfig:-} \ 102 | ; \ 103 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 104 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 105 | make install_sw install_ssldirs install_fips; \ 106 | # use Alpine's CA certificates 107 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 108 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 109 | 110 | # smoke test 111 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 112 | 113 | FROM openssl-builder as erlang-builder 114 | 115 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 116 | 117 | RUN set -eux; \ 118 | # /usr/local/src doesn't exist in Alpine by default 119 | mkdir -p /usr/local/src; \ 120 | \ 121 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 122 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 123 | \ 124 | # Download, verify & extract OTP_SOURCE 125 | mkdir -p "$OTP_PATH"; \ 126 | wget --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 127 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum -c -; \ 128 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 129 | \ 130 | # Configure Erlang/OTP for compilation, disable unused features & applications 131 | # https://erlang.org/doc/applications.html 132 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 133 | cd "$OTP_PATH"; \ 134 | export ERL_TOP="$OTP_PATH"; \ 135 | export CFLAGS='-g -O2'; \ 136 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 137 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 138 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 139 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 140 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 141 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 142 | jitFlag=; \ 143 | case "$dpkgArch" in \ 144 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 145 | esac; \ 146 | ./configure \ 147 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 148 | --host="$hostArch" \ 149 | --build="$buildArch" \ 150 | --disable-hipe \ 151 | --disable-sctp \ 152 | --disable-silent-rules \ 153 | --enable-builtin-zlib \ 154 | --enable-clock-gettime \ 155 | --enable-hybrid-heap \ 156 | --enable-kernel-poll \ 157 | --enable-smp-support \ 158 | --enable-threads \ 159 | --with-microstate-accounting=extra \ 160 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 161 | --without-common_test \ 162 | --without-debugger \ 163 | --without-dialyzer \ 164 | --without-diameter \ 165 | --without-edoc \ 166 | --without-erl_docgen \ 167 | --without-et \ 168 | --without-eunit \ 169 | --without-ftp \ 170 | --without-hipe \ 171 | --without-jinterface \ 172 | --without-megaco \ 173 | --without-observer \ 174 | --without-odbc \ 175 | --without-reltool \ 176 | --without-snmp \ 177 | --without-ssh \ 178 | --without-tftp \ 179 | --without-wx \ 180 | $jitFlag \ 181 | ; \ 182 | # Compile & install Erlang/OTP 183 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 184 | make install; \ 185 | \ 186 | # Remove unnecessary files 187 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 188 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 189 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 190 | 191 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 192 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 193 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 194 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 195 | 196 | FROM alpine:3.22 197 | 198 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 199 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 200 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 201 | 202 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 203 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 204 | 205 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 206 | 207 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 208 | 209 | RUN set -eux; \ 210 | # Configure OpenSSL to use system certs 211 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 212 | \ 213 | # Ensure run-time dependencies are installed 214 | runDeps="$( \ 215 | scanelf --needed --nobanner --format '%n#p' --recursive $ERLANG_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX \ 216 | | tr ',' '\n' \ 217 | | sort -u \ 218 | | grep -v '^$\|lib\(crypto\|ssl\)' \ 219 | | awk 'system("test -e /usr/local/lib/" $1) == 0 { next } { print "so:" $1 }' \ 220 | )"; \ 221 | apk add --no-cache --virtual .otp-run-deps $runDeps; \ 222 | \ 223 | # Check that OpenSSL still works after copying from previous builder 224 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 225 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 226 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 227 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 228 | openssl version; \ 229 | openssl version -d; \ 230 | \ 231 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 232 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 233 | \ 234 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 235 | addgroup -g 101 -S rabbitmq; \ 236 | adduser -u 100 -S -h "$RABBITMQ_DATA_DIR" -G rabbitmq rabbitmq; \ 237 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 238 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 239 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 240 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie; \ 241 | \ 242 | apk add --no-cache \ 243 | # grab su-exec for easy step-down from root 244 | 'su-exec>=0.2' \ 245 | # bash for docker-entrypoint.sh 246 | bash \ 247 | # "ps" for "rabbitmqctl wait" (https://github.com/docker-library/rabbitmq/issues/162) 248 | procps \ 249 | # Bring in tzdata so users could set the timezones through the environment 250 | tzdata 251 | 252 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 253 | ENV RABBITMQ_VERSION 3.13.7 254 | # https://www.rabbitmq.com/signatures.html#importing-gpg 255 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 256 | ENV RABBITMQ_HOME /opt/rabbitmq 257 | 258 | # Add RabbitMQ to PATH 259 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 260 | 261 | # Install RabbitMQ 262 | RUN set -eux; \ 263 | # /usr/local/src doesn't exist in Alpine by default 264 | mkdir -p /usr/local/src; \ 265 | \ 266 | apk add --no-cache --virtual .build-deps \ 267 | gnupg \ 268 | xz \ 269 | ; \ 270 | \ 271 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 272 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 273 | \ 274 | wget --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 275 | wget --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 276 | \ 277 | export GNUPGHOME="$(mktemp -d)"; \ 278 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 279 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 280 | gpgconf --kill all; \ 281 | rm -rf "$GNUPGHOME"; \ 282 | \ 283 | mkdir -p "$RABBITMQ_HOME"; \ 284 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 285 | rm -rf "$RABBITMQ_PATH"*; \ 286 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 287 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 288 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 289 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 290 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 291 | \ 292 | apk del --no-network .build-deps; \ 293 | \ 294 | # verify assumption of no stale cookies 295 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 296 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 297 | # If they all succeed, it's safe to assume that things have been set up correctly 298 | su-exec rabbitmq rabbitmqctl help; \ 299 | su-exec rabbitmq rabbitmqctl list_ciphers; \ 300 | su-exec rabbitmq rabbitmq-plugins list; \ 301 | # no stale cookies 302 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 303 | 304 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 305 | RUN su-exec rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 306 | 307 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 308 | RUN ln -sf /opt/rabbitmq/plugins /plugins 309 | 310 | # set home so that any `--user` knows where to put the erlang cookie 311 | ENV HOME $RABBITMQ_DATA_DIR 312 | # Hint that the data (a.k.a. home dir) dir should be separate volume 313 | VOLUME $RABBITMQ_DATA_DIR 314 | 315 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 316 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 317 | # https://docs.docker.com/samples/library/ubuntu/#locales 318 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 319 | 320 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 321 | COPY docker-entrypoint.sh /usr/local/bin/ 322 | ENTRYPOINT ["docker-entrypoint.sh"] 323 | 324 | EXPOSE 4369 5671 5672 15691 15692 25672 325 | CMD ["rabbitmq-server"] 326 | -------------------------------------------------------------------------------- /3.13/alpine/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec su-exec rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /3.13/alpine/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:3.13-alpine 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apk add --no-cache python3; \ 19 | rabbitmqadmin --version 20 | 21 | EXPOSE 15671 15672 22 | -------------------------------------------------------------------------------- /3.13/ubuntu/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /3.13/ubuntu/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /3.13/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # The official Canonical Ubuntu Focal image is ideal from a security perspective, 8 | # especially for the enterprises that we, the RabbitMQ team, have to deal with 9 | FROM ubuntu:24.04 as build-base 10 | 11 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 12 | 13 | RUN set -eux; \ 14 | apt-get update; \ 15 | apt-get install -y --no-install-recommends \ 16 | build-essential \ 17 | ca-certificates \ 18 | gnupg \ 19 | libncurses5-dev \ 20 | wget 21 | 22 | FROM build-base as openssl-builder 23 | 24 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 25 | 26 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 27 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 28 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 29 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:3.13 --build-arg PGP_KEYSERVER=pgpkeys.eu 3.13/ubuntu 30 | # For context, see https://github.com/docker-library/official-images/issues/4252 31 | 32 | ENV OPENSSL_VERSION 3.1.8 33 | ENV OPENSSL_SOURCE_SHA256="d319da6aecde3aa6f426b44bbf997406d95275c5c59ab6f6ef53caaa079f456f" 34 | # https://www.openssl.org/source/ 35 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 36 | 37 | ENV OTP_VERSION 26.2.5.12 38 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 39 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 40 | ENV OTP_SOURCE_SHA256="5738e05890777716d3f38863aab391988f62529bba7a6299f39d14bc45410412" 41 | 42 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 43 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 44 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 45 | 46 | # Install dependencies required to build Erlang/OTP from source 47 | # https://erlang.org/doc/installation_guide/INSTALL.html 48 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 49 | # gnupg: Required to verify OpenSSL artefacts 50 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 51 | RUN set -eux; \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum --check --strict -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # without specifying "--libdir", Erlang will fail during "crypto:supports()" looking for a "pthread_atfork" function that doesn't exist (but only on arm32v7/armhf??) 73 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 74 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 75 | # https://deb.debian.org/debian/dists/unstable/main/ 76 | case "$dpkgArch" in \ 77 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 78 | amd64) opensslMachine='linux-x86_64' ;; \ 79 | arm64) opensslMachine='linux-aarch64' ;; \ 80 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 81 | # https://wiki.debian.org/ArchitectureSpecificsMemo#Architecture_baselines 82 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 83 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 84 | i386) opensslMachine='linux-x86' ;; \ 85 | ppc64el) opensslMachine='linux-ppc64le' ;; \ 86 | riscv64) opensslMachine='linux64-riscv64' ;; \ 87 | s390x) opensslMachine='linux64-s390x' ;; \ 88 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 89 | esac; \ 90 | MACHINE="$opensslMachine" \ 91 | RELEASE="4.x.y-z" \ 92 | SYSTEM='Linux' \ 93 | BUILD='???' \ 94 | ./Configure \ 95 | "$opensslMachine" \ 96 | enable-fips \ 97 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 98 | --openssldir="$OPENSSL_CONFIG_DIR" \ 99 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 100 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 101 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 102 | ${opensslExtraConfig:-} \ 103 | ; \ 104 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 105 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 106 | make install_sw install_ssldirs install_fips; \ 107 | ldconfig; \ 108 | # use Debian's CA certificates 109 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 110 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 111 | 112 | # smoke test 113 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 114 | 115 | FROM openssl-builder as erlang-builder 116 | 117 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 118 | 119 | RUN set -eux; \ 120 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 121 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 122 | \ 123 | # Download, verify & extract OTP_SOURCE 124 | mkdir -p "$OTP_PATH"; \ 125 | wget --progress dot:giga --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 126 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ 127 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 128 | \ 129 | # backport https://github.com/erlang/otp/pull/7952 (applied upstream in OTP 27+) to fix time64 compilation issues on 32bit architectures 130 | # see also https://bugs.debian.org/1067701, https://salsa.debian.org/erlang-team/packages/erlang/-/blob/89c4e190c6d1d7ee0133d9a8d6bf651ff1861e46/debian/patches/time64.patch 131 | wget --output-document otp-time64.patch 'https://github.com/erlang/otp/pull/7952.patch?full_index=1'; \ 132 | echo 'd1a0c0433a9a08c83171bedd438dd59bb336b40ec75f59edfc3a647b8b0c612d *otp-time64.patch' | sha256sum --check --strict -; \ 133 | patch --input="$PWD/otp-time64.patch" --directory="$OTP_PATH" --strip=1; \ 134 | rm otp-time64.patch; \ 135 | \ 136 | # Configure Erlang/OTP for compilation, disable unused features & applications 137 | # https://erlang.org/doc/applications.html 138 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 139 | cd "$OTP_PATH"; \ 140 | export ERL_TOP="$OTP_PATH"; \ 141 | CFLAGS="$(dpkg-buildflags --get CFLAGS)"; export CFLAGS; \ 142 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$OPENSSL_INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 143 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 144 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 145 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 146 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 147 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 148 | jitFlag=; \ 149 | case "$dpkgArch" in \ 150 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 151 | esac; \ 152 | ./configure \ 153 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 154 | --host="$hostArch" \ 155 | --build="$buildArch" \ 156 | --disable-hipe \ 157 | --disable-sctp \ 158 | --disable-silent-rules \ 159 | --enable-builtin-zlib \ 160 | --enable-clock-gettime \ 161 | --enable-hybrid-heap \ 162 | --enable-kernel-poll \ 163 | --enable-smp-support \ 164 | --enable-threads \ 165 | --with-microstate-accounting=extra \ 166 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 167 | --without-common_test \ 168 | --without-debugger \ 169 | --without-dialyzer \ 170 | --without-diameter \ 171 | --without-edoc \ 172 | --without-erl_docgen \ 173 | --without-et \ 174 | --without-eunit \ 175 | --without-ftp \ 176 | --without-hipe \ 177 | --without-jinterface \ 178 | --without-megaco \ 179 | --without-observer \ 180 | --without-odbc \ 181 | --without-reltool \ 182 | --without-snmp \ 183 | --without-ssh \ 184 | --without-tftp \ 185 | --without-wx \ 186 | $jitFlag \ 187 | ; \ 188 | \ 189 | # Compile & install Erlang/OTP 190 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 191 | make install; \ 192 | \ 193 | # Remove unnecessary files 194 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 195 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 196 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 197 | 198 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 199 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 200 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 201 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 202 | 203 | FROM ubuntu:24.04 204 | 205 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 206 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 207 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 208 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 209 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 210 | 211 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 212 | 213 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 214 | 215 | RUN set -eux; \ 216 | # Configure OpenSSL to use system certs 217 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 218 | \ 219 | # Check that OpenSSL still works after copying from previous builder 220 | ldconfig; \ 221 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 222 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 223 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 224 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 225 | openssl version; \ 226 | openssl version -d; \ 227 | \ 228 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 229 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 230 | \ 231 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 232 | groupadd --gid 999 --system rabbitmq; \ 233 | useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq; \ 234 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 235 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 236 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 237 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie 238 | 239 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 240 | ENV RABBITMQ_VERSION 3.13.7 241 | # https://www.rabbitmq.com/signatures.html#importing-gpg 242 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 243 | ENV RABBITMQ_HOME /opt/rabbitmq 244 | 245 | # Add RabbitMQ to PATH 246 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 247 | 248 | # Install RabbitMQ 249 | RUN set -eux; \ 250 | export DEBIAN_FRONTEND=noninteractive; \ 251 | apt-get update; \ 252 | apt-get install --yes --no-install-recommends \ 253 | ca-certificates \ 254 | # grab gosu for easy step-down from root 255 | gosu \ 256 | # Bring in tzdata so users could set the timezones through the environment 257 | tzdata \ 258 | ; \ 259 | # verify that the "gosu" binary works 260 | gosu nobody true; \ 261 | \ 262 | savedAptMark="$(apt-mark showmanual)"; \ 263 | apt-get install --yes --no-install-recommends \ 264 | gnupg \ 265 | wget \ 266 | xz-utils \ 267 | ; \ 268 | rm -rf /var/lib/apt/lists/*; \ 269 | \ 270 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 271 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 272 | \ 273 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 274 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 275 | \ 276 | export GNUPGHOME="$(mktemp -d)"; \ 277 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 278 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 279 | gpgconf --kill all; \ 280 | rm -rf "$GNUPGHOME"; \ 281 | \ 282 | mkdir -p "$RABBITMQ_HOME"; \ 283 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 284 | rm -rf "$RABBITMQ_PATH"*; \ 285 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 286 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 287 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 288 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 289 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 290 | \ 291 | apt-mark auto '.*' > /dev/null; \ 292 | apt-mark manual $savedAptMark; \ 293 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 294 | \ 295 | # verify assumption of no stale cookies 296 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 297 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 298 | # If they all succeed, it's safe to assume that things have been set up correctly 299 | gosu rabbitmq rabbitmqctl help; \ 300 | gosu rabbitmq rabbitmqctl list_ciphers; \ 301 | gosu rabbitmq rabbitmq-plugins list; \ 302 | # no stale cookies 303 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 304 | 305 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 306 | RUN gosu rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 307 | 308 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 309 | RUN ln -sf /opt/rabbitmq/plugins /plugins 310 | 311 | # set home so that any `--user` knows where to put the erlang cookie 312 | ENV HOME $RABBITMQ_DATA_DIR 313 | # Hint that the data (a.k.a. home dir) dir should be separate volume 314 | VOLUME $RABBITMQ_DATA_DIR 315 | 316 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 317 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 318 | # https://docs.docker.com/samples/library/ubuntu/#locales 319 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 320 | 321 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 322 | COPY docker-entrypoint.sh /usr/local/bin/ 323 | ENTRYPOINT ["docker-entrypoint.sh"] 324 | 325 | EXPOSE 4369 5671 5672 15691 15692 25672 326 | CMD ["rabbitmq-server"] 327 | -------------------------------------------------------------------------------- /3.13/ubuntu/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec gosu rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /3.13/ubuntu/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:3.13 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apt-get update; \ 19 | apt-get install -y --no-install-recommends python3; \ 20 | rm -rf /var/lib/apt/lists/*; \ 21 | rabbitmqadmin --version 22 | 23 | EXPOSE 15671 15672 24 | -------------------------------------------------------------------------------- /4.0/alpine/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /4.0/alpine/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /4.0/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # Alpine Linux is not officially supported by the RabbitMQ team -- use at your own risk! 8 | FROM alpine:3.22 as build-base 9 | 10 | RUN apk add --no-cache \ 11 | build-base \ 12 | dpkg-dev \ 13 | dpkg \ 14 | gnupg \ 15 | libc-dev \ 16 | linux-headers \ 17 | ncurses-dev 18 | 19 | FROM build-base as openssl-builder 20 | 21 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 22 | 23 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 24 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 25 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 26 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:4.0 --build-arg PGP_KEYSERVER=pgpkeys.eu 4.0/ubuntu 27 | # For context, see https://github.com/docker-library/official-images/issues/4252 28 | 29 | ENV OPENSSL_VERSION 3.3.3 30 | ENV OPENSSL_SOURCE_SHA256="712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539" 31 | # https://www.openssl.org/source/ 32 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 33 | 34 | ENV OTP_VERSION 27.3.4 35 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 36 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 37 | ENV OTP_SOURCE_SHA256="c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b" 38 | 39 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 40 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 41 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 42 | 43 | # Install dependencies required to build Erlang/OTP from source 44 | # https://erlang.org/doc/installation_guide/INSTALL.html 45 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 46 | # gnupg: Required to verify OpenSSL artefacts 47 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 48 | RUN set -eux; \ 49 | # /usr/local/src doesn't exist in Alpine by default 50 | mkdir -p /usr/local/src; \ 51 | \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum -c -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 73 | apkArch="$(apk --print-arch)"; \ 74 | # https://dl-cdn.alpinelinux.org/alpine/edge/main/ 75 | case "$apkArch" in \ 76 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 77 | aarch64) opensslMachine='linux-aarch64' ;; \ 78 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 79 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 80 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv6+fp' ;; \ 81 | armv7) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 82 | ppc64le) opensslMachine='linux-ppc64le' ;; \ 83 | riscv64) opensslMachine='linux64-riscv64' ;; \ 84 | s390x) opensslMachine='linux64-s390x' ;; \ 85 | x86) opensslMachine='linux-x86' ;; \ 86 | x86_64) opensslMachine='linux-x86_64' ;; \ 87 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 88 | esac; \ 89 | MACHINE="$opensslMachine" \ 90 | RELEASE="4.x.y-z" \ 91 | SYSTEM='Linux' \ 92 | BUILD='???' \ 93 | ./Configure \ 94 | "$opensslMachine" \ 95 | enable-fips \ 96 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 97 | --openssldir="$OPENSSL_CONFIG_DIR" \ 98 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 99 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 100 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 101 | ${opensslExtraConfig:-} \ 102 | ; \ 103 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 104 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 105 | make install_sw install_ssldirs install_fips; \ 106 | # use Alpine's CA certificates 107 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 108 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 109 | 110 | # smoke test 111 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 112 | 113 | FROM openssl-builder as erlang-builder 114 | 115 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 116 | 117 | RUN set -eux; \ 118 | # /usr/local/src doesn't exist in Alpine by default 119 | mkdir -p /usr/local/src; \ 120 | \ 121 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 122 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 123 | \ 124 | # Download, verify & extract OTP_SOURCE 125 | mkdir -p "$OTP_PATH"; \ 126 | wget --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 127 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum -c -; \ 128 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 129 | \ 130 | # Configure Erlang/OTP for compilation, disable unused features & applications 131 | # https://erlang.org/doc/applications.html 132 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 133 | cd "$OTP_PATH"; \ 134 | export ERL_TOP="$OTP_PATH"; \ 135 | export CFLAGS='-g -O2'; \ 136 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 137 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 138 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 139 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 140 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 141 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 142 | jitFlag=; \ 143 | case "$dpkgArch" in \ 144 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 145 | esac; \ 146 | ./configure \ 147 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 148 | --host="$hostArch" \ 149 | --build="$buildArch" \ 150 | --disable-hipe \ 151 | --disable-sctp \ 152 | --disable-silent-rules \ 153 | --enable-builtin-zlib \ 154 | --enable-clock-gettime \ 155 | --enable-hybrid-heap \ 156 | --enable-kernel-poll \ 157 | --enable-smp-support \ 158 | --enable-threads \ 159 | --with-microstate-accounting=extra \ 160 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 161 | --without-common_test \ 162 | --without-debugger \ 163 | --without-dialyzer \ 164 | --without-diameter \ 165 | --without-edoc \ 166 | --without-erl_docgen \ 167 | --without-et \ 168 | --without-eunit \ 169 | --without-ftp \ 170 | --without-hipe \ 171 | --without-jinterface \ 172 | --without-megaco \ 173 | --without-observer \ 174 | --without-odbc \ 175 | --without-reltool \ 176 | --without-snmp \ 177 | --without-ssh \ 178 | --without-tftp \ 179 | --without-wx \ 180 | $jitFlag \ 181 | ; \ 182 | # Compile & install Erlang/OTP 183 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 184 | make install; \ 185 | \ 186 | # Remove unnecessary files 187 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 188 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 189 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 190 | 191 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 192 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 193 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 194 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 195 | 196 | FROM alpine:3.22 197 | 198 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 199 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 200 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 201 | 202 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 203 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 204 | 205 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 206 | 207 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 208 | 209 | RUN set -eux; \ 210 | # Configure OpenSSL to use system certs 211 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 212 | \ 213 | # Ensure run-time dependencies are installed 214 | runDeps="$( \ 215 | scanelf --needed --nobanner --format '%n#p' --recursive $ERLANG_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX \ 216 | | tr ',' '\n' \ 217 | | sort -u \ 218 | | grep -v '^$\|lib\(crypto\|ssl\)' \ 219 | | awk 'system("test -e /usr/local/lib/" $1) == 0 { next } { print "so:" $1 }' \ 220 | )"; \ 221 | apk add --no-cache --virtual .otp-run-deps $runDeps; \ 222 | \ 223 | # Check that OpenSSL still works after copying from previous builder 224 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 225 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 226 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 227 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 228 | openssl version; \ 229 | openssl version -d; \ 230 | \ 231 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 232 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 233 | \ 234 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 235 | addgroup -g 101 -S rabbitmq; \ 236 | adduser -u 100 -S -h "$RABBITMQ_DATA_DIR" -G rabbitmq rabbitmq; \ 237 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 238 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 239 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 240 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie; \ 241 | \ 242 | apk add --no-cache \ 243 | # grab su-exec for easy step-down from root 244 | 'su-exec>=0.2' \ 245 | # bash for docker-entrypoint.sh 246 | bash \ 247 | # "ps" for "rabbitmqctl wait" (https://github.com/docker-library/rabbitmq/issues/162) 248 | procps \ 249 | # Bring in tzdata so users could set the timezones through the environment 250 | tzdata 251 | 252 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 253 | ENV RABBITMQ_VERSION 4.0.9 254 | # https://www.rabbitmq.com/signatures.html#importing-gpg 255 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 256 | ENV RABBITMQ_HOME /opt/rabbitmq 257 | 258 | # Add RabbitMQ to PATH 259 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 260 | 261 | # Install RabbitMQ 262 | RUN set -eux; \ 263 | # /usr/local/src doesn't exist in Alpine by default 264 | mkdir -p /usr/local/src; \ 265 | \ 266 | apk add --no-cache --virtual .build-deps \ 267 | gnupg \ 268 | xz \ 269 | ; \ 270 | \ 271 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 272 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 273 | \ 274 | wget --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 275 | wget --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 276 | \ 277 | export GNUPGHOME="$(mktemp -d)"; \ 278 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 279 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 280 | gpgconf --kill all; \ 281 | rm -rf "$GNUPGHOME"; \ 282 | \ 283 | mkdir -p "$RABBITMQ_HOME"; \ 284 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 285 | rm -rf "$RABBITMQ_PATH"*; \ 286 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 287 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 288 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 289 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 290 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 291 | \ 292 | apk del --no-network .build-deps; \ 293 | \ 294 | # verify assumption of no stale cookies 295 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 296 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 297 | # If they all succeed, it's safe to assume that things have been set up correctly 298 | su-exec rabbitmq rabbitmqctl help; \ 299 | su-exec rabbitmq rabbitmqctl list_ciphers; \ 300 | su-exec rabbitmq rabbitmq-plugins list; \ 301 | # no stale cookies 302 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 303 | 304 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 305 | RUN su-exec rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 306 | 307 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 308 | RUN ln -sf /opt/rabbitmq/plugins /plugins 309 | 310 | # set home so that any `--user` knows where to put the erlang cookie 311 | ENV HOME $RABBITMQ_DATA_DIR 312 | # Hint that the data (a.k.a. home dir) dir should be separate volume 313 | VOLUME $RABBITMQ_DATA_DIR 314 | 315 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 316 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 317 | # https://docs.docker.com/samples/library/ubuntu/#locales 318 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 319 | 320 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 321 | COPY docker-entrypoint.sh /usr/local/bin/ 322 | ENTRYPOINT ["docker-entrypoint.sh"] 323 | 324 | EXPOSE 4369 5671 5672 15691 15692 25672 325 | CMD ["rabbitmq-server"] 326 | -------------------------------------------------------------------------------- /4.0/alpine/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec su-exec rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /4.0/alpine/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:4.0-alpine 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apk add --no-cache python3; \ 19 | rabbitmqadmin --version 20 | 21 | EXPOSE 15671 15672 22 | -------------------------------------------------------------------------------- /4.0/ubuntu/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /4.0/ubuntu/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /4.0/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # The official Canonical Ubuntu Focal image is ideal from a security perspective, 8 | # especially for the enterprises that we, the RabbitMQ team, have to deal with 9 | FROM ubuntu:24.04 as build-base 10 | 11 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 12 | 13 | RUN set -eux; \ 14 | apt-get update; \ 15 | apt-get install -y --no-install-recommends \ 16 | build-essential \ 17 | ca-certificates \ 18 | gnupg \ 19 | libncurses5-dev \ 20 | wget 21 | 22 | FROM build-base as openssl-builder 23 | 24 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 25 | 26 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 27 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 28 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 29 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:4.0 --build-arg PGP_KEYSERVER=pgpkeys.eu 4.0/ubuntu 30 | # For context, see https://github.com/docker-library/official-images/issues/4252 31 | 32 | ENV OPENSSL_VERSION 3.3.3 33 | ENV OPENSSL_SOURCE_SHA256="712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539" 34 | # https://www.openssl.org/source/ 35 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 36 | 37 | ENV OTP_VERSION 27.3.4 38 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 39 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 40 | ENV OTP_SOURCE_SHA256="c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b" 41 | 42 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 43 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 44 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 45 | 46 | # Install dependencies required to build Erlang/OTP from source 47 | # https://erlang.org/doc/installation_guide/INSTALL.html 48 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 49 | # gnupg: Required to verify OpenSSL artefacts 50 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 51 | RUN set -eux; \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum --check --strict -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # without specifying "--libdir", Erlang will fail during "crypto:supports()" looking for a "pthread_atfork" function that doesn't exist (but only on arm32v7/armhf??) 73 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 74 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 75 | # https://deb.debian.org/debian/dists/unstable/main/ 76 | case "$dpkgArch" in \ 77 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 78 | amd64) opensslMachine='linux-x86_64' ;; \ 79 | arm64) opensslMachine='linux-aarch64' ;; \ 80 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 81 | # https://wiki.debian.org/ArchitectureSpecificsMemo#Architecture_baselines 82 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 83 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 84 | i386) opensslMachine='linux-x86' ;; \ 85 | ppc64el) opensslMachine='linux-ppc64le' ;; \ 86 | riscv64) opensslMachine='linux64-riscv64' ;; \ 87 | s390x) opensslMachine='linux64-s390x' ;; \ 88 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 89 | esac; \ 90 | MACHINE="$opensslMachine" \ 91 | RELEASE="4.x.y-z" \ 92 | SYSTEM='Linux' \ 93 | BUILD='???' \ 94 | ./Configure \ 95 | "$opensslMachine" \ 96 | enable-fips \ 97 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 98 | --openssldir="$OPENSSL_CONFIG_DIR" \ 99 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 100 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 101 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 102 | ${opensslExtraConfig:-} \ 103 | ; \ 104 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 105 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 106 | make install_sw install_ssldirs install_fips; \ 107 | ldconfig; \ 108 | # use Debian's CA certificates 109 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 110 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 111 | 112 | # smoke test 113 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 114 | 115 | FROM openssl-builder as erlang-builder 116 | 117 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 118 | 119 | RUN set -eux; \ 120 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 121 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 122 | \ 123 | # Download, verify & extract OTP_SOURCE 124 | mkdir -p "$OTP_PATH"; \ 125 | wget --progress dot:giga --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 126 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ 127 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 128 | \ 129 | # Configure Erlang/OTP for compilation, disable unused features & applications 130 | # https://erlang.org/doc/applications.html 131 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 132 | cd "$OTP_PATH"; \ 133 | export ERL_TOP="$OTP_PATH"; \ 134 | CFLAGS="$(dpkg-buildflags --get CFLAGS)"; export CFLAGS; \ 135 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$OPENSSL_INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 136 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 137 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 138 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 139 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 140 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 141 | jitFlag=; \ 142 | case "$dpkgArch" in \ 143 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 144 | esac; \ 145 | ./configure \ 146 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 147 | --host="$hostArch" \ 148 | --build="$buildArch" \ 149 | --disable-hipe \ 150 | --disable-sctp \ 151 | --disable-silent-rules \ 152 | --enable-builtin-zlib \ 153 | --enable-clock-gettime \ 154 | --enable-hybrid-heap \ 155 | --enable-kernel-poll \ 156 | --enable-smp-support \ 157 | --enable-threads \ 158 | --with-microstate-accounting=extra \ 159 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 160 | --without-common_test \ 161 | --without-debugger \ 162 | --without-dialyzer \ 163 | --without-diameter \ 164 | --without-edoc \ 165 | --without-erl_docgen \ 166 | --without-et \ 167 | --without-eunit \ 168 | --without-ftp \ 169 | --without-hipe \ 170 | --without-jinterface \ 171 | --without-megaco \ 172 | --without-observer \ 173 | --without-odbc \ 174 | --without-reltool \ 175 | --without-snmp \ 176 | --without-ssh \ 177 | --without-tftp \ 178 | --without-wx \ 179 | $jitFlag \ 180 | ; \ 181 | \ 182 | # Compile & install Erlang/OTP 183 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 184 | make install; \ 185 | \ 186 | # Remove unnecessary files 187 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 188 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 189 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 190 | 191 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 192 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 193 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 194 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 195 | 196 | FROM ubuntu:24.04 197 | 198 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 199 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 200 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 201 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 202 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 203 | 204 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 205 | 206 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 207 | 208 | RUN set -eux; \ 209 | # Configure OpenSSL to use system certs 210 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 211 | \ 212 | # Check that OpenSSL still works after copying from previous builder 213 | ldconfig; \ 214 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 215 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 216 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 217 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 218 | openssl version; \ 219 | openssl version -d; \ 220 | \ 221 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 222 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 223 | \ 224 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 225 | groupadd --gid 999 --system rabbitmq; \ 226 | useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq; \ 227 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 228 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 229 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 230 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie 231 | 232 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 233 | ENV RABBITMQ_VERSION 4.0.9 234 | # https://www.rabbitmq.com/signatures.html#importing-gpg 235 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 236 | ENV RABBITMQ_HOME /opt/rabbitmq 237 | 238 | # Add RabbitMQ to PATH 239 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 240 | 241 | # Install RabbitMQ 242 | RUN set -eux; \ 243 | export DEBIAN_FRONTEND=noninteractive; \ 244 | apt-get update; \ 245 | apt-get install --yes --no-install-recommends \ 246 | ca-certificates \ 247 | # grab gosu for easy step-down from root 248 | gosu \ 249 | # Bring in tzdata so users could set the timezones through the environment 250 | tzdata \ 251 | ; \ 252 | # verify that the "gosu" binary works 253 | gosu nobody true; \ 254 | \ 255 | savedAptMark="$(apt-mark showmanual)"; \ 256 | apt-get install --yes --no-install-recommends \ 257 | gnupg \ 258 | wget \ 259 | xz-utils \ 260 | ; \ 261 | rm -rf /var/lib/apt/lists/*; \ 262 | \ 263 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 264 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 265 | \ 266 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 267 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 268 | \ 269 | export GNUPGHOME="$(mktemp -d)"; \ 270 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 271 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 272 | gpgconf --kill all; \ 273 | rm -rf "$GNUPGHOME"; \ 274 | \ 275 | mkdir -p "$RABBITMQ_HOME"; \ 276 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 277 | rm -rf "$RABBITMQ_PATH"*; \ 278 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 279 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 280 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 281 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 282 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 283 | \ 284 | apt-mark auto '.*' > /dev/null; \ 285 | apt-mark manual $savedAptMark; \ 286 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 287 | \ 288 | # verify assumption of no stale cookies 289 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 290 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 291 | # If they all succeed, it's safe to assume that things have been set up correctly 292 | gosu rabbitmq rabbitmqctl help; \ 293 | gosu rabbitmq rabbitmqctl list_ciphers; \ 294 | gosu rabbitmq rabbitmq-plugins list; \ 295 | # no stale cookies 296 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 297 | 298 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 299 | RUN gosu rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 300 | 301 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 302 | RUN ln -sf /opt/rabbitmq/plugins /plugins 303 | 304 | # set home so that any `--user` knows where to put the erlang cookie 305 | ENV HOME $RABBITMQ_DATA_DIR 306 | # Hint that the data (a.k.a. home dir) dir should be separate volume 307 | VOLUME $RABBITMQ_DATA_DIR 308 | 309 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 310 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 311 | # https://docs.docker.com/samples/library/ubuntu/#locales 312 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 313 | 314 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 315 | COPY docker-entrypoint.sh /usr/local/bin/ 316 | ENTRYPOINT ["docker-entrypoint.sh"] 317 | 318 | EXPOSE 4369 5671 5672 15691 15692 25672 319 | CMD ["rabbitmq-server"] 320 | -------------------------------------------------------------------------------- /4.0/ubuntu/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec gosu rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /4.0/ubuntu/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:4.0 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apt-get update; \ 19 | apt-get install -y --no-install-recommends python3; \ 20 | rm -rf /var/lib/apt/lists/*; \ 21 | rabbitmqadmin --version 22 | 23 | EXPOSE 15671 15672 24 | -------------------------------------------------------------------------------- /4.1/alpine/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /4.1/alpine/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /4.1/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # Alpine Linux is not officially supported by the RabbitMQ team -- use at your own risk! 8 | FROM alpine:3.22 as build-base 9 | 10 | RUN apk add --no-cache \ 11 | build-base \ 12 | dpkg-dev \ 13 | dpkg \ 14 | gnupg \ 15 | libc-dev \ 16 | linux-headers \ 17 | ncurses-dev 18 | 19 | FROM build-base as openssl-builder 20 | 21 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 22 | 23 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 24 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 25 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 26 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:4.1 --build-arg PGP_KEYSERVER=pgpkeys.eu 4.1/ubuntu 27 | # For context, see https://github.com/docker-library/official-images/issues/4252 28 | 29 | ENV OPENSSL_VERSION 3.3.3 30 | ENV OPENSSL_SOURCE_SHA256="712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539" 31 | # https://www.openssl.org/source/ 32 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 33 | 34 | ENV OTP_VERSION 27.3.4 35 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 36 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 37 | ENV OTP_SOURCE_SHA256="c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b" 38 | 39 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 40 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 41 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 42 | 43 | # Install dependencies required to build Erlang/OTP from source 44 | # https://erlang.org/doc/installation_guide/INSTALL.html 45 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 46 | # gnupg: Required to verify OpenSSL artefacts 47 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 48 | RUN set -eux; \ 49 | # /usr/local/src doesn't exist in Alpine by default 50 | mkdir -p /usr/local/src; \ 51 | \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum -c -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 73 | apkArch="$(apk --print-arch)"; \ 74 | # https://dl-cdn.alpinelinux.org/alpine/edge/main/ 75 | case "$apkArch" in \ 76 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 77 | aarch64) opensslMachine='linux-aarch64' ;; \ 78 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 79 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 80 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv6+fp' ;; \ 81 | armv7) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 82 | ppc64le) opensslMachine='linux-ppc64le' ;; \ 83 | riscv64) opensslMachine='linux64-riscv64' ;; \ 84 | s390x) opensslMachine='linux64-s390x' ;; \ 85 | x86) opensslMachine='linux-x86' ;; \ 86 | x86_64) opensslMachine='linux-x86_64' ;; \ 87 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 88 | esac; \ 89 | MACHINE="$opensslMachine" \ 90 | RELEASE="4.x.y-z" \ 91 | SYSTEM='Linux' \ 92 | BUILD='???' \ 93 | ./Configure \ 94 | "$opensslMachine" \ 95 | enable-fips \ 96 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 97 | --openssldir="$OPENSSL_CONFIG_DIR" \ 98 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 99 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 100 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 101 | ${opensslExtraConfig:-} \ 102 | ; \ 103 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 104 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 105 | make install_sw install_ssldirs install_fips; \ 106 | # use Alpine's CA certificates 107 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 108 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 109 | 110 | # smoke test 111 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 112 | 113 | FROM openssl-builder as erlang-builder 114 | 115 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 116 | 117 | RUN set -eux; \ 118 | # /usr/local/src doesn't exist in Alpine by default 119 | mkdir -p /usr/local/src; \ 120 | \ 121 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 122 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 123 | \ 124 | # Download, verify & extract OTP_SOURCE 125 | mkdir -p "$OTP_PATH"; \ 126 | wget --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 127 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum -c -; \ 128 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 129 | \ 130 | # Configure Erlang/OTP for compilation, disable unused features & applications 131 | # https://erlang.org/doc/applications.html 132 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 133 | cd "$OTP_PATH"; \ 134 | export ERL_TOP="$OTP_PATH"; \ 135 | export CFLAGS='-g -O2'; \ 136 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 137 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 138 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 139 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 140 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 141 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 142 | jitFlag=; \ 143 | case "$dpkgArch" in \ 144 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 145 | esac; \ 146 | ./configure \ 147 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 148 | --host="$hostArch" \ 149 | --build="$buildArch" \ 150 | --disable-hipe \ 151 | --disable-sctp \ 152 | --disable-silent-rules \ 153 | --enable-builtin-zlib \ 154 | --enable-clock-gettime \ 155 | --enable-hybrid-heap \ 156 | --enable-kernel-poll \ 157 | --enable-smp-support \ 158 | --enable-threads \ 159 | --with-microstate-accounting=extra \ 160 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 161 | --without-common_test \ 162 | --without-debugger \ 163 | --without-dialyzer \ 164 | --without-diameter \ 165 | --without-edoc \ 166 | --without-erl_docgen \ 167 | --without-et \ 168 | --without-eunit \ 169 | --without-ftp \ 170 | --without-hipe \ 171 | --without-jinterface \ 172 | --without-megaco \ 173 | --without-observer \ 174 | --without-odbc \ 175 | --without-reltool \ 176 | --without-snmp \ 177 | --without-ssh \ 178 | --without-tftp \ 179 | --without-wx \ 180 | $jitFlag \ 181 | ; \ 182 | # Compile & install Erlang/OTP 183 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 184 | make install; \ 185 | \ 186 | # Remove unnecessary files 187 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 188 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 189 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 190 | 191 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 192 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 193 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 194 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 195 | 196 | FROM alpine:3.22 197 | 198 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 199 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 200 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 201 | 202 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 203 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 204 | 205 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 206 | 207 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 208 | 209 | RUN set -eux; \ 210 | # Configure OpenSSL to use system certs 211 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 212 | \ 213 | # Ensure run-time dependencies are installed 214 | runDeps="$( \ 215 | scanelf --needed --nobanner --format '%n#p' --recursive $ERLANG_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX \ 216 | | tr ',' '\n' \ 217 | | sort -u \ 218 | | grep -v '^$\|lib\(crypto\|ssl\)' \ 219 | | awk 'system("test -e /usr/local/lib/" $1) == 0 { next } { print "so:" $1 }' \ 220 | )"; \ 221 | apk add --no-cache --virtual .otp-run-deps $runDeps; \ 222 | \ 223 | # Check that OpenSSL still works after copying from previous builder 224 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 225 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 226 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 227 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 228 | openssl version; \ 229 | openssl version -d; \ 230 | \ 231 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 232 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 233 | \ 234 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 235 | addgroup -g 101 -S rabbitmq; \ 236 | adduser -u 100 -S -h "$RABBITMQ_DATA_DIR" -G rabbitmq rabbitmq; \ 237 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 238 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 239 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 240 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie; \ 241 | \ 242 | apk add --no-cache \ 243 | # grab su-exec for easy step-down from root 244 | 'su-exec>=0.2' \ 245 | # bash for docker-entrypoint.sh 246 | bash \ 247 | # "ps" for "rabbitmqctl wait" (https://github.com/docker-library/rabbitmq/issues/162) 248 | procps \ 249 | # Bring in tzdata so users could set the timezones through the environment 250 | tzdata 251 | 252 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 253 | ENV RABBITMQ_VERSION 4.1.0 254 | # https://www.rabbitmq.com/signatures.html#importing-gpg 255 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 256 | ENV RABBITMQ_HOME /opt/rabbitmq 257 | 258 | # Add RabbitMQ to PATH 259 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 260 | 261 | # Install RabbitMQ 262 | RUN set -eux; \ 263 | # /usr/local/src doesn't exist in Alpine by default 264 | mkdir -p /usr/local/src; \ 265 | \ 266 | apk add --no-cache --virtual .build-deps \ 267 | gnupg \ 268 | xz \ 269 | ; \ 270 | \ 271 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 272 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 273 | \ 274 | wget --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 275 | wget --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 276 | \ 277 | export GNUPGHOME="$(mktemp -d)"; \ 278 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 279 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 280 | gpgconf --kill all; \ 281 | rm -rf "$GNUPGHOME"; \ 282 | \ 283 | mkdir -p "$RABBITMQ_HOME"; \ 284 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 285 | rm -rf "$RABBITMQ_PATH"*; \ 286 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 287 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 288 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 289 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 290 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 291 | \ 292 | apk del --no-network .build-deps; \ 293 | \ 294 | # verify assumption of no stale cookies 295 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 296 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 297 | # If they all succeed, it's safe to assume that things have been set up correctly 298 | su-exec rabbitmq rabbitmqctl help; \ 299 | su-exec rabbitmq rabbitmqctl list_ciphers; \ 300 | su-exec rabbitmq rabbitmq-plugins list; \ 301 | # no stale cookies 302 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 303 | 304 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 305 | RUN su-exec rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 306 | 307 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 308 | RUN ln -sf /opt/rabbitmq/plugins /plugins 309 | 310 | # set home so that any `--user` knows where to put the erlang cookie 311 | ENV HOME $RABBITMQ_DATA_DIR 312 | # Hint that the data (a.k.a. home dir) dir should be separate volume 313 | VOLUME $RABBITMQ_DATA_DIR 314 | 315 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 316 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 317 | # https://docs.docker.com/samples/library/ubuntu/#locales 318 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 319 | 320 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 321 | COPY docker-entrypoint.sh /usr/local/bin/ 322 | ENTRYPOINT ["docker-entrypoint.sh"] 323 | 324 | EXPOSE 4369 5671 5672 15691 15692 25672 325 | CMD ["rabbitmq-server"] 326 | -------------------------------------------------------------------------------- /4.1/alpine/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec su-exec rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /4.1/alpine/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:4.1-alpine 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apk add --no-cache python3; \ 19 | rabbitmqadmin --version 20 | 21 | EXPOSE 15671 15672 22 | -------------------------------------------------------------------------------- /4.1/ubuntu/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /4.1/ubuntu/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /4.1/ubuntu/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | # The official Canonical Ubuntu Focal image is ideal from a security perspective, 8 | # especially for the enterprises that we, the RabbitMQ team, have to deal with 9 | FROM ubuntu:24.04 as build-base 10 | 11 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 12 | 13 | RUN set -eux; \ 14 | apt-get update; \ 15 | apt-get install -y --no-install-recommends \ 16 | build-essential \ 17 | ca-certificates \ 18 | gnupg \ 19 | libncurses5-dev \ 20 | wget 21 | 22 | FROM build-base as openssl-builder 23 | 24 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 25 | 26 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 27 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 28 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 29 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:4.1 --build-arg PGP_KEYSERVER=pgpkeys.eu 4.1/ubuntu 30 | # For context, see https://github.com/docker-library/official-images/issues/4252 31 | 32 | ENV OPENSSL_VERSION 3.3.3 33 | ENV OPENSSL_SOURCE_SHA256="712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539" 34 | # https://www.openssl.org/source/ 35 | ENV OPENSSL_PGP_KEY_IDS="0xBA5473A2B0587B07FB27CF2D216094DFD0CB81EF" 36 | 37 | ENV OTP_VERSION 27.3.4 38 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 39 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 40 | ENV OTP_SOURCE_SHA256="c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b" 41 | 42 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 43 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 44 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 45 | 46 | # Install dependencies required to build Erlang/OTP from source 47 | # https://erlang.org/doc/installation_guide/INSTALL.html 48 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 49 | # gnupg: Required to verify OpenSSL artefacts 50 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 51 | RUN set -eux; \ 52 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 53 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 54 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 55 | \ 56 | # Required by the crypto & ssl Erlang/OTP applications 57 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 58 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 59 | export GNUPGHOME="$(mktemp -d)"; \ 60 | for key in $OPENSSL_PGP_KEY_IDS; do \ 61 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 62 | done; \ 63 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 64 | gpgconf --kill all; \ 65 | rm -rf "$GNUPGHOME"; \ 66 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum --check --strict -; \ 67 | mkdir -p "$OPENSSL_PATH"; \ 68 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 69 | \ 70 | # Configure OpenSSL for compilation 71 | cd "$OPENSSL_PATH"; \ 72 | # without specifying "--libdir", Erlang will fail during "crypto:supports()" looking for a "pthread_atfork" function that doesn't exist (but only on arm32v7/armhf??) 73 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 74 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 75 | # https://deb.debian.org/debian/dists/unstable/main/ 76 | case "$dpkgArch" in \ 77 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 78 | amd64) opensslMachine='linux-x86_64' ;; \ 79 | arm64) opensslMachine='linux-aarch64' ;; \ 80 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 81 | # https://wiki.debian.org/ArchitectureSpecificsMemo#Architecture_baselines 82 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 83 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 84 | i386) opensslMachine='linux-x86' ;; \ 85 | ppc64el) opensslMachine='linux-ppc64le' ;; \ 86 | riscv64) opensslMachine='linux64-riscv64' ;; \ 87 | s390x) opensslMachine='linux64-s390x' ;; \ 88 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 89 | esac; \ 90 | MACHINE="$opensslMachine" \ 91 | RELEASE="4.x.y-z" \ 92 | SYSTEM='Linux' \ 93 | BUILD='???' \ 94 | ./Configure \ 95 | "$opensslMachine" \ 96 | enable-fips \ 97 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 98 | --openssldir="$OPENSSL_CONFIG_DIR" \ 99 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 100 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 101 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 102 | ${opensslExtraConfig:-} \ 103 | ; \ 104 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 105 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 106 | make install_sw install_ssldirs install_fips; \ 107 | ldconfig; \ 108 | # use Debian's CA certificates 109 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 110 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 111 | 112 | # smoke test 113 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 114 | 115 | FROM openssl-builder as erlang-builder 116 | 117 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 118 | 119 | RUN set -eux; \ 120 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 121 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 122 | \ 123 | # Download, verify & extract OTP_SOURCE 124 | mkdir -p "$OTP_PATH"; \ 125 | wget --progress dot:giga --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 126 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ 127 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 128 | \ 129 | # Configure Erlang/OTP for compilation, disable unused features & applications 130 | # https://erlang.org/doc/applications.html 131 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 132 | cd "$OTP_PATH"; \ 133 | export ERL_TOP="$OTP_PATH"; \ 134 | CFLAGS="$(dpkg-buildflags --get CFLAGS)"; export CFLAGS; \ 135 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$OPENSSL_INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 136 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 137 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 138 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 139 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 140 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 141 | jitFlag=; \ 142 | case "$dpkgArch" in \ 143 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 144 | esac; \ 145 | ./configure \ 146 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 147 | --host="$hostArch" \ 148 | --build="$buildArch" \ 149 | --disable-hipe \ 150 | --disable-sctp \ 151 | --disable-silent-rules \ 152 | --enable-builtin-zlib \ 153 | --enable-clock-gettime \ 154 | --enable-hybrid-heap \ 155 | --enable-kernel-poll \ 156 | --enable-smp-support \ 157 | --enable-threads \ 158 | --with-microstate-accounting=extra \ 159 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 160 | --without-common_test \ 161 | --without-debugger \ 162 | --without-dialyzer \ 163 | --without-diameter \ 164 | --without-edoc \ 165 | --without-erl_docgen \ 166 | --without-et \ 167 | --without-eunit \ 168 | --without-ftp \ 169 | --without-hipe \ 170 | --without-jinterface \ 171 | --without-megaco \ 172 | --without-observer \ 173 | --without-odbc \ 174 | --without-reltool \ 175 | --without-snmp \ 176 | --without-ssh \ 177 | --without-tftp \ 178 | --without-wx \ 179 | $jitFlag \ 180 | ; \ 181 | \ 182 | # Compile & install Erlang/OTP 183 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 184 | make install; \ 185 | \ 186 | # Remove unnecessary files 187 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 188 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 189 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 190 | 191 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 192 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 193 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 194 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 195 | 196 | FROM ubuntu:24.04 197 | 198 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 199 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 200 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 201 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 202 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 203 | 204 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 205 | 206 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 207 | 208 | RUN set -eux; \ 209 | # Configure OpenSSL to use system certs 210 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 211 | \ 212 | # Check that OpenSSL still works after copying from previous builder 213 | ldconfig; \ 214 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 215 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 216 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 217 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 218 | openssl version; \ 219 | openssl version -d; \ 220 | \ 221 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 222 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 223 | \ 224 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 225 | groupadd --gid 999 --system rabbitmq; \ 226 | useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq; \ 227 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 228 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 229 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 230 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie 231 | 232 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 233 | ENV RABBITMQ_VERSION 4.1.0 234 | # https://www.rabbitmq.com/signatures.html#importing-gpg 235 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 236 | ENV RABBITMQ_HOME /opt/rabbitmq 237 | 238 | # Add RabbitMQ to PATH 239 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 240 | 241 | # Install RabbitMQ 242 | RUN set -eux; \ 243 | export DEBIAN_FRONTEND=noninteractive; \ 244 | apt-get update; \ 245 | apt-get install --yes --no-install-recommends \ 246 | ca-certificates \ 247 | # grab gosu for easy step-down from root 248 | gosu \ 249 | # Bring in tzdata so users could set the timezones through the environment 250 | tzdata \ 251 | ; \ 252 | # verify that the "gosu" binary works 253 | gosu nobody true; \ 254 | \ 255 | savedAptMark="$(apt-mark showmanual)"; \ 256 | apt-get install --yes --no-install-recommends \ 257 | gnupg \ 258 | wget \ 259 | xz-utils \ 260 | ; \ 261 | rm -rf /var/lib/apt/lists/*; \ 262 | \ 263 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 264 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 265 | \ 266 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 267 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 268 | \ 269 | export GNUPGHOME="$(mktemp -d)"; \ 270 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 271 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 272 | gpgconf --kill all; \ 273 | rm -rf "$GNUPGHOME"; \ 274 | \ 275 | mkdir -p "$RABBITMQ_HOME"; \ 276 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 277 | rm -rf "$RABBITMQ_PATH"*; \ 278 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 279 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 280 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 281 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 282 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 283 | \ 284 | apt-mark auto '.*' > /dev/null; \ 285 | apt-mark manual $savedAptMark; \ 286 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 287 | \ 288 | # verify assumption of no stale cookies 289 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 290 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 291 | # If they all succeed, it's safe to assume that things have been set up correctly 292 | gosu rabbitmq rabbitmqctl help; \ 293 | gosu rabbitmq rabbitmqctl list_ciphers; \ 294 | gosu rabbitmq rabbitmq-plugins list; \ 295 | # no stale cookies 296 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 297 | 298 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 299 | RUN gosu rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 300 | 301 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 302 | RUN ln -sf /opt/rabbitmq/plugins /plugins 303 | 304 | # set home so that any `--user` knows where to put the erlang cookie 305 | ENV HOME $RABBITMQ_DATA_DIR 306 | # Hint that the data (a.k.a. home dir) dir should be separate volume 307 | VOLUME $RABBITMQ_DATA_DIR 308 | 309 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 310 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 311 | # https://docs.docker.com/samples/library/ubuntu/#locales 312 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 313 | 314 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 315 | COPY docker-entrypoint.sh /usr/local/bin/ 316 | ENTRYPOINT ["docker-entrypoint.sh"] 317 | 318 | EXPOSE 4369 5671 5672 15691 15692 25672 319 | CMD ["rabbitmq-server"] 320 | -------------------------------------------------------------------------------- /4.1/ubuntu/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec gosu rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /4.1/ubuntu/management/Dockerfile: -------------------------------------------------------------------------------- 1 | # 2 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 3 | # 4 | # PLEASE DO NOT EDIT IT DIRECTLY. 5 | # 6 | 7 | FROM rabbitmq:4.1 8 | 9 | RUN set -eux; \ 10 | rabbitmq-plugins enable --offline rabbitmq_management; \ 11 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 12 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 13 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 14 | # see https://github.com/docker-library/rabbitmq/issues/207 15 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 16 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 17 | chmod +x /usr/local/bin/rabbitmqadmin; \ 18 | apt-get update; \ 19 | apt-get install -y --no-install-recommends python3; \ 20 | rm -rf /var/lib/apt/lists/*; \ 21 | rabbitmqadmin --version 22 | 23 | EXPOSE 15671 15672 24 | -------------------------------------------------------------------------------- /Dockerfile-alpine.template: -------------------------------------------------------------------------------- 1 | # Alpine Linux is not officially supported by the RabbitMQ team -- use at your own risk! 2 | FROM alpine:{{ .alpine.version }} as build-base 3 | 4 | RUN apk add --no-cache \ 5 | build-base \ 6 | dpkg-dev \ 7 | dpkg \ 8 | gnupg \ 9 | libc-dev \ 10 | linux-headers \ 11 | ncurses-dev 12 | 13 | FROM build-base as openssl-builder 14 | 15 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 16 | 17 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 18 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 19 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 20 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:{{ env.version }} --build-arg PGP_KEYSERVER=pgpkeys.eu {{ env.version }}/ubuntu 21 | # For context, see https://github.com/docker-library/official-images/issues/4252 22 | 23 | ENV OPENSSL_VERSION {{ .openssl.version }} 24 | ENV OPENSSL_SOURCE_SHA256="{{ .openssl.sha256 }}" 25 | # https://www.openssl.org/source/ 26 | ENV OPENSSL_PGP_KEY_IDS="{{ 27 | [ 28 | # "OpenSSL " 29 | # https://openssl-library.org/source/index.html 30 | # "The current releases are signed by the OpenSSL key with fingerprint:" 31 | # https://keys.openpgp.org/search?q=openssl%40openssl.org 32 | "BA54 73A2 B058 7B07 FB27 CF2D 2160 94DF D0CB 81EF", 33 | 34 | # hack for trailing comma above 35 | empty 36 | ] 37 | # TODO auto-generate / scrape this list from the canonical upstream source instead (check the signature file and add an entry in the .openssl object with just the one signature that we expect to have signed this release, after cross-referencing the official OMC list?) 38 | | map("0x" + gsub(" "; "")) | join(" ") 39 | }}" 40 | 41 | ENV OTP_VERSION {{ .otp.version }} 42 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 43 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 44 | ENV OTP_SOURCE_SHA256="{{ .otp.sha256 }}" 45 | 46 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 47 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 48 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 49 | 50 | # Install dependencies required to build Erlang/OTP from source 51 | # https://erlang.org/doc/installation_guide/INSTALL.html 52 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 53 | # gnupg: Required to verify OpenSSL artefacts 54 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 55 | RUN set -eux; \ 56 | # /usr/local/src doesn't exist in Alpine by default 57 | mkdir -p /usr/local/src; \ 58 | \ 59 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 60 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 61 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 62 | \ 63 | # Required by the crypto & ssl Erlang/OTP applications 64 | wget --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 65 | wget --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 66 | export GNUPGHOME="$(mktemp -d)"; \ 67 | for key in $OPENSSL_PGP_KEY_IDS; do \ 68 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 69 | done; \ 70 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 71 | gpgconf --kill all; \ 72 | rm -rf "$GNUPGHOME"; \ 73 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum -c -; \ 74 | mkdir -p "$OPENSSL_PATH"; \ 75 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 76 | \ 77 | # Configure OpenSSL for compilation 78 | cd "$OPENSSL_PATH"; \ 79 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 80 | apkArch="$(apk --print-arch)"; \ 81 | # https://dl-cdn.alpinelinux.org/alpine/edge/main/ 82 | case "$apkArch" in \ 83 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 84 | aarch64) opensslMachine='linux-aarch64' ;; \ 85 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 86 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 87 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv6+fp' ;; \ 88 | armv7) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 89 | ppc64le) opensslMachine='linux-ppc64le' ;; \ 90 | riscv64) opensslMachine='linux64-riscv64' ;; \ 91 | s390x) opensslMachine='linux64-s390x' ;; \ 92 | x86) opensslMachine='linux-x86' ;; \ 93 | x86_64) opensslMachine='linux-x86_64' ;; \ 94 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 95 | esac; \ 96 | MACHINE="$opensslMachine" \ 97 | RELEASE="4.x.y-z" \ 98 | SYSTEM='Linux' \ 99 | BUILD='???' \ 100 | ./Configure \ 101 | "$opensslMachine" \ 102 | enable-fips \ 103 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 104 | --openssldir="$OPENSSL_CONFIG_DIR" \ 105 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 106 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 107 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 108 | ${opensslExtraConfig:-} \ 109 | ; \ 110 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 111 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 112 | make install_sw install_ssldirs install_fips; \ 113 | # use Alpine's CA certificates 114 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 115 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 116 | 117 | # smoke test 118 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 119 | 120 | FROM openssl-builder as erlang-builder 121 | 122 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 123 | 124 | RUN set -eux; \ 125 | # /usr/local/src doesn't exist in Alpine by default 126 | mkdir -p /usr/local/src; \ 127 | \ 128 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 129 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 130 | \ 131 | # Download, verify & extract OTP_SOURCE 132 | mkdir -p "$OTP_PATH"; \ 133 | wget --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 134 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum -c -; \ 135 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 136 | \ 137 | # Configure Erlang/OTP for compilation, disable unused features & applications 138 | # https://erlang.org/doc/applications.html 139 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 140 | cd "$OTP_PATH"; \ 141 | export ERL_TOP="$OTP_PATH"; \ 142 | export CFLAGS='-g -O2'; \ 143 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 144 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 145 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 146 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 147 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 148 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 149 | jitFlag=; \ 150 | case "$dpkgArch" in \ 151 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 152 | esac; \ 153 | ./configure \ 154 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 155 | --host="$hostArch" \ 156 | --build="$buildArch" \ 157 | --disable-hipe \ 158 | --disable-sctp \ 159 | --disable-silent-rules \ 160 | --enable-builtin-zlib \ 161 | --enable-clock-gettime \ 162 | --enable-hybrid-heap \ 163 | --enable-kernel-poll \ 164 | --enable-smp-support \ 165 | --enable-threads \ 166 | --with-microstate-accounting=extra \ 167 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 168 | --without-common_test \ 169 | --without-debugger \ 170 | --without-dialyzer \ 171 | --without-diameter \ 172 | --without-edoc \ 173 | --without-erl_docgen \ 174 | --without-et \ 175 | --without-eunit \ 176 | --without-ftp \ 177 | --without-hipe \ 178 | --without-jinterface \ 179 | --without-megaco \ 180 | --without-observer \ 181 | --without-odbc \ 182 | --without-reltool \ 183 | --without-snmp \ 184 | --without-ssh \ 185 | --without-tftp \ 186 | --without-wx \ 187 | $jitFlag \ 188 | ; \ 189 | # Compile & install Erlang/OTP 190 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 191 | make install; \ 192 | \ 193 | # Remove unnecessary files 194 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 195 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 196 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 197 | 198 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 199 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 200 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 201 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 202 | 203 | FROM alpine:{{ .alpine.version }} 204 | 205 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 206 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 207 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 208 | 209 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 210 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 211 | 212 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 213 | 214 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 215 | 216 | RUN set -eux; \ 217 | # Configure OpenSSL to use system certs 218 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 219 | \ 220 | # Ensure run-time dependencies are installed 221 | runDeps="$( \ 222 | scanelf --needed --nobanner --format '%n#p' --recursive $ERLANG_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX \ 223 | | tr ',' '\n' \ 224 | | sort -u \ 225 | | grep -v '^$\|lib\(crypto\|ssl\)' \ 226 | | awk 'system("test -e /usr/local/lib/" $1) == 0 { next } { print "so:" $1 }' \ 227 | )"; \ 228 | apk add --no-cache --virtual .otp-run-deps $runDeps; \ 229 | \ 230 | # Check that OpenSSL still works after copying from previous builder 231 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 232 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 233 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 234 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 235 | openssl version; \ 236 | openssl version -d; \ 237 | \ 238 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 239 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 240 | \ 241 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 242 | addgroup -g 101 -S rabbitmq; \ 243 | adduser -u 100 -S -h "$RABBITMQ_DATA_DIR" -G rabbitmq rabbitmq; \ 244 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 245 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 246 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 247 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie; \ 248 | \ 249 | apk add --no-cache \ 250 | # grab su-exec for easy step-down from root 251 | 'su-exec>=0.2' \ 252 | # bash for docker-entrypoint.sh 253 | bash \ 254 | # "ps" for "rabbitmqctl wait" (https://github.com/docker-library/rabbitmq/issues/162) 255 | procps \ 256 | # Bring in tzdata so users could set the timezones through the environment 257 | tzdata 258 | 259 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 260 | ENV RABBITMQ_VERSION {{ .version }} 261 | # https://www.rabbitmq.com/signatures.html#importing-gpg 262 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 263 | ENV RABBITMQ_HOME /opt/rabbitmq 264 | 265 | # Add RabbitMQ to PATH 266 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 267 | 268 | # Install RabbitMQ 269 | RUN set -eux; \ 270 | # /usr/local/src doesn't exist in Alpine by default 271 | mkdir -p /usr/local/src; \ 272 | \ 273 | apk add --no-cache --virtual .build-deps \ 274 | gnupg \ 275 | xz \ 276 | ; \ 277 | \ 278 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 279 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 280 | \ 281 | wget --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 282 | wget --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 283 | \ 284 | export GNUPGHOME="$(mktemp -d)"; \ 285 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 286 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 287 | gpgconf --kill all; \ 288 | rm -rf "$GNUPGHOME"; \ 289 | \ 290 | mkdir -p "$RABBITMQ_HOME"; \ 291 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 292 | rm -rf "$RABBITMQ_PATH"*; \ 293 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 294 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 295 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 296 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 297 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 298 | \ 299 | apk del --no-network .build-deps; \ 300 | \ 301 | # verify assumption of no stale cookies 302 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 303 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 304 | # If they all succeed, it's safe to assume that things have been set up correctly 305 | su-exec rabbitmq rabbitmqctl help; \ 306 | su-exec rabbitmq rabbitmqctl list_ciphers; \ 307 | su-exec rabbitmq rabbitmq-plugins list; \ 308 | # no stale cookies 309 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 310 | 311 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 312 | RUN su-exec rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 313 | 314 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 315 | RUN ln -sf /opt/rabbitmq/plugins /plugins 316 | 317 | # set home so that any `--user` knows where to put the erlang cookie 318 | ENV HOME $RABBITMQ_DATA_DIR 319 | # Hint that the data (a.k.a. home dir) dir should be separate volume 320 | VOLUME $RABBITMQ_DATA_DIR 321 | 322 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 323 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 324 | # https://docs.docker.com/samples/library/ubuntu/#locales 325 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 326 | 327 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 328 | COPY docker-entrypoint.sh /usr/local/bin/ 329 | ENTRYPOINT ["docker-entrypoint.sh"] 330 | 331 | EXPOSE 4369 5671 5672 15691 15692 25672 332 | CMD ["rabbitmq-server"] 333 | -------------------------------------------------------------------------------- /Dockerfile-management.template: -------------------------------------------------------------------------------- 1 | FROM {{ 2 | "rabbitmq:" + env.version 3 | + if env.variant == "alpine" then "-alpine" else "" end 4 | }} 5 | 6 | RUN set -eux; \ 7 | rabbitmq-plugins enable --offline rabbitmq_management; \ 8 | # make sure the metrics collector is re-enabled (disabled in the base image for Prometheus-style metrics by default) 9 | rm -f /etc/rabbitmq/conf.d/20-management_agent.disable_metrics_collector.conf; \ 10 | # grab "rabbitmqadmin" from inside the "rabbitmq_management-X.Y.Z" plugin folder 11 | # see https://github.com/docker-library/rabbitmq/issues/207 12 | cp /plugins/rabbitmq_management-*/priv/www/cli/rabbitmqadmin /usr/local/bin/rabbitmqadmin; \ 13 | [ -s /usr/local/bin/rabbitmqadmin ]; \ 14 | chmod +x /usr/local/bin/rabbitmqadmin; \ 15 | {{ if env.variant == "alpine" then ( -}} 16 | apk add --no-cache python3; \ 17 | {{ ) else ( -}} 18 | apt-get update; \ 19 | apt-get install -y --no-install-recommends python3; \ 20 | rm -rf /var/lib/apt/lists/*; \ 21 | {{ ) end -}} 22 | rabbitmqadmin --version 23 | 24 | EXPOSE 15671 15672 25 | -------------------------------------------------------------------------------- /Dockerfile-ubuntu.template: -------------------------------------------------------------------------------- 1 | # The official Canonical Ubuntu Focal image is ideal from a security perspective, 2 | # especially for the enterprises that we, the RabbitMQ team, have to deal with 3 | FROM ubuntu:{{ .ubuntu.version }} as build-base 4 | 5 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 6 | 7 | RUN set -eux; \ 8 | apt-get update; \ 9 | apt-get install -y --no-install-recommends \ 10 | build-essential \ 11 | ca-certificates \ 12 | gnupg \ 13 | libncurses5-dev \ 14 | wget 15 | 16 | FROM build-base as openssl-builder 17 | 18 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 19 | 20 | # Default to a PGP keyserver that pgp-happy-eyeballs recognizes, but allow for substitutions locally 21 | ARG PGP_KEYSERVER=keyserver.ubuntu.com 22 | # If you are building this image locally and are getting `gpg: keyserver receive failed: No data` errors, 23 | # run the build with a different PGP_KEYSERVER, e.g. docker build --tag rabbitmq:{{ env.version }} --build-arg PGP_KEYSERVER=pgpkeys.eu {{ env.version }}/ubuntu 24 | # For context, see https://github.com/docker-library/official-images/issues/4252 25 | 26 | ENV OPENSSL_VERSION {{ .openssl.version }} 27 | ENV OPENSSL_SOURCE_SHA256="{{ .openssl.sha256 }}" 28 | # https://www.openssl.org/source/ 29 | ENV OPENSSL_PGP_KEY_IDS="{{ 30 | [ 31 | # "OpenSSL " 32 | # https://openssl-library.org/source/index.html 33 | # "The current releases are signed by the OpenSSL key with fingerprint:" 34 | # https://keys.openpgp.org/search?q=openssl%40openssl.org 35 | "BA54 73A2 B058 7B07 FB27 CF2D 2160 94DF D0CB 81EF", 36 | 37 | # hack for trailing comma above 38 | empty 39 | ] 40 | # TODO auto-generate / scrape this list from the canonical upstream source instead (check the signature file and add an entry in the .openssl object with just the one signature that we expect to have signed this release, after cross-referencing the official OMC list?) 41 | | map("0x" + gsub(" "; "")) | join(" ") 42 | }}" 43 | 44 | ENV OTP_VERSION {{ .otp.version }} 45 | # TODO add PGP checking when the feature will be added to Erlang/OTP's build system 46 | # https://erlang.org/pipermail/erlang-questions/2019-January/097067.html 47 | ENV OTP_SOURCE_SHA256="{{ .otp.sha256 }}" 48 | 49 | # install openssl & erlang to a path that isn't auto-checked for libs to prevent accidental use by system packages 50 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 51 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 52 | 53 | # Install dependencies required to build Erlang/OTP from source 54 | # https://erlang.org/doc/installation_guide/INSTALL.html 55 | # dpkg-dev: Required to set up host & build type when compiling Erlang/OTP 56 | # gnupg: Required to verify OpenSSL artefacts 57 | # libncurses5-dev: Required for Erlang/OTP new shell & observer_cli - https://github.com/zhongwencool/observer_cli 58 | RUN set -eux; \ 59 | OPENSSL_SOURCE_URL="https://github.com/openssl/openssl/releases/download/openssl-$OPENSSL_VERSION/openssl-$OPENSSL_VERSION.tar.gz"; \ 60 | OPENSSL_PATH="/usr/local/src/openssl-$OPENSSL_VERSION"; \ 61 | OPENSSL_CONFIG_DIR="$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 62 | \ 63 | # Required by the crypto & ssl Erlang/OTP applications 64 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_SOURCE_URL.asc"; \ 65 | wget --progress dot:giga --output-document "$OPENSSL_PATH.tar.gz" "$OPENSSL_SOURCE_URL"; \ 66 | export GNUPGHOME="$(mktemp -d)"; \ 67 | for key in $OPENSSL_PGP_KEY_IDS; do \ 68 | gpg --batch --keyserver "$PGP_KEYSERVER" --recv-keys "$key"; \ 69 | done; \ 70 | gpg --batch --verify "$OPENSSL_PATH.tar.gz.asc" "$OPENSSL_PATH.tar.gz"; \ 71 | gpgconf --kill all; \ 72 | rm -rf "$GNUPGHOME"; \ 73 | echo "$OPENSSL_SOURCE_SHA256 *$OPENSSL_PATH.tar.gz" | sha256sum --check --strict -; \ 74 | mkdir -p "$OPENSSL_PATH"; \ 75 | tar --extract --file "$OPENSSL_PATH.tar.gz" --directory "$OPENSSL_PATH" --strip-components 1; \ 76 | \ 77 | # Configure OpenSSL for compilation 78 | cd "$OPENSSL_PATH"; \ 79 | # without specifying "--libdir", Erlang will fail during "crypto:supports()" looking for a "pthread_atfork" function that doesn't exist (but only on arm32v7/armhf??) 80 | # OpenSSL's "config" script uses a lot of "uname"-based target detection... 81 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 82 | # https://deb.debian.org/debian/dists/unstable/main/ 83 | case "$dpkgArch" in \ 84 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L860 (look for "linux-" and "linux64-" keys) 85 | amd64) opensslMachine='linux-x86_64' ;; \ 86 | arm64) opensslMachine='linux-aarch64' ;; \ 87 | # https://github.com/openssl/openssl/blob/openssl-3.1.1/Configurations/10-main.conf#L736-L766 88 | # https://wiki.debian.org/ArchitectureSpecificsMemo#Architecture_baselines 89 | # https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html 90 | armhf) opensslMachine='linux-armv4'; opensslExtraConfig='-march=armv7-a+fp' ;; \ 91 | i386) opensslMachine='linux-x86' ;; \ 92 | ppc64el) opensslMachine='linux-ppc64le' ;; \ 93 | riscv64) opensslMachine='linux64-riscv64' ;; \ 94 | s390x) opensslMachine='linux64-s390x' ;; \ 95 | *) echo >&2 "error: unsupported arch: '$apkArch'"; exit 1 ;; \ 96 | esac; \ 97 | MACHINE="$opensslMachine" \ 98 | RELEASE="4.x.y-z" \ 99 | SYSTEM='Linux' \ 100 | BUILD='???' \ 101 | ./Configure \ 102 | "$opensslMachine" \ 103 | enable-fips \ 104 | --prefix="$OPENSSL_INSTALL_PATH_PREFIX" \ 105 | --openssldir="$OPENSSL_CONFIG_DIR" \ 106 | --libdir="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 107 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 108 | -Wl,-rpath="$OPENSSL_INSTALL_PATH_PREFIX/lib" \ 109 | ${opensslExtraConfig:-} \ 110 | ; \ 111 | # Compile, install OpenSSL, verify that the command-line works & development headers are present 112 | make -j "$(getconf _NPROCESSORS_ONLN)"; \ 113 | make install_sw install_ssldirs install_fips; \ 114 | ldconfig; \ 115 | # use Debian's CA certificates 116 | rmdir "$OPENSSL_CONFIG_DIR/certs" "$OPENSSL_CONFIG_DIR/private"; \ 117 | ln -sf /etc/ssl/certs /etc/ssl/private "$OPENSSL_CONFIG_DIR" 118 | 119 | # smoke test 120 | RUN $OPENSSL_INSTALL_PATH_PREFIX/bin/openssl version 121 | 122 | FROM openssl-builder as erlang-builder 123 | 124 | ARG BUILDKIT_SBOM_SCAN_STAGE=true 125 | 126 | RUN set -eux; \ 127 | OTP_SOURCE_URL="https://github.com/erlang/otp/releases/download/OTP-$OTP_VERSION/otp_src_$OTP_VERSION.tar.gz"; \ 128 | OTP_PATH="/usr/local/src/otp-$OTP_VERSION"; \ 129 | \ 130 | # Download, verify & extract OTP_SOURCE 131 | mkdir -p "$OTP_PATH"; \ 132 | wget --progress dot:giga --output-document "$OTP_PATH.tar.gz" "$OTP_SOURCE_URL"; \ 133 | echo "$OTP_SOURCE_SHA256 *$OTP_PATH.tar.gz" | sha256sum --check --strict -; \ 134 | tar --extract --file "$OTP_PATH.tar.gz" --directory "$OTP_PATH" --strip-components 1; \ 135 | \ 136 | {{ if .otp.version | startswith("25.") or startswith("26.") then ( -}} 137 | # backport https://github.com/erlang/otp/pull/7952 (applied upstream in OTP 27+) to fix time64 compilation issues on 32bit architectures 138 | # see also https://bugs.debian.org/1067701, https://salsa.debian.org/erlang-team/packages/erlang/-/blob/89c4e190c6d1d7ee0133d9a8d6bf651ff1861e46/debian/patches/time64.patch 139 | wget --output-document otp-time64.patch 'https://github.com/erlang/otp/pull/7952.patch?full_index=1'; \ 140 | echo 'd1a0c0433a9a08c83171bedd438dd59bb336b40ec75f59edfc3a647b8b0c612d *otp-time64.patch' | sha256sum --check --strict -; \ 141 | patch --input="$PWD/otp-time64.patch" --directory="$OTP_PATH" --strip=1; \ 142 | rm otp-time64.patch; \ 143 | \ 144 | {{ ) else "" end -}} 145 | # Configure Erlang/OTP for compilation, disable unused features & applications 146 | # https://erlang.org/doc/applications.html 147 | # ERL_TOP is required for Erlang/OTP makefiles to find the absolute path for the installation 148 | cd "$OTP_PATH"; \ 149 | export ERL_TOP="$OTP_PATH"; \ 150 | CFLAGS="$(dpkg-buildflags --get CFLAGS)"; export CFLAGS; \ 151 | # add -rpath to avoid conflicts between our OpenSSL's "libssl.so" and the libssl package by making sure "$OPENSSL_INSTALL_PATH_PREFIX/lib" is searched first (but only for Erlang/OpenSSL to avoid issues with other tools using libssl; https://github.com/docker-library/rabbitmq/issues/364) 152 | export CFLAGS="$CFLAGS -Wl,-rpath=$OPENSSL_INSTALL_PATH_PREFIX/lib"; \ 153 | hostArch="$(dpkg-architecture --query DEB_HOST_GNU_TYPE)"; \ 154 | buildArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; \ 155 | dpkgArch="$(dpkg --print-architecture)"; dpkgArch="${dpkgArch##*-}"; \ 156 | # JIT is only supported on amd64 + arm64; https://github.com/erlang/otp/blob/OTP-25.3.2.2/erts/configure#L24306-L24347 157 | jitFlag=; \ 158 | case "$dpkgArch" in \ 159 | amd64 | arm64) jitFlag='--enable-jit' ;; \ 160 | esac; \ 161 | ./configure \ 162 | --prefix="$ERLANG_INSTALL_PATH_PREFIX" \ 163 | --host="$hostArch" \ 164 | --build="$buildArch" \ 165 | --disable-hipe \ 166 | --disable-sctp \ 167 | --disable-silent-rules \ 168 | --enable-builtin-zlib \ 169 | --enable-clock-gettime \ 170 | --enable-hybrid-heap \ 171 | --enable-kernel-poll \ 172 | --enable-smp-support \ 173 | --enable-threads \ 174 | --with-microstate-accounting=extra \ 175 | --with-ssl="$OPENSSL_INSTALL_PATH_PREFIX" \ 176 | --without-common_test \ 177 | --without-debugger \ 178 | --without-dialyzer \ 179 | --without-diameter \ 180 | --without-edoc \ 181 | --without-erl_docgen \ 182 | --without-et \ 183 | --without-eunit \ 184 | --without-ftp \ 185 | --without-hipe \ 186 | --without-jinterface \ 187 | --without-megaco \ 188 | --without-observer \ 189 | --without-odbc \ 190 | --without-reltool \ 191 | --without-snmp \ 192 | --without-ssh \ 193 | --without-tftp \ 194 | --without-wx \ 195 | $jitFlag \ 196 | ; \ 197 | \ 198 | # Compile & install Erlang/OTP 199 | make -j "$(getconf _NPROCESSORS_ONLN)" GEN_OPT_FLGS="-O2 -fno-strict-aliasing"; \ 200 | make install; \ 201 | \ 202 | # Remove unnecessary files 203 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name examples -exec rm -rf '{}' +; \ 204 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name src -exec rm -rf '{}' +; \ 205 | find "$ERLANG_INSTALL_PATH_PREFIX/lib/erlang" -type d -name include -exec rm -rf '{}' + 206 | 207 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 208 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$PATH 209 | RUN find $ERLANG_INSTALL_PATH_PREFIX -type f -name 'crypto.so' -exec ldd {} \; | awk '/libcrypto\.so/ { if (!index($3,ENVIRON["OPENSSL_INSTALL_PATH_PREFIX"])) exit 1 }' 210 | RUN erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().' 211 | 212 | FROM ubuntu:{{ .ubuntu.version }} 213 | 214 | # OPENSSL/ERLANG_INSTALL_PATH_PREFIX are defined in a different stage, so define them again 215 | ENV ERLANG_INSTALL_PATH_PREFIX /opt/erlang 216 | ENV OPENSSL_INSTALL_PATH_PREFIX /opt/openssl 217 | COPY --from=erlang-builder $ERLANG_INSTALL_PATH_PREFIX $ERLANG_INSTALL_PATH_PREFIX 218 | COPY --from=openssl-builder $OPENSSL_INSTALL_PATH_PREFIX $OPENSSL_INSTALL_PATH_PREFIX 219 | 220 | ENV PATH $ERLANG_INSTALL_PATH_PREFIX/bin:$OPENSSL_INSTALL_PATH_PREFIX/bin:$PATH 221 | 222 | ENV RABBITMQ_DATA_DIR /var/lib/rabbitmq 223 | 224 | RUN set -eux; \ 225 | # Configure OpenSSL to use system certs 226 | ln -vsf /etc/ssl/certs /etc/ssl/private "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl"; \ 227 | \ 228 | # Check that OpenSSL still works after copying from previous builder 229 | ldconfig; \ 230 | sed -i.ORIG -e "/\.include.*fips/ s!.*!.include $OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf!" \ 231 | -e '/# fips =/s/.*/fips = fips_sect/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/openssl.cnf"; \ 232 | sed -i.ORIG -e '/^activate/s/^/#/' "$OPENSSL_INSTALL_PATH_PREFIX/etc/ssl/fipsmodule.cnf"; \ 233 | [ "$(command -v openssl)" = "$OPENSSL_INSTALL_PATH_PREFIX/bin/openssl" ]; \ 234 | openssl version; \ 235 | openssl version -d; \ 236 | \ 237 | # Check that Erlang/OTP crypto & ssl were compiled against OpenSSL correctly 238 | erl -noshell -eval 'ok = crypto:start(), ok = io:format("~p~n~n~p~n~n", [crypto:supports(), ssl:versions()]), init:stop().'; \ 239 | \ 240 | # Create rabbitmq system user & group, fix permissions & allow root user to connect to the RabbitMQ Erlang VM 241 | groupadd --gid 999 --system rabbitmq; \ 242 | useradd --uid 999 --system --home-dir "$RABBITMQ_DATA_DIR" --gid rabbitmq rabbitmq; \ 243 | mkdir -p "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 244 | chown -fR rabbitmq:rabbitmq "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 245 | chmod 1777 "$RABBITMQ_DATA_DIR" /etc/rabbitmq /etc/rabbitmq/conf.d /tmp/rabbitmq-ssl /var/log/rabbitmq; \ 246 | ln -sf "$RABBITMQ_DATA_DIR/.erlang.cookie" /root/.erlang.cookie 247 | 248 | # Use the latest stable RabbitMQ release (https://www.rabbitmq.com/download.html) 249 | ENV RABBITMQ_VERSION {{ .version }} 250 | # https://www.rabbitmq.com/signatures.html#importing-gpg 251 | ENV RABBITMQ_PGP_KEY_ID 0x0A9AF2115F4687BD29803A206B73A36E6026DFCA 252 | ENV RABBITMQ_HOME /opt/rabbitmq 253 | 254 | # Add RabbitMQ to PATH 255 | ENV PATH $RABBITMQ_HOME/sbin:$PATH 256 | 257 | # Install RabbitMQ 258 | RUN set -eux; \ 259 | export DEBIAN_FRONTEND=noninteractive; \ 260 | apt-get update; \ 261 | apt-get install --yes --no-install-recommends \ 262 | ca-certificates \ 263 | # grab gosu for easy step-down from root 264 | gosu \ 265 | # Bring in tzdata so users could set the timezones through the environment 266 | tzdata \ 267 | ; \ 268 | # verify that the "gosu" binary works 269 | gosu nobody true; \ 270 | \ 271 | savedAptMark="$(apt-mark showmanual)"; \ 272 | apt-get install --yes --no-install-recommends \ 273 | gnupg \ 274 | wget \ 275 | xz-utils \ 276 | ; \ 277 | rm -rf /var/lib/apt/lists/*; \ 278 | \ 279 | RABBITMQ_SOURCE_URL="https://github.com/rabbitmq/rabbitmq-server/releases/download/v$RABBITMQ_VERSION/rabbitmq-server-generic-unix-latest-toolchain-$RABBITMQ_VERSION.tar.xz"; \ 280 | RABBITMQ_PATH="/usr/local/src/rabbitmq-$RABBITMQ_VERSION"; \ 281 | \ 282 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_SOURCE_URL.asc"; \ 283 | wget --progress dot:giga --output-document "$RABBITMQ_PATH.tar.xz" "$RABBITMQ_SOURCE_URL"; \ 284 | \ 285 | export GNUPGHOME="$(mktemp -d)"; \ 286 | gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$RABBITMQ_PGP_KEY_ID"; \ 287 | gpg --batch --verify "$RABBITMQ_PATH.tar.xz.asc" "$RABBITMQ_PATH.tar.xz"; \ 288 | gpgconf --kill all; \ 289 | rm -rf "$GNUPGHOME"; \ 290 | \ 291 | mkdir -p "$RABBITMQ_HOME"; \ 292 | tar --extract --file "$RABBITMQ_PATH.tar.xz" --directory "$RABBITMQ_HOME" --strip-components 1; \ 293 | rm -rf "$RABBITMQ_PATH"*; \ 294 | # Do not default SYS_PREFIX to RABBITMQ_HOME, leave it empty 295 | grep -qE '^SYS_PREFIX=\$\{RABBITMQ_HOME\}$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 296 | sed -i 's/^SYS_PREFIX=.*$/SYS_PREFIX=/' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 297 | grep -qE '^SYS_PREFIX=$' "$RABBITMQ_HOME/sbin/rabbitmq-defaults"; \ 298 | chown -R rabbitmq:rabbitmq "$RABBITMQ_HOME"; \ 299 | \ 300 | apt-mark auto '.*' > /dev/null; \ 301 | apt-mark manual $savedAptMark; \ 302 | apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \ 303 | \ 304 | # verify assumption of no stale cookies 305 | [ ! -e "$RABBITMQ_DATA_DIR/.erlang.cookie" ]; \ 306 | # Ensure RabbitMQ was installed correctly by running a few commands that do not depend on a running server, as the rabbitmq user 307 | # If they all succeed, it's safe to assume that things have been set up correctly 308 | gosu rabbitmq rabbitmqctl help; \ 309 | gosu rabbitmq rabbitmqctl list_ciphers; \ 310 | gosu rabbitmq rabbitmq-plugins list; \ 311 | # no stale cookies 312 | rm "$RABBITMQ_DATA_DIR/.erlang.cookie" 313 | 314 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 315 | RUN gosu rabbitmq rabbitmq-plugins enable --offline rabbitmq_prometheus 316 | 317 | # Added for backwards compatibility - users can simply COPY custom plugins to /plugins 318 | RUN ln -sf /opt/rabbitmq/plugins /plugins 319 | 320 | # set home so that any `--user` knows where to put the erlang cookie 321 | ENV HOME $RABBITMQ_DATA_DIR 322 | # Hint that the data (a.k.a. home dir) dir should be separate volume 323 | VOLUME $RABBITMQ_DATA_DIR 324 | 325 | # warning: the VM is running with native name encoding of latin1 which may cause Elixir to malfunction as it expects utf8. Please ensure your locale is set to UTF-8 (which can be verified by running "locale" in your shell) 326 | # Setting all environment variables that control language preferences, behaviour differs - https://www.gnu.org/software/gettext/manual/html_node/The-LANGUAGE-variable.html#The-LANGUAGE-variable 327 | # https://docs.docker.com/samples/library/ubuntu/#locales 328 | ENV LANG=C.UTF-8 LANGUAGE=C.UTF-8 LC_ALL=C.UTF-8 329 | 330 | COPY --chown=rabbitmq:rabbitmq 10-defaults.conf 20-management_agent.disable_metrics_collector.conf /etc/rabbitmq/conf.d/ 331 | COPY docker-entrypoint.sh /usr/local/bin/ 332 | ENTRYPOINT ["docker-entrypoint.sh"] 333 | 334 | EXPOSE 4369 5671 5672 15691 15692 25672 335 | CMD ["rabbitmq-server"] 336 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Docker, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # https://github.com/docker-library/rabbitmq 2 | 3 | ## Maintained by: [the Docker Community](https://github.com/docker-library/rabbitmq) 4 | 5 | This is the Git repo of the [Docker "Official Image"](https://github.com/docker-library/official-images#what-are-official-images) for [`rabbitmq`](https://hub.docker.com/_/rabbitmq/) (not to be confused with any official `rabbitmq` image provided by `rabbitmq` upstream). See [the Docker Hub page](https://hub.docker.com/_/rabbitmq/) for the full readme on how to use this Docker image and for information regarding contributing and issues. 6 | 7 | The [full image description on Docker Hub](https://hub.docker.com/_/rabbitmq/) is generated/maintained over in [the docker-library/docs repository](https://github.com/docker-library/docs), specifically in [the `rabbitmq` directory](https://github.com/docker-library/docs/tree/master/rabbitmq). 8 | 9 | ## See a change merged here that doesn't show up on Docker Hub yet? 10 | 11 | For more information about the full official images change lifecycle, see [the "An image's source changed in Git, now what?" FAQ entry](https://github.com/docker-library/faq#an-images-source-changed-in-git-now-what). 12 | 13 | For outstanding `rabbitmq` image PRs, check [PRs with the "library/rabbitmq" label on the official-images repository](https://github.com/docker-library/official-images/labels/library%2Frabbitmq). For the current "source of truth" for [`rabbitmq`](https://hub.docker.com/_/rabbitmq/), see [the `library/rabbitmq` file in the official-images repository](https://github.com/docker-library/official-images/blob/master/library/rabbitmq). 14 | 15 | 16 | -------------------------------------------------------------------------------- /apply-templates.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | [ -f versions.json ] # run "versions.sh" first 5 | 6 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 7 | 8 | jqt='.jq-template.awk' 9 | if [ -n "${BASHBREW_SCRIPTS:-}" ]; then 10 | jqt="$BASHBREW_SCRIPTS/jq-template.awk" 11 | elif [ "$BASH_SOURCE" -nt "$jqt" ]; then 12 | # https://github.com/docker-library/bashbrew/blob/master/scripts/jq-template.awk 13 | wget -qO "$jqt" 'https://github.com/docker-library/bashbrew/raw/9f6a35772ac863a0241f147c820354e4008edf38/scripts/jq-template.awk' 14 | fi 15 | 16 | if [ "$#" -eq 0 ]; then 17 | versions="$(jq -r 'keys | map(@sh) | join(" ")' versions.json)" 18 | eval "set -- $versions" 19 | fi 20 | 21 | generated_warning() { 22 | cat <<-EOH 23 | # 24 | # NOTE: THIS DOCKERFILE IS GENERATED VIA "apply-templates.sh" 25 | # 26 | # PLEASE DO NOT EDIT IT DIRECTLY. 27 | # 28 | 29 | EOH 30 | } 31 | 32 | for version; do 33 | export version 34 | 35 | if [ -d "$version" ]; then 36 | rm -rf "$version" 37 | fi 38 | 39 | if jq -e '.[env.version] | not' versions.json > /dev/null; then 40 | echo "skipping $version ..." 41 | continue 42 | fi 43 | 44 | for variant in alpine ubuntu; do 45 | export variant 46 | 47 | echo "processing $version/$variant ..." 48 | 49 | mkdir -p "$version/$variant" 50 | 51 | { 52 | generated_warning 53 | gawk -f "$jqt" "Dockerfile-$variant.template" 54 | } > "$version/$variant/Dockerfile" 55 | 56 | cp -f docker-entrypoint.sh conf.d/*.conf "$version/$variant/" 57 | 58 | if [ "$variant" = 'alpine' ]; then 59 | sed -i -e 's/gosu/su-exec/g' "$version/$variant/docker-entrypoint.sh" 60 | fi 61 | 62 | echo "processing $version/$variant/management ..." 63 | 64 | mkdir -p "$version/$variant/management" 65 | 66 | { 67 | generated_warning 68 | gawk -f "$jqt" Dockerfile-management.template 69 | } > "$version/$variant/management/Dockerfile" 70 | done 71 | done 72 | -------------------------------------------------------------------------------- /conf.d/10-defaults.conf: -------------------------------------------------------------------------------- 1 | ## DEFAULT SETTINGS ARE NOT MEANT TO BE TAKEN STRAIGHT INTO PRODUCTION 2 | ## see https://www.rabbitmq.com/configure.html for further information 3 | ## on configuring RabbitMQ 4 | 5 | ## allow access to the guest user from anywhere on the network 6 | ## https://www.rabbitmq.com/access-control.html#loopback-users 7 | ## https://www.rabbitmq.com/production-checklist.html#users 8 | loopback_users.guest = false 9 | 10 | ## Send all logs to stdout/TTY. Necessary to see logs when running via 11 | ## a container 12 | log.console = true 13 | -------------------------------------------------------------------------------- /conf.d/20-management_agent.disable_metrics_collector.conf: -------------------------------------------------------------------------------- 1 | # Enable Prometheus-style metrics by default (https://github.com/docker-library/rabbitmq/issues/419) 2 | management_agent.disable_metrics_collector = true 3 | -------------------------------------------------------------------------------- /docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # allow the container to be started with `--user` 5 | if [[ "$1" == rabbitmq* ]] && [ "$(id -u)" = '0' ]; then 6 | if [ "$1" = 'rabbitmq-server' ]; then 7 | find /var/lib/rabbitmq \! -user rabbitmq -exec chown rabbitmq '{}' + 8 | fi 9 | 10 | exec gosu rabbitmq "$BASH_SOURCE" "$@" 11 | fi 12 | 13 | deprecatedEnvVars=( 14 | RABBITMQ_DEFAULT_PASS_FILE 15 | RABBITMQ_DEFAULT_USER_FILE 16 | RABBITMQ_MANAGEMENT_SSL_CACERTFILE 17 | RABBITMQ_MANAGEMENT_SSL_CERTFILE 18 | RABBITMQ_MANAGEMENT_SSL_DEPTH 19 | RABBITMQ_MANAGEMENT_SSL_FAIL_IF_NO_PEER_CERT 20 | RABBITMQ_MANAGEMENT_SSL_KEYFILE 21 | RABBITMQ_MANAGEMENT_SSL_VERIFY 22 | RABBITMQ_SSL_CACERTFILE 23 | RABBITMQ_SSL_CERTFILE 24 | RABBITMQ_SSL_DEPTH 25 | RABBITMQ_SSL_FAIL_IF_NO_PEER_CERT 26 | RABBITMQ_SSL_KEYFILE 27 | RABBITMQ_SSL_VERIFY 28 | RABBITMQ_VM_MEMORY_HIGH_WATERMARK 29 | ) 30 | hasOldEnv= 31 | for old in "${deprecatedEnvVars[@]}"; do 32 | if [ -n "${!old:-}" ]; then 33 | echo >&2 "error: $old is set but deprecated" 34 | hasOldEnv=1 35 | fi 36 | done 37 | if [ -n "$hasOldEnv" ]; then 38 | echo >&2 'error: deprecated environment variables detected' 39 | echo >&2 40 | echo >&2 'Please use a configuration file instead; visit https://www.rabbitmq.com/configure.html to learn more' 41 | echo >&2 42 | exit 1 43 | fi 44 | 45 | # if long and short hostnames are not the same, use long hostnames 46 | if [ -z "${RABBITMQ_USE_LONGNAME:-}" ] && [ "$(hostname)" != "$(hostname -s)" ]; then 47 | : "${RABBITMQ_USE_LONGNAME:=true}" 48 | fi 49 | 50 | exec "$@" 51 | -------------------------------------------------------------------------------- /generate-stackbrew-library.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | declare -A aliases=( 5 | [4.1]='4 latest' 6 | [3.13]='3' 7 | ) 8 | defaultVariant='ubuntu' 9 | 10 | self="$(basename "$BASH_SOURCE")" 11 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 12 | 13 | if [ "$#" -eq 0 ]; then 14 | versions="$(jq -r ' 15 | to_entries 16 | # sort version numbers with highest first 17 | | sort_by(.key | split("[.-]"; "") | map(try tonumber // .)) 18 | | reverse 19 | | map(if .value then .key | @sh else empty end) 20 | | join(" ") 21 | ' versions.json)" 22 | eval "set -- $versions" 23 | fi 24 | 25 | # get the most recent commit which modified any of "$@" 26 | fileCommit() { 27 | git log -1 --format='format:%H' HEAD -- "$@" 28 | } 29 | 30 | # get the most recent commit which modified "$1/Dockerfile" or any file COPY'd from "$1/Dockerfile" 31 | dirCommit() { 32 | local dir="$1"; shift 33 | ( 34 | cd "$dir" 35 | fileCommit \ 36 | Dockerfile \ 37 | $(git show HEAD:./Dockerfile | awk ' 38 | /^COPY/ { 39 | for (i = 2; i < NF; i++) { 40 | if ($i ~ /^--from=/) { 41 | next 42 | } 43 | print $i 44 | } 45 | } 46 | ') 47 | ) 48 | } 49 | 50 | getArches() { 51 | local repo="$1"; shift 52 | local officialImagesBase="${BASHBREW_LIBRARY:-https://github.com/docker-library/official-images/raw/HEAD/library}/" 53 | 54 | local parentRepoToArchesStr 55 | parentRepoToArchesStr="$( 56 | find -name 'Dockerfile' -exec awk -v officialImagesBase="$officialImagesBase" ' 57 | /^FROM/ { 58 | if (index($2, ":") > 0 && index($2, "'"$repo"'") == 0) { 59 | printf "%s%s\n", officialImagesBase, $2 60 | } 61 | }' '{}' + | sort -u \ 62 | | xargs -r bashbrew cat --format '["{{ .RepoName }}:{{ .TagName }}"]="{{ join " " .TagEntry.Architectures }}"' 63 | )" 64 | eval "declare -g -A parentRepoToArches=( $parentRepoToArchesStr )" 65 | } 66 | getArches 'rabbitmq' 67 | 68 | cat <<-EOH 69 | # this file is generated via https://github.com/docker-library/rabbitmq/blob/$(fileCommit "$self")/$self 70 | 71 | Maintainers: Tianon Gravi (@tianon), 72 | Joseph Ferguson (@yosifkit) 73 | GitRepo: https://github.com/docker-library/rabbitmq.git 74 | Builder: buildkit 75 | EOH 76 | 77 | # prints "$2$1$3$1...$N" 78 | join() { 79 | local sep="$1"; shift 80 | local out; printf -v out "${sep//%/%%}%s" "$@" 81 | echo "${out#$sep}" 82 | } 83 | 84 | for version; do 85 | export version 86 | rcVersion="${version%-rc}" 87 | 88 | if ! fullVersion="$(jq -er '.[env.version] | if . then .version else empty end' versions.json)"; then 89 | # support running "generate-stackbrew-library.sh" on a singular "null" version ("3.10-rc" when the RC is older than the GA release, for example) 90 | continue 91 | fi 92 | 93 | # if this is a "-rc" release, let's make sure the release it contains isn't already GA (and thus something we should not publish anymore) 94 | export rcVersion 95 | if [ "$rcVersion" != "$version" ] && rcFullVersion="$(jq -r '.[env.rcVersion].version // ""' versions.json)" && [ -n "$rcFullVersion" ]; then 96 | latestVersion="$({ echo "$fullVersion"; echo "$rcFullVersion"; } | sort -V | tail -1)" 97 | if [[ "$fullVersion" == "$rcFullVersion"* ]] || [ "$latestVersion" = "$rcFullVersion" ]; then 98 | # "x.y.z-rc1" == x.y.z* 99 | continue 100 | fi 101 | fi 102 | 103 | versionAliases=() 104 | if [ "$version" = "$rcVersion" ]; then 105 | while [ "$fullVersion" != "$version" -a "${fullVersion%[.-]*}" != "$fullVersion" ]; do 106 | versionAliases+=( $fullVersion ) 107 | fullVersion="${fullVersion%[.-]*}" 108 | done 109 | else 110 | versionAliases+=( $fullVersion ) 111 | fi 112 | versionAliases+=( 113 | $version 114 | ${aliases[$version]:-} 115 | ) 116 | 117 | for variant in ubuntu alpine; do 118 | dir="$version/$variant" 119 | commit="$(dirCommit "$dir")" 120 | 121 | if [ "$variant" = "$defaultVariant" ]; then 122 | variantAliases=( "${versionAliases[@]}" ) 123 | else 124 | variantAliases=( "${versionAliases[@]/%/-$variant}" ) 125 | variantAliases=( "${variantAliases[@]//latest-/}" ) 126 | fi 127 | 128 | variantParent="$(awk ' 129 | /^FROM/ { 130 | if (index($2, ":") > 0) { 131 | print $2 132 | exit 0 133 | } 134 | }' "$dir/Dockerfile")" 135 | variantArches="${parentRepoToArches[$variantParent]}" 136 | 137 | echo 138 | cat <<-EOE 139 | Tags: $(join ', ' "${variantAliases[@]}") 140 | Architectures: $(join ', ' $variantArches) 141 | GitCommit: $commit 142 | Directory: $dir 143 | EOE 144 | 145 | for subVariant in management; do 146 | subDir="$dir/$subVariant" 147 | commit="$(dirCommit "$subDir")" 148 | 149 | subVariantAliases=( "${versionAliases[@]/%/-$subVariant}" ) 150 | subVariantAliases=( "${subVariantAliases[@]//latest-/}" ) 151 | 152 | if [ "$variant" != "$defaultVariant" ]; then 153 | subVariantAliases=( "${subVariantAliases[@]/%/-$variant}" ) 154 | fi 155 | 156 | echo 157 | cat <<-EOE 158 | Tags: $(join ', ' "${subVariantAliases[@]}") 159 | Architectures: $(join ', ' $variantArches) 160 | GitCommit: $commit 161 | Directory: $subDir 162 | EOE 163 | done 164 | done 165 | done 166 | -------------------------------------------------------------------------------- /update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 5 | 6 | ./versions.sh "$@" 7 | ./apply-templates.sh "$@" 8 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "3.13": { 3 | "alpine": { 4 | "version": "3.22" 5 | }, 6 | "openssl": { 7 | "sha256": "d319da6aecde3aa6f426b44bbf997406d95275c5c59ab6f6ef53caaa079f456f", 8 | "version": "3.1.8" 9 | }, 10 | "otp": { 11 | "sha256": "5738e05890777716d3f38863aab391988f62529bba7a6299f39d14bc45410412", 12 | "version": "26.2.5.12" 13 | }, 14 | "ubuntu": { 15 | "version": "24.04" 16 | }, 17 | "version": "3.13.7" 18 | }, 19 | "3.13-rc": null, 20 | "4.0": { 21 | "alpine": { 22 | "version": "3.22" 23 | }, 24 | "openssl": { 25 | "sha256": "712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539", 26 | "version": "3.3.3" 27 | }, 28 | "otp": { 29 | "sha256": "c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b", 30 | "version": "27.3.4" 31 | }, 32 | "ubuntu": { 33 | "version": "24.04" 34 | }, 35 | "version": "4.0.9" 36 | }, 37 | "4.0-rc": null, 38 | "4.1": { 39 | "alpine": { 40 | "version": "3.22" 41 | }, 42 | "openssl": { 43 | "sha256": "712590fd20aaa60ec75d778fe5b810d6b829ca7fb1e530577917a131f9105539", 44 | "version": "3.3.3" 45 | }, 46 | "otp": { 47 | "sha256": "c3a0a0b51df08f877eed88378f3d2da7026a75b8559803bd78071bb47cd4783b", 48 | "version": "27.3.4" 49 | }, 50 | "ubuntu": { 51 | "version": "24.04" 52 | }, 53 | "version": "4.1.0" 54 | }, 55 | "4.1-rc": null 56 | } 57 | -------------------------------------------------------------------------------- /versions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -Eeuo pipefail 3 | 4 | declare -A alpineVersions=( 5 | [3.13]='3.22' 6 | [4.0]='3.22' 7 | [4.1]='3.22' 8 | ) 9 | 10 | declare -A ubuntuVersions=( 11 | [3.13]='24.04' 12 | [4.0]='24.04' 13 | [4.1]='24.04' 14 | ) 15 | 16 | # https://www.rabbitmq.com/which-erlang.html ("Maximum supported Erlang/OTP") 17 | declare -A otpMajors=( 18 | [3.13]='26' 19 | [4.0]='27' 20 | [4.1]='27' 21 | ) 22 | 23 | # https://www.openssl.org/policies/releasestrat.html 24 | # https://www.openssl.org/source/ 25 | declare -A opensslMajors=( 26 | [3.13]='3.1' 27 | [4.0]='3.3' 28 | [4.1]='3.3' 29 | ) 30 | 31 | cd "$(dirname "$(readlink -f "$BASH_SOURCE")")" 32 | 33 | versions=( "$@" ) 34 | if [ ${#versions[@]} -eq 0 ]; then 35 | versions=( "${!otpMajors[@]}" ) 36 | # try RC releases after doing the non-RCs so we can check whether they're newer (and thus whether we should care) 37 | versions+=( "${versions[@]/%/-rc}" ) 38 | json='{}' 39 | else 40 | json="$(< versions.json)" 41 | fi 42 | versions=( "${versions[@]%/}" ) 43 | 44 | for version in "${versions[@]}"; do 45 | export version 46 | 47 | rcVersion="${version%-rc}" 48 | rcGrepV='-v' 49 | if [ "$rcVersion" != "$version" ]; then 50 | rcGrepV= 51 | fi 52 | rcGrepV+=' -E' 53 | rcGrepExpr='beta|milestone|rc' 54 | 55 | githubTags=( $( 56 | git ls-remote --tags https://github.com/rabbitmq/rabbitmq-server.git \ 57 | "refs/tags/v${rcVersion}"{'','.*','-*','^*'} \ 58 | | cut -d'/' -f3- \ 59 | | cut -d'^' -f1 \ 60 | | { grep $rcGrepV -- "$rcGrepExpr" || :; } \ 61 | | sort -urV 62 | ) ) 63 | 64 | fullVersion= 65 | githubTag= 66 | for possibleTag in "${githubTags[@]}"; do 67 | fullVersion="$( 68 | { 69 | # thanks GitHub... 70 | wget -qO- "https://github.com/rabbitmq/rabbitmq-server/releases/expanded_assets/$possibleTag" \ 71 | || wget -qO- "https://github.com/rabbitmq/rabbitmq-server/releases/tag/$possibleTag" 72 | } | grep -oE "/rabbitmq-server-generic-unix-${rcVersion}([.-].+)?[.]tar[.]xz" \ 73 | | head -1 \ 74 | | sed -r "s/^.*(${rcVersion}.*)[.]tar[.]xz/\1/" \ 75 | || : 76 | )" 77 | if [ -n "$fullVersion" ]; then 78 | githubTag="$possibleTag" 79 | break 80 | fi 81 | done 82 | if [ -z "$fullVersion" ] || [ -z "$githubTag" ]; then 83 | echo >&2 "warning: failed to get full version for '$version'; skipping" 84 | continue 85 | fi 86 | export fullVersion 87 | 88 | # if this is a "-rc" release, let's make sure the release it contains isn't already GA (and thus something we should not publish anymore) 89 | export rcVersion 90 | if [ "$rcVersion" != "$version" ] && rcFullVersion="$(jq <<<"$json" -r '.[env.rcVersion].version // ""')" && [ -n "$rcFullVersion" ]; then 91 | latestVersion="$({ echo "$fullVersion"; echo "$rcFullVersion"; } | sort -V | tail -1)" 92 | if [[ "$fullVersion" == "$rcFullVersion"* ]] || [ "$latestVersion" = "$rcFullVersion" ]; then 93 | # "x.y.z-rc1" == x.y.z* 94 | echo >&2 "warning: skipping/removing '$version' ('$rcVersion' is at '$rcFullVersion' which is newer than '$fullVersion')" 95 | json="$(jq <<<"$json" -c '.[env.version] = null')" 96 | continue 97 | fi 98 | fi 99 | 100 | otpMajor="${otpMajors[$rcVersion]}" 101 | otpVersions=( $( 102 | git ls-remote --tags https://github.com/erlang/otp.git \ 103 | "refs/tags/OTP-$otpMajor.*"\ 104 | | cut -d'/' -f3- \ 105 | | cut -d'^' -f1 \ 106 | | cut -d- -f2- \ 107 | | sort -urV 108 | ) ) 109 | otpVersion= 110 | for possibleVersion in "${otpVersions[@]}"; do 111 | if otpSourceSha256="$( 112 | wget -qO- "https://github.com/erlang/otp/releases/download/OTP-$possibleVersion/SHA256.txt" \ 113 | | awk -v v="$possibleVersion" '$2 == "otp_src_" v ".tar.gz" { print $1 }' 114 | )"; then 115 | otpVersion="$possibleVersion" 116 | break 117 | fi 118 | done 119 | if [ -z "$otpVersion" ]; then 120 | echo >&2 "warning: failed to get Erlang/OTP version for '$version' ($fullVersion); skipping" 121 | continue 122 | fi 123 | export otpVersion otpSourceSha256 124 | 125 | opensslMajor="${opensslMajors[$rcVersion]}" 126 | # grab versions from upstream and ignore any alpha/beta releases 127 | opensslVersions=( $( 128 | git ls-remote --tags https://github.com/openssl/openssl.git \ 129 | "refs/tags/openssl-$opensslMajor.*"\ 130 | | cut -d'/' -f3- \ 131 | | cut -d'^' -f1 \ 132 | | cut -d- -f2- \ 133 | | grep -vE -- '-[A-Za-z]+' \ 134 | | sort -urV 135 | ) ) 136 | opensslVersion= 137 | for possibleVersion in "${opensslVersions[@]}"; do 138 | if opensslSourceSha256="$(wget -qO- "https://github.com/openssl/openssl/releases/download/openssl-$possibleVersion/openssl-$possibleVersion.tar.gz.sha256")"; then 139 | opensslVersion="$possibleVersion" 140 | break 141 | fi 142 | done 143 | if [ -z "$opensslVersion" ]; then 144 | echo >&2 "warning: failed to get OpenSSL version for '$version' ($fullVersion); skipping" 145 | continue 146 | fi 147 | export opensslVersion opensslSourceSha256 148 | 149 | # OpenSSL 3.0.5's sha256 file starts with a single space 😬 150 | opensslSourceSha256="${opensslSourceSha256# }" 151 | # OpenSSL 3.1.8+ and 3.3.3+ now include the filename 152 | opensslSourceSha256="${opensslSourceSha256%% *}" 153 | 154 | alpineVersion="${alpineVersions[$rcVersion]}" 155 | export alpineVersion 156 | 157 | ubuntuVersion="${ubuntuVersions[$rcVersion]}" 158 | export ubuntuVersion 159 | 160 | echo "$version: $fullVersion (otp $otpVersion, openssl $opensslVersion, alpine, $alpineVersion, ubuntu $ubuntuVersion)" 161 | 162 | json="$( 163 | jq <<<"$json" -c ' 164 | .[env.version] = { 165 | version: env.fullVersion, 166 | openssl: { 167 | version: env.opensslVersion, 168 | sha256: env.opensslSourceSha256, 169 | }, 170 | otp: { 171 | version: env.otpVersion, 172 | sha256: env.otpSourceSha256, 173 | }, 174 | alpine: { 175 | version: env.alpineVersion 176 | }, 177 | ubuntu: { 178 | version: env.ubuntuVersion 179 | }, 180 | } 181 | ' 182 | )" 183 | done 184 | 185 | jq <<<"$json" -S . > versions.json 186 | --------------------------------------------------------------------------------