如何减小 discourse Docker 镜像大小?

大家好:

我们在 K8s 集群中部署 Discourse,需要构建一个镜像,但该集群有一些限制,例如无法访问外部互联网等。该论坛是内部使用的,所以这方面没有问题。为了实现这一点,我遵循了官方支持的安装方法,并基于启动脚本的 bootstrap 和 run 命令创建了一个 Dockerfile,其中我们执行了所有不需要数据库的构建时步骤,以及在启动时执行的其余步骤。启动速度有点慢,但目前还可以接受。

这样做的一个问题是最终镜像相当大(约 2GB),因为我使用 Discourse 基础镜像来运行启动脚本。我查看了基础镜像的 Dockerfile - https://github.com/discourse/discourse_docker/blob/master/image/base/Dockerfile。看起来安装了很多东西,比如 postgres 和 redis。我们正在尝试使用多容器方法,其中 discourse、redis 和 postgres 在不同的容器中。我明白这是一个通用的基础镜像,适用于所有支持的安装方式。但我正在寻找一种方法来减小最终镜像的大小。此外,移除不必要的东西在漏洞方面会更好。

我的问题是,我是否可以安全地移除基础 Docker 镜像中安装的 postgres、redis 依赖项,而不会破坏 Discourse 应用程序的任何功能?另外,是否可以从最终镜像中移除 curl、wget 等工具,因为在我们的设置中它们很少需要,而且控制台几乎无法访问。

1 个赞

您也可以——我这里还有一个正在进行的计划,旨在通过此操作来精简镜像:

回复:镜像启动缓慢——我们目前也在为此做些准备。

3 个赞

这里是提问的好地方吗?我想问一下,“精简版”(slim)镜像是什么,自托管者能使用它们吗?

普通镜像大约是 1G,而精简版镜像大约是 600M。(查看 这个索引 中的 Docker 镜像)

ask.discourse.com 认为这些精简版镜像正是为此类目的而设计的,但我不知道这些信息是否准确。)

3 个赞

我尝试用精简版基础镜像替换普通基础镜像,然后它就开始失败了。我看到了很多不同类型的错误,所以我不知道是什么原因导致的。

错误集 1

