mirror of https://github.com/docusealco/docuseal
				
				
				
			
							parent
							
								
									9539c476c0
								
							
						
					
					
						commit
						3034c00bb3
					
				| @ -0,0 +1,46 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | if ENV['RAILS_ENV'] == 'production' && ENV['SECRET_KEY_BASE'].to_s.empty? | ||||||
|  |   require 'dotenv' | ||||||
|  |   require 'securerandom' | ||||||
|  | 
 | ||||||
|  |   dotenv_path = "#{ENV.fetch('WORKDIR', '.')}/docuseal.env" | ||||||
|  | 
 | ||||||
|  |   unless File.exist?(dotenv_path) | ||||||
|  |     default_env = <<~TEXT | ||||||
|  |       DATABASE_URL= # keep empty to use sqlite or specify postgresql database URL | ||||||
|  |       SECRET_KEY_BASE=#{SecureRandom.hex(64)} | ||||||
|  |     TEXT | ||||||
|  | 
 | ||||||
|  |     File.write(dotenv_path, default_env) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   database_url = ENV.fetch('DATABASE_URL', nil) | ||||||
|  | 
 | ||||||
|  |   Dotenv.load(dotenv_path) | ||||||
|  | 
 | ||||||
|  |   ENV['DATABASE_URL'] = ENV['DATABASE_URL'].to_s.empty? ? database_url : ENV.fetch('DATABASE_URL', nil) | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | if ENV['DATABASE_URL'].to_s.split('@').last.to_s.split('/').first.to_s.include?('_') | ||||||
|  |   require 'addressable' | ||||||
|  | 
 | ||||||
|  |   url = Addressable::URI.parse(ENV.fetch('DATABASE_URL', '')) | ||||||
|  | 
 | ||||||
|  |   ENV['DATABASE_HOST'] = url.host | ||||||
|  |   ENV['DATABASE_PORT'] = (url.port || 5432).to_s | ||||||
|  |   ENV['DATABASE_USER'] = url.user | ||||||
|  |   ENV['DATABASE_PASSWORD'] = url.password | ||||||
|  |   ENV['DATABASE_NAME'] = url.path.to_s.delete_prefix('/') | ||||||
|  | 
 | ||||||
|  |   ENV.delete('DATABASE_URL') | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | if ENV['REDIS_URL'].to_s.empty? | ||||||
|  |   require 'digest' | ||||||
|  | 
 | ||||||
|  |   redis_password = Digest::SHA1.hexdigest("redis#{ENV.fetch('SECRET_KEY_BASE', '')}") | ||||||
|  | 
 | ||||||
|  |   ENV['REDIS_URL'] = "redis://default:#{redis_password}@0.0.0.0:6379/0" | ||||||
|  |   ENV['LOCAL_REDIS_URL'] = ENV.fetch('REDIS_URL', nil) | ||||||
|  | end | ||||||
| @ -1,16 +1,14 @@ | |||||||
| # frozen_string_literal: true | # frozen_string_literal: true | ||||||
| 
 | 
 | ||||||
| if defined?(Sidekiq) | require 'sidekiq/web' if defined?(Puma) | ||||||
|   require 'sidekiq/web' |  | ||||||
| 
 | 
 | ||||||
|  | if !ENV['SIDEKIQ_BASIC_AUTH_PASSWORD'].to_s.empty? && defined?(Sidekiq::Web) | ||||||
|   Sidekiq::Web.use(Rack::Auth::Basic) do |_, password| |   Sidekiq::Web.use(Rack::Auth::Basic) do |_, password| | ||||||
|     next true if Rails.env.development? |  | ||||||
| 
 |  | ||||||
|     ActiveSupport::SecurityUtils.secure_compare( |     ActiveSupport::SecurityUtils.secure_compare( | ||||||
|       Digest::SHA256.hexdigest(password), |       Digest::SHA256.hexdigest(password), | ||||||
|       Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_BASIC_AUTH_PASSWORD')) |       Digest::SHA256.hexdigest(ENV.fetch('SIDEKIQ_BASIC_AUTH_PASSWORD')) | ||||||
|     ) |     ) | ||||||
|   end |   end | ||||||
| 
 |  | ||||||
|   Sidekiq.strict_args! |  | ||||||
| end | end | ||||||
|  | 
 | ||||||
|  | Sidekiq.strict_args! | ||||||
|  | |||||||
| @ -0,0 +1,70 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | require 'puma/plugin' | ||||||
|  | 
 | ||||||
|  | # rubocop:disable Metrics | ||||||
|  | Puma::Plugin.create do | ||||||
|  |   def start(launcher) | ||||||
|  |     return if ENV['LOCAL_REDIS_URL'].to_s.empty? | ||||||
|  | 
 | ||||||
|  |     @puma_pid = $PROCESS_ID | ||||||
|  | 
 | ||||||
|  |     launcher.events.on_booted do | ||||||
|  |       @redis_server_pid = fork_redis | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     in_background { monitor_redis } | ||||||
|  | 
 | ||||||
