lib/generators/dockerfile_generator.rb in dockerfile-rails-1.5.14 vs lib/generators/dockerfile_generator.rb in dockerfile-rails-1.6.0
- old
+ new
@@ -6,10 +6,11 @@
class DockerfileGenerator < Rails::Generators::Base
include DockerfileRails::Scanner
BASE_DEFAULTS = {
+ "alpine" => false,
"bin-cd" => false,
"cache" => false,
"ci" => false,
"compose" => false,
"fullstaq" => false,
@@ -37,11 +38,11 @@
"sqlite3" => false,
"sqlserver" => false,
"sentry" => false,
"sudo" => false,
"swap" => nil,
- "variant" => "slim",
+ "variant" => nil,
"windows" => false,
"yjit" => false,
}.yield_self { |hash| Struct.new(*hash.keys.map(&:to_sym)).new(*hash.values) }
OPTION_DEFAULTS = BASE_DEFAULTS.dup
@@ -50,10 +51,29 @@
@@packages = { "base" => [], "build" => [], "deploy" => [] }
@@vars = { "base" => {}, "build" => {}, "deploy" => {} }
@@args = { "base" => {}, "build" => {}, "deploy" => {} }
@@instructions = { "base" => nil, "build" => nil, "deploy" => nil }
+ ALPINE_MAPPINGS = {
+ "build-essential" => "build-base",
+ "chromium-sandbox" => "chromium-chromedriver",
+ "default-libmysqlclient-dev" => "mysql-client",
+ "default-mysqlclient" => "mysql-client",
+ "freedts-bin" => "freedts",
+ "libicu-dev" => "icu-dev",
+ "libjemalloc" => "jemalloc-dev",
+ "libjpeg-dev" => "jpeg-dev",
+ "libmagickwand-dev" => "imagemagick-libs",
+ "libsqlite3-0" => "sqlite-dev",
+ "libtiff-dev" => "tiff-dev",
+ "libvips" => "vips-dev",
+ "node-gyp" => "gyp",
+ "pkg-config" => "pkgconfig",
+ "python" => "python3",
+ "python-is-python3" => "python3"
+ }
+
# load defaults from config file
if File.exist? "config/dockerfile.yml"
options = YAML.safe_load(IO.read("config/dockerfile.yml"), symbolize_names: true)[:options]
if options
@@ -144,10 +164,13 @@
desc: "image platform (example: linux/arm64)"
class_option :registry, type: :string, default: OPTION_DEFAULTS.registry,
desc: "docker registry to use (example: registry.docker.com/library/)"
+ class_option :alpine, type: :boolean, default: OPTION_DEFAULTS.alpine,
+ descr: "use alpine image"
+
class_option :variant, type: :string, default: OPTION_DEFAULTS.variant,
desc: "dockerhub image variant (example: slim-bullseye)"
class_option :jemalloc, type: :boolean, default: OPTION_DEFAULTS.jemalloc,
desc: "use jemalloc alternative malloc implementation"
@@ -372,10 +395,14 @@
else
""
end
end
+ def variant
+ options.variant || (options.alpine ? "alpine" : "slim")
+ end
+
def run_as_root?
options.root?
end
def using_litefs?
@@ -514,10 +541,14 @@
end
gems.sort
end
+ def alpinize(packages)
+ packages.map { |package| ALPINE_MAPPINGS[package] || package }.sort.uniq
+ end
+
def base_packages
packages = []
packages += @@packages["base"] if @@packages["base"]
if using_execjs?
@@ -542,11 +573,17 @@
end
# Passenger
packages << "passenger" if using_passenger?
- packages.sort.uniq
+ if options.alpine?
+ packages << "tzdata"
+
+ alpinize(packages)
+ else
+ packages.sort.uniq
+ end
end
def base_requirements
requirements = []
requirements << "nodejs" if using_execjs?
@@ -608,11 +645,15 @@
else
packages << "python"
end
end
- packages.sort.uniq
+ if options.alpine?
+ alpinize(packages)
+ else
+ packages.sort.uniq
+ end
end
def deploy_packages
packages = %w(curl) # work with the default healthcheck strategy in MRSK
packages += @@packages["deploy"] if @@packages["deploy"]
@@ -657,13 +698,52 @@
if !options.procfile.blank? || (procfile.size > 1)
packages << "ruby-foreman"
end
- packages.sort
+ if options.alpine?
+ packages << "sqlite-libs" if @gemfile.include? "sqlite3"
+ packages << "libpq" if @gemfile.include? "pg"
+
+ alpinize(packages)
+ else
+ packages.sort.uniq
+ end
end
+ def pkg_update
+ if options.alpine?
+ "apk update"
+ else
+ "apt-get update -qq"
+ end
+ end
+
+ def pkg_install
+ if options.alpine?
+ "apk add"
+ else
+ "apt-get install --no-install-recommends -y"
+ end
+ end
+
+ def pkg_cache
+ if options.alpine?
+ { "dev-apk-cache" => "/var/cache/apk" }
+ else
+ { "dev-apt-cache" => "/var/cache/apt", "dev-apt-lib" => "/var/lib/apt" }
+ end
+ end
+
+ def pkg_cleanup
+ if options.alpine?
+ "/var/cache/apk/*"
+ else
+ "/var/lib/apt/lists /var/cache/apt/archives"
+ end
+ end
+
def base_repos
repos = []
packages = []
if using_passenger?
@@ -678,12 +758,12 @@
if repos.empty?
""
else
packages.sort!.uniq!
unless packages.empty?
- repos.unshift "apt-get update -qq &&",
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
+ repos.unshift "#{pkg_update} &&",
+ "#{pkg_install} #{packages.join(" ")} &&"
end
repos.join(" \\\n ") + " && \\\n "
end
end
@@ -704,21 +784,22 @@
if repos.empty?
""
else
packages.sort!.uniq!
unless packages.empty?
- repos.unshift "apt-get update -qq &&",
- "apt-get install --no-install-recommends -y #{packages.join(" ")} &&"
+ repos.unshift "#{pkg_update} &&",
+ "#{pkg_install} --no-install-recommends -y #{packages.join(" ")} &&"
end
repos.join(" \\\n ") + " && \\\n "
end
end
def base_env
env = {
"RAILS_ENV" => "production",
+ "BUNDLE_PATH" => "/usr/local/bundle",
"BUNDLE_WITHOUT" => options.ci? ? "development" : "development:test"
}
if options.lock?
env["BUNDLE_DEPLOYMENT"] = "1"
@@ -732,10 +813,10 @@
env.merge! @@args["base"].to_h { |key, value| [key, "$#{key}"] }
end
env.merge! @@vars["base"] if @@vars["base"]
- env.map { |key, value| "#{key}=#{value.inspect}" }
+ env.map { |key, value| "#{key}=#{value.inspect}" }.sort
end
def build_env
env = {}