/usr/local/lib/ruby/gems/3.3.0/gems/bundler-2.6.4/lib/bundler/definition.rb:683:in `materialize’: Could not find bootsnap-1.18.6, actionmailer-8.0.2, actionpack-8.0.2, actionview-8.0.2, activemodel-8.0.2, activerecord-8.0.2, activesupport-8.0.2, railties-8.0.2, propshaft-1.2.1, json-2.13.0, actionview_precompiler-0.4.0, discourse-seed-fu-2.3.12, mail-2.8.1, mini_mime-1.1.5, mini_suffix-0.3.3, redis-5.4.0, redis-namespace-1.11.0, active_model_serializers-0.8.4, http_accept_language-2.1.1, discourse-fonts-0.0.19, discourse-emojis-1.0.41, message_bus-4.4.1, rails_multisite-7.0.0, fastimage-2.3.1, aws-sdk-s3-1.182.0, aws-sdk-sns-1.96.0, excon-1.2.5, unf-0.2.0, email_reply_trimmer-0.2.0, image_optim-0.31.4, multi_json-1.17.0, mustache-1.1.1, nokogiri-1.18.8-x86_64-linux-gnu, loofah-2.24.1, css_parser-1.21.1, omniauth-2.1.2, omniauth-facebook-9.0.0, omniauth-twitter-1.4.0, omniauth-github-2.0.0, omniauth-oauth2-1.7.3, omniauth-google-oauth2-1.0.1, oj-3.16.11, pg-1.5.9, mini_sql-1.6.0, pry-rails-0.3.11, pry-byebug-3.11.0, rtlcss-0.2.1, messageformat-wrapper-1.1.0, rake-13.3.0, thor-1.4.0, diffy-3.4.4, rinku-2.0.6, sidekiq-7.3.9, mini_scheduler-0.18.0, execjs-2.10.0, mini_racer-0.19.0, highline-3.1.2, rack-2.2.17, rack-protection-3.2.0, cbor-0.5.9.8, cose-1.3.1, addressable-2.8.7, json_schemer-2.4.0, net-imap-0.5.9, digest-3.2.0, capybara-3.40.0, webmock-3.25.1, simplecov-0.22.0, test-prof-1.4.4, rails-dom-testing-2.3.0, minio_runner-1.0.0, capybara-playwright-driver-0.5.6, rspec-3.13.1, listen-3.9.0, certified-1.0.0, fabrication-3.0.0, mocha-2.7.1, rb-fsevent-0.11.2, rspec-rails-8.0.1, shoulda-matchers-6.5.0, rspec-html-matchers-0.10.0, pry-stack_explorer-0.6.1, byebug-12.0.0, rubocop-discourse-3.12.1, parallel_tests-5.3.0, rswag-specs-2.16.0, annotaterb-4.17.0, syntax_tree-6.3.0, rspec-multi-mock-0.3.1, ruby-prof-1.7.2, bullet-8.0.8, better_errors-2.10.1, binding_of_caller-1.0.1, yaml-lint-0.1.2, yard-0.9.37, discourse_dev_assets-0.0.5, faker-3.5.2, fast_blank-1.0.1, lru_redux-1.1.0, htmlentities-4.3.4, rack-mini-profiler-4.0.0, unicorn-6.1.0, puma-6.6.0, rbtrace-0.5.2, ruby-readability-0.7.2, stackprof-0.2.27, memory_profiler-1.1.0, cppjieba_rb-0.4.4, lograge-0.14.0, logstash-event-1.2.02, logster-2.20.1, sassc-embedded-1.80.2, rotp-6.3.0, rqrcode-3.1.0, rubyzip-2.4.1, sshkey-3.0.0, rchardet-1.9.0, lz4-ruby-0.3.3, sanitize-7.0.0, web-push-3.0.1, colored2-4.0.3, maxminddb-0.1.22, rails_failover-2.3.0, faraday-2.13.3, faraday-retry-2.3.2, net-http-0.6.0, cgi-0.5.0, tzinfo-data-1.2025.2, csv-3.3.5, iso8601-0.13.0, rrule-0.6.0, dry-initializer-3.2.0, parallel-1.27.0, inflection-1.0.0, multipart-post-2.4.1, faraday-multipart-1.1.1, zendesk_api-1.38.0.rc1, stripe-11.1.0, sawyer-0.9.2, octokit-5.6.1, tokenizers-0.5.5-x86_64-linux, tokenizers-0.5.5, tiktoken_ruby-0.0.11.1-x86_64-linux, discourse_ai-tokenizers-0.3.1, ed25519-1.4.0, Ascii85-2.0.1, ruby-rc4-0.1.5, hashery-2.1.2, ttfunk-1.8.0, afm-0.2.2, pdf-reader-2.14.1, msgpack-1.8.0, activejob-8.0.2, rack-session-1.0.2, rack-test-2.2.0, rails-html-sanitizer-1.6.2, useragent-0.16.11, builder-3.3.0, erubi-1.13.1, timeout-0.4.3, base64-0.3.0, benchmark-0.4.1, bigdecimal-3.2.2, concurrent-ruby-1.3.5, connection_pool-2.5.3, drb-2.2.3, i18n-1.14.7, logger-1.7.0, minitest-5.25.5, securerandom-0.4.1, tzinfo-2.0.6, uri-1.0.3, irb-1.15.2, rackup-1.0.1, zeitwerk-2.7.3, ffi-1.17.2-x86_64-linux-gnu, redis-client-0.25.1, aws-sdk-core-3.226.0, aws-sdk-kms-1.99.0, aws-sigv4-1.12.1, exifr-1.4.1, fspath-3.1.2, image_size-3.4.0, in_threads-1.6.0, progress-3.6.0, racc-1.8.1, crass-1.0.6, hashie-5.0.0, omniauth-oauth-1.2.1, oauth2-1.4.11, jwt-2.10.1, ostruct-0.6.3, pry-0.15.2, libv8-node-24.1.0.0-x86_64-linux, libv8-node-24.1.0.0, reline-0.6.2, openssl-signature_algorithm-1.3.0, public_suffix-6.0.2, hana-1.3.7, regexp_parser-2.10.0, simpleidn-0.2.3, date-3.4.1, matrix-0.4.3, xpath-3.2.0, crack-1.0.0, hashdiff-1.2.0, docile-1.4.1, simplecov-html-0.13.2, simplecov_json_formatter-0.1.4, playwright-ruby-client-1.52.0, rspec-core-3.13.5, rspec-expectations-3.13.5, rspec-mocks-3.13.5, rb-inotify-0.11.1, rspec-support-3.13.4, lint_roller-1.1.0, rubocop-1.78.0, rubocop-capybara-2.22.1, rubocop-factory_bot-2.27.1, rubocop-rails-2.32.0, rubocop-rspec-3.6.0, rubocop-rspec_rails-2.31.0, json-schema-5.2.1, prettier_print-1.2.1, uniform_notifier-1.17.0, rouge-4.6.0, debug_inspector-1.2.0, literate_randomizer-0.4.0, kgio-2.11.4, raindrops-0.20.1, nio4r-2.7.4, optimist-3.2.1, guess_html_encoding-0.0.11, rexml-3.4.1, request_store-1.7.0, sass-embedded-1.85.0-x86_64-linux-gnu, chunky_png-1.4.0, rqrcode_core-2.0.0, openssl-3.3.0, faraday-net_http-3.4.1, globalid-1.2.1, pp-0.6.2, rdoc-6.14.2, webrick-1.9.1, aws-eventstream-1.4.0, aws-partitions-1.1117.0, jmespath-1.6.2, oauth-1.1.0, multi_xml-0.7.2, coderay-1.1.3, method_source-1.1.0, io-console-0.8.1, mime-types-3.7.0, diff-lcs-1.6.2, language_server-protocol-3.17.0.5, parser-3.3.8.0, rainbow-3.1.1, rubocop-ast-1.46.0, ruby-progressbar-1.13.0, unicode-display_width-3.1.4, google-protobuf-4.31.1-x86_64-linux-gnu, google-protobuf-4.31.1, erb-5.0.2, psych-5.2.6, oauth-tty-1.0.5, snaky_hash-2.0.3, version_gem-1.1.8, mime-types-data-3.2025.0715, ast-2.4.3, prism-1.4.0, unicode-emoji-4.0.4, stringio-3.1.7 in locally installed gems (Bundler::GemNotFound)

supervisor pid: 577 unicorn pid: 583
./config/unicorn_launcher: line 66: unicorn: command not found

编辑:抱歉打扰了。这些失败可能只是因为构建时失败。不知何故,构建看起来完成了,但现在我看到一些步骤失败了。特别是 cd /var/www/discourse && su discourse -c 'bundle install --jobs $(($(nproc) - 1)) --retry 3',由于权限问题。不过我想知道,为什么这在精简版和普通版基础镜像之间会有变化?

构建步骤中的错误

Retrying download gem from https://rubygems.org/due to error (2/4): Bundler::PermissionError There was an error while trying to write to `/usr/local/lib/ruby/gems/3.3.0/cache/rake-13.3.0.gem`. It is likely that you need to grant write permissions for that path.

精简版镜像仍然包含 postgres 和 redis。

精简版与其他版本的区别从第 37 条命令开始。以下命令在精简版中未执行:

ENV RAILS_ENV=production
RUN |3 DEBIAN_RELEASE=bookworm PG_MAJOR=15 DISCOURSE_BRANCH=main /bin/sh -c cd /var/www/discourse &&    sudo -u discourse bundle config --local deployment true &&    sudo -u discourse bundle config --local path ./vendor/bundle &&    sudo -u discourse bundle config --local without test development &&    sudo -u discourse bundle install --jobs $(($(nproc) - 1)) &&    find /var/www/discourse/vendor/bundle -name cache -not -path '*/gems/*' -type d -exec rm -rf {} + &&    find /var/www/discourse/vendor/bundle -name tmp -type d -exec rm -rf {} + # buildkit
RUN |3 DEBIAN_RELEASE=bookworm PG_MAJOR=15 DISCOURSE_BRANCH=main /bin/sh -c cd /var/www/discourse &&    sudo -u discourse /bin/bash -c 'if [ -f yarn.lock ]; then yarn install --frozen-lockfile && yarn cache clean; else pnpm install --frozen-lockfile; fi' # buildkit

基本上,它缺少一些构建步骤。没有 bundle install,也没有 pnpm install。这些是你最终会需要的。

最大的问题在于第 11 条命令:390MiB

RUN |2 DEBIAN_RELEASE=bookworm PG_MAJOR=15 /bin/sh -c echo "debconf debconf/frontend select Teletype" | debconf-set-selections;     apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install gnupg sudo curl fping locales     ca-certificates rsync     cmake g++ pkg-config patch     libxslt-dev libcurl4-openssl-dev     libssl-dev libyaml-dev libtool     libpcre3 libpcre3-dev zlib1g zlib1g-dev     libxml2-dev gawk parallel     libreadline-dev anacron wget     psmisc whois brotli libunwind-dev     libtcmalloc-minimal4 cmake     pngcrush pngquant ripgrep poppler-utils     ghostscript libjbig0 libtiff6 libpng16-16 libfontconfig1     libwebpdemux2 libwebpmux3 libxext6 librsvg2-2 libgomp1     fonts-urw-base35 libheif1/${DEBIAN_RELEASE}-backports     nginx-common &&     DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends git rsyslog logrotate cron ssh-client less;     install -d /usr/share/postgresql-common/pgdg &&    curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc &&    echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt ${DEBIAN_RELEASE}-pgdg main" > /etc/apt/sources.list.d/pgdg.list;     curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -;     echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list;     curl --silent --location https://deb.nodesource.com/setup_22.x | sudo bash -;     sed -i -e 's/start -q anacron/anacron -s/' /etc/cron.d/anacron;     sed -i.bak 's/$ModLoad imklog/#$ModLoad imklog/' /etc/rsyslog.conf;     sed -i.bak 's/module(load="imklog")/#module(load="imklog")/' /etc/rsyslog.conf;     dpkg-divert --local --rename --add /sbin/initctl;     sh -c "test -f /sbin/initctl || ln -s /bin/true /sbin/initctl";     apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get -y install runit socat     libpq-dev postgresql-client-${PG_MAJOR}     postgresql-${PG_MAJOR} postgresql-contrib-${PG_MAJOR} postgresql-${PG_MAJOR}-pgvector     nodejs yarn &&    mkdir -p /etc/runit/1.d # buildkit

它安装了许多其他部分所需的工具,也安装了 postgresql:

gnupg sudo curl fping locales ca-certificates rsync cmake g++ pkg-config patch libxslt-dev libcurl4-openssl-dev libssl-dev libyaml-dev libtool libpcre3 libpcre3-dev zlib1g zlib1g-dev libxml2-dev gawk parallel libreadline-dev anacron wget psmisc whois brotli libunwind-dev libtcmalloc-minimal4 cmake pngcrush pngquant ripgrep poppler-utils ghostscript libjbig0 libtiff6 libpng16-16 libfontconfig1 libwebpdemux2 libwebpmux3 libxext6 librsvg2-2 libgomp1 fonts-urw-base35 libheif1 nginx-common git rsyslog logrotate cron ssh-client less runit socat libpq-dev postgresql-client postgresql postgresql-contrib postgresql-pgvector nodejs yarn

1 个赞

除了 postgres+redis(我有一个提供上述的建议)之外,那里安装的一些较大的库是用于编译 Discourse 使用的 gem。目前没有简单有效的方法可以删除这些库。

跟进,上述提案已合并,并且现在正在构建不包含 postgres 或 redis 的 *-web-only 镜像。(撰写本文时最新的已构建标签是 discourse/base:2.0.20250813-2244-web-only

2 个赞

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.