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
|
||||||
@ -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