|  |     at_exit do | ||||||
|  |       stop_redis_server if Process.pid == @puma_pid | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     launcher.events.on_stopped { stop_redis_server } | ||||||
|  |     launcher.events.on_restart { stop_redis_server } | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def monitor_redis | ||||||
|  |     loop do | ||||||
|  |       if redis_dead? | ||||||
|  |         Process.kill(:INT, @puma_pid) | ||||||
|  | 
 | ||||||
|  |         break | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       sleep 5 | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def redis_dead? | ||||||
|  |     return false unless @redis_server_pid | ||||||
|  | 
 | ||||||
|  |     Process.waitpid(@redis_server_pid, Process::WNOHANG) | ||||||
|  | 
 | ||||||
|  |     false | ||||||
|  |   rescue Errno::ECHILD, Errno::ESRCH | ||||||
|  |     true | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def fork_redis | ||||||
|  |     fork do | ||||||
|  |       Process.setsid | ||||||
|  | 
 | ||||||
|  |       Dir.chdir(ENV.fetch('WORKDIR', nil)) unless ENV['WORKDIR'].to_s.empty? | ||||||
|  | 
 | ||||||
|  |       exec('redis-server', '--requirepass', Digest::SHA1.hexdigest("redis#{ENV.fetch('SECRET_KEY_BASE', '')}"), | ||||||
|  |            out: '/dev/null') | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def stop_redis_server | ||||||
|  |     if @redis_server_pid | ||||||
|  |       Process.kill(:INT, @redis_server_pid) | ||||||
|  |       Process.wait(@redis_server_pid) | ||||||
|  |     end | ||||||
|  |   rescue Errno::ECHILD, Errno::ESRCH | ||||||
|  |     nil | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | # rubocop:enable Metrics | ||||||
| @ -0,0 +1,74 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | require 'puma/plugin' | ||||||
|  | 
 | ||||||
|  | # rubocop:disable Metrics | ||||||
|  | Puma::Plugin.create do | ||||||
|  |   def config(cfg) | ||||||
|  |     return if cfg.instance_variable_get(:@options)[:workers] <= 0 | ||||||
|  | 
 | ||||||
|  |     cfg.on_worker_boot { start_sidekiq! } | ||||||
|  | 
 | ||||||
|  |     cfg.on_worker_shutdown { @sidekiq&.stop } | ||||||
|  |     cfg.on_refork { @sidekiq&.stop } | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def start(launcher) | ||||||
|  |     launcher.events.on_booted do | ||||||
|  |       next if Puma.stats_hash[:workers].to_i != 0 | ||||||
|  | 
 | ||||||
|  |       start_sidekiq! | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     launcher.events.on_stopped { Thread.new { @sidekiq&.stop }.join } | ||||||
|  |     launcher.events.on_restart { Thread.new { @sidekiq&.stop }.join } | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def fire_event(config, event) | ||||||
|  |     arr = config[:lifecycle_events][event] | ||||||
|  | 
 | ||||||
|  |     arr.each(&:call) | ||||||
|  | 
 | ||||||
|  |     arr.clear | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def start_sidekiq! | ||||||
|  |     Thread.new do | ||||||
|  |       wait_for_redis! | ||||||
|  | 
 | ||||||
|  |       configs = Sidekiq.configure_embed do |config| | ||||||
|  |         config.logger.level = Logger::INFO | ||||||
|  |         sidekiq_config = YAML.load_file('config/sidekiq.yml') | ||||||
|  |         config.queues = sidekiq_config['queues'] | ||||||
|  |         config.concurrency = ENV.fetch('SIDEKIQ_THREADS', 5).to_i | ||||||
|  |         config.merge!(sidekiq_config) | ||||||
|  |         config[:max_retries] = 13 | ||||||
|  | 
 | ||||||
|  |         ActiveSupport.run_load_hooks(:sidekiq_config, config) | ||||||
|  |       end.instance_variable_get(:@config) | ||||||
|  | 
 | ||||||
|  |       @sidekiq = Sidekiq::Launcher.new(configs, embedded: true) | ||||||
|  | 
 | ||||||
|  |       @sidekiq.run | ||||||
|  | 
 | ||||||
|  |       fire_event(configs, :startup) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def wait_for_redis! | ||||||
|  |     attempt = 0 | ||||||
|  | 
 | ||||||
|  |     loop do | ||||||
|  |       attempt += 1 | ||||||
|  | 
 | ||||||
|  |       sleep (attempt - 1) / 10.0 | ||||||
|  | 
 | ||||||
|  |       RedisClient.new(url: ENV.fetch('REDIS_URL', nil)).call('GET', '1') | ||||||
|  | 
 | ||||||
|  |       break | ||||||
|  |     rescue RedisClient::CannotConnectError | ||||||
|  |       raise('Unable to connect to redis') if attempt > 10 | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | # rubocop:enable Metrics | ||||||
					Loading…
					
					
				
		Reference in new issue