lib/generators/dockerfile_generator.rb in dockerfile-rails-1.6.25 vs lib/generators/dockerfile_generator.rb in dockerfile-rails-1.7.0

- old
+ new

@@ -1,9 +1,10 @@ # frozen_string_literal: true require "erb" require "json" +require "shellwords" require_relative "../dockerfile-rails/scanner.rb" class DockerfileGenerator < Rails::Generators::Base include DockerfileRails::Scanner @@ -13,14 +14,15 @@ "cache" => false, "ci" => false, "compose" => false, "fullstaq" => false, "gemfile-updates" => true, - "jemalloc" => false, + "jemalloc" => true, "label" => {}, "link" => false, "litefs" => false, + "litestream" => false, "lock" => true, "max-idle" => nil, "migrate" => "", "mysql" => false, "nginx" => false, @@ -72,11 +74,12 @@ "libjemalloc2" => "jemalloc", "libvips" => "vips-dev", "node-gyp" => "gyp", "pkg-config" => "pkgconfig", "python" => "python3", - "python-is-python3" => "python3" + "python-is-python3" => "python3", + "sqlite3" => "sqlite", } # load defaults from config file if File.exist? "config/dockerfile.yml" options = YAML.safe_load(IO.read("config/dockerfile.yml"), symbolize_names: true)[:options] @@ -160,10 +163,13 @@ desc: "include SQL server libraries" class_option :litefs, type: :boolean, default: OPTION_DEFAULTS.litefs, desc: "replicate sqlite3 databases using litefs" + class_option :litestream, type: :boolean, default: OPTION_DEFAULTS.litestream, + desc: "replicate sqlite3 databases using litesream" + class_option :tigris, type: :boolean, default: OPTION_DEFAULTS.tigris, desc: "configure active storage to use tigris" class_option :postgresql, aliases: "--postgres", type: :boolean, default: OPTION_DEFAULTS.postgresql, desc: "include postgresql libraries" @@ -344,10 +350,14 @@ template "litefs.yml.erb", "config/litefs.yml" fly_attach_consul end + if using_litestream? + template "litestream.rake.erb", "lib/tasks/litestream.rake" + end + if File.exist?("fly.toml") && (fly_processes || !options.prepare || options.swap || deploy_database == "sqlite3") if File.stat("fly.toml").size > 0 template "fly.toml.erb", "fly.toml" else toml = fly_make_toml @@ -486,10 +496,14 @@ def using_litestack? @gemfile.include?("litestack") end + def using_litestream? + options.litestream? + end + def using_node? return @using_node if @using_node != nil return if using_bun? @using_node = File.exist?("package.json") end @@ -592,10 +606,14 @@ if options.mysql? || @mysql system "bundle add mysql2 --skip-install" unless has_mysql_gem? end + if options.litestream? + system "bundle add litestream --skip-install" unless @gemfile.include? "litestream" + end + if options.redis? || using_redis? system "bundle add redis --skip-install" unless @gemfile.include? "redis" end if options.tigris? @@ -660,23 +678,34 @@ def alpinize(packages) packages.map { |package| ALPINE_MAPPINGS[package] || package }.sort.uniq end def base_packages - packages = [] + packages = %w(curl) # work with the default healthcheck strategy in Kamal packages += @@packages["base"] if @@packages["base"] + packages << "libjemalloc2" if options.jemalloc? && !options.fullstaq? + + # start with databases: sqlite3, postgres, mysql + packages << "postgresql-client" if options.postgresql? || @postgresql + packages << "default-mysql-client" if options.mysql? || @mysql + packages << "freetds-bin" if options.sqlserver? || @sqlserver + if options.sqlite3? || @sqlite3 + packages << "sqlite3" unless packages.include? "sqlite3" + end + + # ActiveStorage preview support + packages << "libvips" if @gemfile.include? "ruby-vips" + if using_execjs? if node_version == "lts" packages += %w(nodejs npm) - else - packages += %w(curl) end end if using_puppeteer? - packages += %w(curl gnupg) + packages += %w(gnupg) end # charlock_holmes. Placed here as the library itself is # libicu63 in buster, libicu67 in bullseye, libiclu72 in bookworm... packages << "libicu-dev" if @gemfile.include? "charlock_holmes" @@ -723,22 +752,19 @@ end # add git if needed to install gems packages << "git" if @git - # ActiveStorage preview support - packages << "libvips" if @gemfile.include? "ruby-vips" - # Rmagick gem packages += %w[pkg-config libmagickwand-dev] if @gemfile.include? "rmagick" # node support, including support for building native modules if using_node? packages += %w(node-gyp pkg-config) unless using_execjs? || using_puppeteer? - packages << "curl" + # packages << "curl" end # module build process depends on Python, and debian changed # how python is installed with the bullseye release. Below # is based on debian release included with the Ruby images on @@ -760,33 +786,24 @@ packages << "python" end end if using_bun? - packages += %w(curl unzip) + packages += %w(unzip) end 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 += @@packages["deploy"] if @@packages["deploy"] - # start with databases: sqlite3, postgres, mysql - packages << "postgresql-client" if options.postgresql? || @postgresql - packages << "default-mysql-client" if options.mysql? || @mysql - packages << "freetds-bin" if options.sqlserver? || @sqlserver - packages << "libjemalloc2" if options.jemalloc? && !options.fullstaq? - if options.sqlite3? || @sqlite3 - packages << "libsqlite3-0" unless packages.include? "sqlite3" - end - # litefs packages += ["ca-certificates", "fuse3", "sudo"] if options.litefs? # ActiveStorage preview support packages << "libvips" if @gemfile.include? "ruby-vips" @@ -863,11 +880,11 @@ def base_repos repos = [] packages = [] if using_passenger? - packages += %w(gnupg curl) + packages += %w(curl gnupg) repos += [ "curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt |", " gpg --dearmor > /etc/apt/trusted.gpg.d/phusion.gpg &&", "bash -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger $(source /etc/os-release; echo $VERSION_CODENAME) main > /etc/apt/sources.list.d/passenger.list'" ] @@ -889,11 +906,11 @@ def deploy_repos repos = [] packages = [] if using_puppeteer? && deploy_packages.include?("google-chrome-stable") - packages += %w(gnupg curl) + packages += %w(gnupg) repos += [ "curl https://dl-ssl.google.com/linux/linux_signing_key.pub |", " gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg &&", 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list' ] @@ -977,12 +994,12 @@ if options.yjit? env["RUBY_YJIT_ENABLE"] = "1" end if options.jemalloc? && !options.fullstaq? - env["LD_PRELOAD"] = "libjemalloc.so.2" - env["MALLOC_CONF"] = "dirty_decay_ms:1000,narenas:2,background_thread:true" + # env["LD_PRELOAD"] = "libjemalloc.so.2" + # env["MALLOC_CONF"] = "dirty_decay_ms:1000,narenas:2,background_thread:true" end if using_puppeteer? env["GROVER_NO_SANDBOX"] = "true" if @gemfile.include? "grover" env["PUPPETEER_RUBY_NO_SANDBOX"] = "1" if @gemfile.include? "puppeteer-ruby" @@ -1131,10 +1148,34 @@ else "sqlite3" end end + def start_command + if !options.procfile.blank? + ["foreman", "start", "--procfile=#{options.procfile}"] + elsif procfile.size > 1 + ["foreman", "start", "--procfile=Procfile.prod"] + else + command = Shellwords.split(procfile.values.first) + + if command.first == "./bin/thrust" + command[1..] + else + command + end + end + end + + def shellescape(string) + if %r{\A[-\w._/= ]+\z}.match?(string) + string.inspect + else + Shellwords.escape(string) + end + end + def node_version return unless using_node? || using_execjs? version = nil @@ -1250,10 +1291,14 @@ base = { rails: "./bin/rails server" } end + if using_litestream? && base[:rails] + base[:rails] = "./bin/rake litestream:run " + base[:rails] + end + if solidq_launcher == :procfile base["solidq"] = "bundle exec rake solid_queue:start" end base @@ -1261,10 +1306,14 @@ def using_thruster? options.thruster? || @gemfile.include?("thruster") end + def using_kamal? + @gemfile.include?("kamal") + end + def fly_processes return unless File.exist? "fly.toml" return unless using_sidekiq? || using_solidq? || using_thruster? if procfile.size > 1 @@ -1464,9 +1513,13 @@ list = fly_processes if list if using_thruster? primary = list.keys.first list[primary] = list[primary].sub(/^.*thrust /, "") + end + + if using_litestream? && list["app"] + list["app"] = "./bin/rake litestream:run #{list["app"]}" end if toml.include? "[processes]" toml.sub!(/\[processes\].*?(\n\n|\n?\z)/m, "[processes]\n" + list.map { |name, cmd| " #{name} = #{cmd.inspect}" }.join("\n") + '\1')