Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature add render.com support #678

Merged
merged 6 commits into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ Metrics/PerceivedComplexity:
Rails:
Enabled: true

Rails/UnknownEnv:
Environments:
- production
- development
- staging
- test

require:
- rubocop-performance
- rubocop-rails
Expand Down
7 changes: 5 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ gem 'valid_email2'
gem 'wicked_pdf'
gem 'wkhtmltopdf-binary'

group :development, :staging, :test do
gem 'faker'
end

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platforms: %i[mri mingw x64_mingw]
gem 'faker'
# Use sqlite3 as the database for Active Record
gem 'factory_bot_rails'
gem 'rubocop-performance'
Expand Down Expand Up @@ -115,6 +118,6 @@ end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]

group :production do
group :production, :staging do
gem 'pg'
end
54 changes: 53 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,59 @@ heroku config:set RAILS_LOG_TO_STDOUT=enabled
heroku config:set [email protected]
```

Configure reCAPTCHA for prodaction:
## Deploy to render.com
<details><summary>INFO IS HERE</summary>

* Go to https://dashboard.render.com
* Add New PostgreSQL with YOUR_CUSTOM_NAME_PG and select Region
* Add New Web Service with link to your repo clone\
select:
* YOUR_CUSTOM_NAME_CV
* same Region
* Runtime: Ruby
* Build Command - "./bin/render-build.sh"
* Start Command - "./bin/render-start.sh"
* Go to YOUR_CUSTOM_NAME_PG PostgreSQL -> Info and copy `Internal Database URL`

* Go to YOUR_CUSTOM_NAME_CV app -> Environment
* Environment Variables, by one\
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Привет! Извини что так долго не приходили! вот здесь все таки стоит указать набор пременных окружения не обходимых для деплоя, если человек их будет через web интерфейс
EMAIL_FROM= любой email существующий в базе
EMAIL_SPECIAL_USER= любой email существующий в базе
HABR_ACCESS_TOKEN = любой набор символо
HOST= адрес хоста который выдается на рендере без указания протокола

еще надо бы добавить что пред деплоем нало сконфигурировать файл puma.rb для рендер, например как это описанно здесь https://render.com/docs/deploy-rails

Copy link
Contributor Author

@qsimpleq qsimpleq Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

На бесплатном варианте нет доступа к консоли. Поэтому нужно все эти правки сразу в код вносить (я про puma.rb)

Copy link
Contributor Author

@qsimpleq qsimpleq Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Переменные желательно всё же вынести в отдельный блок документации и нормально описать все имеющиеся.

А тут я перечислил только те, что необходимы для запуска на render.com

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Конкретно для Render.com я бы вынес необходимое в конфиге puma.rb в блок

if ENV['RENDER'].present?
  pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
  workers ENV.fetch("WEB_CONCURRENCY") { 4 }
  preload_app!
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А тут я перечислил только те, что необходимы для запуска на render.com

а без переменной HOST будет возможен запуск?) изначально когда генерится env там HOST=localhos, человек который будет разворачивать ее допустим не установит и у него при переходе по адресу который сгенерит рендер будет localhos открыватся

EMAIL_SPECIAL_USER - без вот этой пременной главня страница упадет с ошибкой,

HABR_ACCESS_TOKEN - без вот этой деплой упадет

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Переменные желательно всё же вынести в отдельный блок документации и нормально описать все имеющиеся.

все в ваших руках это opensource)))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Конкретно для Render.com я бы вынес необходимое в конфиге puma.rb в блок

if ENV['RENDER'].present?
  pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
  workers ENV.fetch("WEB_CONCURRENCY") { 4 }
  preload_app!
end

да можно так

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да, без HOST не запустится. Всё верно, это я уже поправил.

Я имел ввиду вынести описание всех используемых переменных окружения в отдельный блок README
Незачем их в деплое для render описывать

Copy link
Contributor

@usernaimandrey usernaimandrey Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

так я не предлагаю все только те что не обходимы для деплоя

or
* Secret Files .env with your settings, based on .env.example and add this variables:
* DATABASE_URL
```shell
echo "DATABASE_URL=Internal Database URL" >> .env
```
* RACK_ENV and RAILS_ENV
```shell
echo "RACK_ENV=staging" >> .env
echo "RAILS_ENV=staging" >> .env
```
usernaimandrey marked this conversation as resolved.
Show resolved Hide resolved
* RENDER_LOAD_FIXTURES to load fixtures
```shell
echo "RENDER_LOAD_FIXTURES=1" >> .env
```
Generate new master.key if the original is missing
* RAILS_MASTER_KEY
```shell
export RAILS_MASTER_KEY="$(ruby -r securerandom -e 'print SecureRandom.hex(16)')"
# printf $RAILS_MASTER_KEY > master.key
echo "RAILS_MASTER_KEY=$RAILS_MASTER_KEY" >> .env
```
* SECRET_KEY_BASE
```shell
echo "SECRET_KEY_BASE=$(rake secret)" >> .env
```
* CREDENTIALS_CLEAR, to remove original config/credentials.yml.enc on render.com
```shell
echo "CREDENTIALS_CLEAR=1" >> .env
```

* You can deploy app
</details>

---

Configure reCAPTCHA for production:

* Follow the link [reCAPTCHA](https://www.google.com/recaptcha)
* Log into Admin Console with your credentials or create a new Google Account in case you don't have one
Expand Down
18 changes: 18 additions & 0 deletions bin/render-build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# exit on error
set -o errexit

source "$(dirname $0)/render_lib.sh" && load_dotenv_file

test -n $CREDENTIALS_CLEAR && test -f config/credentials.yml.enc && rm config/credentials.yml.enc && echo CREDENTIALS_CLEAR
usernaimandrey marked this conversation as resolved.
Show resolved Hide resolved
echo "$RAILS_MASTER_KEY" > config/master.key

bundle install
npm install
npm run build

bundle exec rake assets:precompile
bundle exec rake assets:clean

./bin/rails db:prepare
./bin/rails db:seed
7 changes: 7 additions & 0 deletions bin/render-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash
# exit on error
set -o errexit

source "$(dirname $0)/render_lib.sh" && load_dotenv_file
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

еще подскажи если тот кто будет деплоить добавит прерменные через web интерфейс этот запуск сработает?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Только если добавит файл с переменными там же в интерфейсе

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я думаю об этом надо было сказать и команду для старта прописать

Только если добавит файл с переменными там же в интерфейсе

вот тут не понял, знаю что там можно файлик подгрузить через интерфейс рендера, а твоим способом он как то по другому попадет?

Copy link
Contributor Author

@qsimpleq qsimpleq Oct 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Файлы там складируются по пути /etc/secrets/filename, оттуда и загружаю

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Файлы там складируются по пути /etc/secrets/filename, оттуда и загружаю

так они там просто так же не берутся), их туда загрузить тот кто деплоит, а по инструкции это не очень понятно

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Может сегодня напрямую спишемся минут на 5?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Да можно, но только давай уже завтра можешь меня mattermost найти @farmacevt


bundle exec puma -C config/puma.rb
12 changes: 12 additions & 0 deletions bin/render_lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
# exit on error
set -o errexit

function load_dotenv_file() {
current_dir="$(pwd)";
script_dir="$(dirname $0)";
cd "$script_dir"
export DOTENV_FILE='/etc/secrets/env'
if [ -f "$DOTENV_FILE" ]; then export $(sed '/^\s*$/d; /^[[:space:]]*#/d' "$DOTENV_FILE"); fi
cd $current_dir
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

а для чего вот это? В рендер можно использовать обычные переменные окружения.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно свой .env файл загрузить просто и не мучаться с этими переменными

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

да там и так, и через web интерфейс можно их натыкать, но через скрипт меньше ручной работы, тем более .env автоматом генерируется, главное чтобы не забыли в нем значения прописать

11 changes: 8 additions & 3 deletions config/cable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ development:
adapter: redis
url: redis://localhost:6379/1

test:
adapter: test

production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: hexlet_cv_production

staging:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: hexlet_cv_staging

test:
adapter: test
5 changes: 5 additions & 0 deletions config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ production:
adapter: postgresql
<<: *default
url: <%= ENV['DATABASE_URL'] %>

staging:
adapter: postgresql
<<: *default
url: <%= ENV['DATABASE_URL'] %>
125 changes: 125 additions & 0 deletions config/environments/staging.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
# frozen_string_literal: true

Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.

# Code is not reloaded between requests.
config.cache_classes = true

# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true

# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true

# Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
# or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
# config.require_master_key = true

# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? || ENV['RENDER'].present?

# Compress CSS using a preprocessor (compress with webpack).
config.assets.css_compressor = Class.new { def self.compress(str) str end } # rubocop:disable Style/SingleLineMethods

# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false

# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'

# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX

# Store uploaded files on the local file system (see config/storage.yml for options).
config.active_storage.service = :local

# Mount Action Cable outside main process or domain.
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]

# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
config.force_ssl = true

# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug

# Prepend all log lines with the following tags.
config.log_tags = [:request_id]

# Use a different cache store in production.
# config.cache_store = :mem_cache_store

# Use a real queuing backend for Active Job (and separate queues per environment).
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "hexlet_cv_production"

config.action_mailer.perform_caching = false
config.action_mailer.default_url_options = { host: ENV.fetch('HOST') }
config.action_mailer.deliver_later_queue_name = 'default_mailer_queue'

# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false

# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true

# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify

# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = Logger::Formatter.new

# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')

if ENV['RAILS_LOG_TO_STDOUT'].present?
logger = ActiveSupport::Logger.new($stdout)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end

# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false

# Inserts middleware to perform automatic connection switching.
# The `database_selector` hash is used to pass options to the DatabaseSelector
# middleware. The `delay` is used to determine how long to wait after a write
# to send a subsequent read to the primary.
#
# The `database_resolver` class is used by the middleware to determine which
# database is appropriate to use based on the time delay.
#
# The `database_resolver_context` class is used by the middleware to set
# timestamps for the last write to the primary. The resolver uses the context
# class timestamps to determine how long to wait before reading from the
# replica.
#
# By default Rails will store a last write timestamp in the session. The
# DatabaseSelector middleware is designed as such you can define your own
# strategy for connection switching and pass that into the middleware through
# these configuration options.
# config.active_record.database_selector = { delay: 2.seconds }
# config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver
# config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session
ActionMailer::Base.smtp_settings = {
user_name: 'SMTP_Injection',
password: Rails.application.credentials.sparkpost_key,
address: 'smtp.sparkpostmail.com',
port: 587,
enable_starttls_auto: true,
format: :html,
from: '[email protected]'
}
end
5 changes: 0 additions & 5 deletions db/migrate/20230424111451_add_uniq_index_to_career_items.rb

This file was deleted.

13 changes: 0 additions & 13 deletions db/migrate/20230503134755_create_career_step.rb

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

5 changes: 0 additions & 5 deletions db/migrate/20230503140032_drop_table_steps.rb

This file was deleted.

5 changes: 5 additions & 0 deletions db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)

if Rails.env.staging? && ENV['RENDER']&.to_i&.positive? && ENV['RENDER_LOAD_FIXTURES']&.to_i&.positive?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

я думаю мы это будем использовать только на рендере и только на staging
if Rails.env.staging? && ENV['render'].present? будет достаточно

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Отладка варианта production на рендер, как вариант, но можно и убрать

require_relative 'seeds/render_load_fixtures'
render_load_fixtures
end
Loading