Closed1
wkhtmltopdf-binary を使っている Rails コンテナのイメージサイズ削減
wkhtmltopdf-binary が結構イメージサイズを食っているということがあった。
bin/ 以下に各種アーキテクチャ・OS別のバイナリがあるので、これがそこそこ大きい
実行時には、これらのうち実際のアーキテクチャ・OSにマッチするバイナリ以外しかいらないはずなので、いらないものはインストールしないようにしたい。やや豪快だが、インストール後に不要なバイナリは削除することにした。
下記のようなスクリプトを足す。
ただし、アップデートで、バイナリの命名規則が変わると動かなくなることに注意する。
remove_unnecessary_binaries.rb
require 'rbconfig'
# バイナリの判定ロジックは、こちらを参考にしている: https://github.com/zakird/wkhtmltopdf_binary_gem/blob/e1baf3e9dc97e64d79f8333bd1a5848de5dee407/bin/wkhtmltopdf
def architecture
case RbConfig::CONFIG['host_cpu']
when *%w[arm64 aarch64 arch64]
'arm64'
when 'x86_64'
'amd64'
else
'i386'
end
end
def detect_binary_suffix
suffix = case RbConfig::CONFIG['host_os']
when /linux/
os = `. /etc/os-release 2> /dev/null && echo ${ID}_${VERSION_ID}`.strip
os = 'ubuntu_16.04' if os.start_with?('ubuntu_16.') ||
os.start_with?('ubuntu_17.') ||
os.start_with?('linuxmint_18.')
os = 'ubuntu_18.04' if os.start_with?('ubuntu_18.') ||
os.start_with?('ubuntu_19.') ||
os.start_with?('elementary') ||
os.start_with?('linuxmint_19.') ||
os.start_with?('pop') ||
os.start_with?('zorin')
os = 'ubuntu_20.04' if os.start_with?('ubuntu_20.') ||
os.start_with?('linuxmint_20.')
os = 'ubuntu_21.10' if os.start_with?('ubuntu_21.') ||
os.start_with?('linuxmint_21.')
os = 'ubuntu_22.04' if os.start_with?('ubuntu_22.') ||
os.start_with?('ubuntu_24.') ||
os.start_with?('tuxedo_22.') ||
os.start_with?('linuxmint_22')
os = 'centos_6' if (os.start_with?('amzn_') && os != 'amzn_2' && os != 'amzn_2023') ||
(os.empty? && File.read('/etc/centos-release').start_with?('CentOS release 6'))
os = 'centos_7' if (os.start_with?('amzn_2') && !os.start_with?('amzn_20')) ||
os.start_with?('rhel_7.')
os = 'centos_8' if os.start_with?('rocky_8') ||
os.start_with?('rhel_8.') ||
os.start_with?('ol_8.') ||
os.start_with?('almalinux_8') ||
os.start_with?('alinux_') ||
os == 'amzn_2023'
os_based_on_debian_9 = os.start_with?('debian_9') ||
os.start_with?('deepin')
os = 'debian_9' if os_based_on_debian_9
os = 'debian_10' if !os_based_on_debian_9 && os.start_with?('debian_10')
os = 'debian_11' if !os_based_on_debian_9 && os.start_with?('debian_11')
os = 'debian_12' if !os_based_on_debian_9 && os.start_with?('debian_12')
os = 'archlinux' if os.start_with?('arch_') ||
os.start_with?('manjaro_')
"#{os}_#{architecture}"
when /darwin/
'macos_cocoa'
else
'unknown'
end
suffix
end
binary_dir = File.dirname(Gem.bin_path("wkhtmltopdf-binary", "wkhtmltopdf"))
binary_suffix = detect_binary_suffix
exclude_file = File.join(binary_dir, "wkhtmltopdf_#{binary_suffix}.gz")
Dir.glob("#{binary_dir}/*.gz").each do |file|
if File.file?(file) && file != exclude_file
puts "Removing #{file}"
File.delete(file)
end
end
Dockerfile 内で bundle install した後にこのスクリプトを実行する。
...
COPY remove_unnecessary_binaries.rb /app/remove_unnecessary_binaries.rb
RUN bundle config set --local without 'test development' \
&& bundle install -j4 \
&& ruby /app/remove_unnecessary_binaries.rb \
&& rm -rf /usr/local/bundle/cache/*.gem \
&& find /usr/local/bundle/gems/ -name "*.c" -delete \
&& find /usr/local/bundle/gems/ -name "*.o" -delete
このスクラップは2025/02/10にクローズされました