diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..d817069 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,5 @@ +.git +.dockerignore +.byebug_history +log/* +tmp/* \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0254eab..e550422 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ /vendor/bundle/ /vendor/ruby/ /node_modules +/docker/ssl_keys # minimal Rails specific artifacts diff --git a/Gemfile b/Gemfile index 08cfd34..334fe4a 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ gem 'bootstrap', '~> 4.0.0' gem 'jquery-rails' gem 'bourbon' gem 'foreman' +gem 'rails_12factor', group: :production gem 'dotenv' gem 'coffee-rails', '~> 4.2' gem 'devise' diff --git a/Gemfile.lock b/Gemfile.lock index 6247f42..b1b76ac 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -270,7 +270,12 @@ GEM nokogiri (>= 1.6) rails-html-sanitizer (1.0.4) loofah (~> 2.2, >= 2.2.2) + rails_12factor (0.0.3) + rails_serve_static_assets + rails_stdout_logging rails_layout (1.0.42) + rails_serve_static_assets (0.0.5) + rails_stdout_logging (0.0.5) railties (5.2.1) actionpack (= 5.2.1) activesupport (= 5.2.1) @@ -429,6 +434,7 @@ DEPENDENCIES puma (~> 3.11) pundit rails (~> 5.2.0) + rails_12factor rails_layout rspec-rails sass-rails (~> 5.0) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 6274a2b..fcda9cc 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -15,8 +15,6 @@ //= require popper //= require bootstrap-sprockets //= require moment -////= require select2/dist/js/select2.full.js -//= require chart.js/dist/Chart.js //= require cable //= require moment //= require jquery diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss index ae55bc4..10d3c59 100644 --- a/app/assets/stylesheets/application.css.scss +++ b/app/assets/stylesheets/application.css.scss @@ -11,7 +11,6 @@ * It is generally better to create a new file per style scope. * *= require fullcalendar - //*= require select2/dist/css/select2.css *= require_tree . *= require_self @@ -32,14 +31,14 @@ } .main.ui.container { -//#main-container { + //#main-container { display: flex; flex-flow: row nowrap; justify-content: center; } .ui.raised.container.segment { -//#container-segment { + //#container-segment { margin-top: 23px; margin-right: auto !important; margin-left: auto !important; @@ -52,7 +51,7 @@ margin-left: 210px; } -@media only screen and (max-width: 1520px) { +@media only screen and (max-width: 1144px) { #fixed-sidebar { display: none; } @@ -77,7 +76,7 @@ } } -@media only screen and (min-width: 1521px) { +@media only screen and (min-width: 1145px) { #fixed-sidebar { display: flex; } diff --git a/app/controllers/trainings_controller.rb b/app/controllers/trainings_controller.rb index ecca016..f39a8f2 100644 --- a/app/controllers/trainings_controller.rb +++ b/app/controllers/trainings_controller.rb @@ -8,13 +8,26 @@ class TrainingsController < ApplicationController # protect_from_forgery with: :null_session skip_before_action :verify_authenticity_token, only: %i[join_clients exercises] + def index + @training = Training.where(user_id: current_user.id).map do |training| + { + name: Client.find_by(id: training.client_id).full_name, + training: training + } + end + end + + def show + @name = Client.find_by(id: @training.client_id).full_name + @sets = kit_constructor + end + def new @clients = current_user.clients (current_user.trainings.find_by(status: 0))&.delete + @date = params[:date] training = current_user.trainings.build redirect_url calendar_path, alert: "Couldn't create training" unless training.save - @date = params[:date] - @training = current_user.trainings.build end def join_clients @@ -52,22 +65,15 @@ def exercises render layout: false end - def show - authorize @training - @name = Client.find_by(id: @training.client_id).full_name - @sets = kit_constructor - end - def client_list current_user.clients.map do |client| - # Client.where(user_id: user).map do |client| + # Client.where(user_id: user).map do |client| [client.first_name + ' ' + client.second_name, client.id] end end def create @training = current_user.trainings.build(training_params) - authorize @training if @training.save calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin @@ -84,13 +90,13 @@ def create end_time = start_time + 2.hours summary = Client.find_by(id: @training.client_id).full_name event = Google::Apis::CalendarV3::Event.new( - id: 'training' + @training.id.to_s + 'fitfree1asslcom', - start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339), - end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339), - summary: summary, - description: @training.description - ) - service.insert_event(calendar_id, event) + id: 'training' + @training.id.to_s + 'fitfree1asslcom', + start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339), + end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339), + summary: summary, + description: @training.description + ) + service.insert_event(calendar_id, event) end rescue Google::Apis::AuthorizationError response = client.refresh! @@ -105,7 +111,6 @@ def create end def edit - authorize @training @list = client_list @name = name(@training) @sets = sets(@training, current_user) @@ -113,7 +118,6 @@ def edit def update @training.update(status: :planned) - authorize @training if @training.update(training_params) calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin @@ -130,11 +134,11 @@ def update end_time = start_time + 2.hours summary = Client.find_by(id: @training.client_id).full_name event = Google::Apis::CalendarV3::Event.new( - start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339), - end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339), - summary: summary, - description: @training.description - ) + start: Google::Apis::CalendarV3::EventDateTime.new(date_time: (start_time - 3.hours).to_datetime.rfc3339), + end: Google::Apis::CalendarV3::EventDateTime.new(date_time: (end_time - 3.hours).to_datetime.rfc3339), + summary: summary, + description: @training.description + ) if service.get_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom') service.patch_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom', event) end @@ -157,12 +161,10 @@ def update end def cancel - authorize @training @training.update(status: :canceled) end def destroy - authorize @training calendar_id = Calendar.find_by(user_id: current_user.id).calendar_id begin if calendar_id @@ -178,14 +180,14 @@ def destroy service.delete_event(calendar_id, 'training' + @training.id.to_s + 'fitfree1asslcom') end end + TrainingsHelper::BackgroundProccess.delete_background_proc(@training.id) if @training.status == :planned + @training.destroy + redirect_to calendar_index_path rescue Google::Apis::AuthorizationError response = client.refresh! session[:authorization] = session[:authorization].merge(response) retry end - TrainingsHelper::BackgroundProccess.delete_background_proc(@training.id) if @training.status == :planned - @training.destroy - redirect_to calendar_index_path end private @@ -216,8 +218,8 @@ def create_background_proc(training_id) def kit_constructor sets = Kit.where(training_id: @training.id, user_id: current_user.id).map do |kit| { - exercises: Exercise.where(kit_id: kit.id, user_id: current_user.id), - kit: kit + exercises: Exercise.where(kit_id: kit.id, user_id: current_user.id), + kit: kit } end sets.each do |kit| diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index de67dd2..c44ca30 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -28,7 +28,7 @@ <%= t('navigation.clients') %> - + <%= t('navigation.settings') %> @@ -55,7 +55,7 @@ <%= t('navigation.clients') %> - + <%= t('navigation.settings') %> diff --git a/app/views/payments/index.html.slim b/app/views/payments/index.html.slim index 17d1297..569d4e0 100644 --- a/app/views/payments/index.html.slim +++ b/app/views/payments/index.html.slim @@ -1,6 +1,6 @@ = render 'clients/navbar', active_section: :payments -.ui.container +.main.ui.container /todo: change depends screen size => .html.ui.top.attached.segment .ui.raised.container.segment .ui.top.attached.label @@ -21,11 +21,22 @@ td.Date = payment.datetime.strftime("%B %d, %Y") td.Price = payment.price td.right.aligned.Cancel: button.negative.ui.button [onclick="document.location.replace('#{'payments/' + payment.id.to_s + '/delete'}')"] Ⓧ - center - .pagniation-wrapper align="center" - = paginate @payments_list - button.positive.ui.button [onclick="window.location='payments/create';"] #{t('.add')} - + tfoot + tr + th colspan="3" + button.positive.ui.button [onclick="window.location='payments/create';"] Add + .ui.right.floated.pagination.menu + a.icon.item + i.left.chevron.icon + a.item 1 + a.item 2 + a.item 3 + a.item 4 + a.icon.item + i.right.chevron.icon - else h4 #{t('payments.index.no_payments')} - button.positive.ui.button [type="submit" onclick="window.location='payments/create';"] #{t('.add')} \ No newline at end of file + button.positive.ui.button [type="submit" onclick="window.location='payments/create';"] #{t('payments.index.add')} + /todo: make pagination + = paginate @payments_list, + previous_label: 'Previous', next_label: 'Next', inner_window: 1, outer_window: 0 \ No newline at end of file diff --git a/config/application.rb b/config/application.rb index 7ba4599..8d4a4a4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -29,7 +29,7 @@ class Application < Rails::Application config.i18n.default_locale = :en # Initialize configuration defaults for originally generated Rails version. config.load_defaults 5.2 - config.active_job.queue_adapter = Rails.env.production? ? :sidekiq : :async + config.active_job.queue_adapter = :sidekiq # Settings in config/environments/* take precedence over those specified here. # Application configuration can go into files in config/initializers # -- all .rb files in that directory are automatically loaded after loading diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 57930f9..9bef71d 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -3,11 +3,17 @@ Sidekiq.configure_client do |config| # accepts :expiration (optional) + config.redis = { + url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" + } Sidekiq::Status.configure_client_middleware config, expiration: 30.minutes end Sidekiq.configure_server do |config| # accepts :expiration (optional) + config.redis = { + url: "redis://#{ENV["REDIS_HOST"]}:#{ENV["REDIS_PORT"]}" + } Sidekiq::Status.configure_server_middleware config, expiration: 30.minutes # accepts :expiration (optional) diff --git a/config/secrets.yml b/config/secrets.yml index 8945aaf..efe5aff 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -38,7 +38,7 @@ test: production: admin_name: <%= ENV["ADMIN_NAME"] %> admin_email: <%= ENV["ADMIN_EMAIL"] %> - admin_password: <%= ENV["ADMIN_PASSWORD"] %> + admin_password: 123456789 email_provider_username: <%= ENV["SENDGRID_USERNAME"] %> email_provider_password: <%= ENV["SENDGRID_PASSWORD"] %> domain_name: <%= ENV["DOMAIN_NAME"] %> diff --git a/db/schema.rb b/db/schema.rb index bda4585..bdbbdc4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -34,13 +34,12 @@ t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.index ["confirmation_token"], name: "index_administrators_on_confirmation_token", unique: true - t.index ["email"], name: "index_administrators_on_email", unique: true - t.index ["reset_password_token"], name: "index_administrators_on_reset_password_token", unique: true end create_table "attachments", force: :cascade do |t| t.integer "message_id" - t.text "path" + t.text "name" + t.integer "status" t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -58,18 +57,18 @@ t.string "second_name", default: "", null: false t.string "phone_number", default: "", null: false t.integer "user_id" - t.integer "price" - t.datetime "birth" - t.string "email" - t.string "instagram_link" - t.string "facebook_link" - t.string "vk_link" - t.integer "status" + t.datetime "birth", default: "2018-09-14 07:48:24", null: false + t.string "email", default: "", null: false + t.string "instagram_link", default: "", null: false + t.string "facebook_link", default: "", null: false + t.string "vk_link", default: "", null: false + t.integer "status", default: 0, null: false + t.integer "price", default: 0, null: false + t.string "telegram_chat_id" + t.string "telegram_bind_id", default: "73e911d9-da46-4354-9a08-086271698cc1" t.integer "gender" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "telegram_chat_id" - t.string "telegram_bind_id", default: "13a4cefa-016e-434b-a25d-1ae406d74abb" t.string "avatar_file_name" t.string "avatar_content_type" t.bigint "avatar_file_size" @@ -111,21 +110,13 @@ end create_table "exercises", force: :cascade do |t| - t.integer "exercise_type_id" + t.bigint "exercise_type_id" t.integer "kit_id" - t.integer "user_id" t.integer "repeats" - t.integer "approach" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "images", force: :cascade do |t| - t.integer "message_id" - t.integer "status" - t.string "name" + t.integer "approaches" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.index ["exercise_type_id"], name: "index_exercises_on_exercise_type_id" end create_table "jobs", force: :cascade do |t| @@ -180,9 +171,9 @@ create_table "metrics", force: :cascade do |t| t.string "name", null: false t.string "units", null: false + t.integer "kind_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "kind_id" end create_table "snapshots", force: :cascade do |t| @@ -193,30 +184,25 @@ t.index ["client_id"], name: "index_snapshots_on_client_id" end - create_table "statuses", force: :cascade do |t| - t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "telegram_bots", force: :cascade do |t| t.bigint "user_id" - t.string "token", default: "", null: false - t.string "telegram_webhook_id", default: "11d6d037-15d1-4394-9485-5c3bb7b470d3", null: false + t.string "name" + t.string "token" + t.string "telegram_webhook_id", default: "f442b4a9-9882-4d20-9265-c20452cddfd4", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["user_id"], name: "index_telegram_bots_on_user_id" end create_table "trainings", force: :cascade do |t| + t.bigint "user_id" t.datetime "time" t.integer "price" t.text "description" - t.integer "user_id" - t.integer "client_id" - t.integer "status", default: 0, null: false + t.integer "status", default: 0 t.datetime "created_at", null: false - t.datetime "updated_at", null: fals + t.datetime "updated_at", null: false + t.index ["user_id"], name: "index_trainings_on_user_id" end create_table "transactions", force: :cascade do |t| @@ -233,7 +219,7 @@ t.string "encrypted_password", default: "", null: false t.string "bot_token" t.string "bot_name" - t.string "bot_webhook_id", default: "b7c5bf6b-a8ea-4cba-ab0d-9216b8a876de", null: false + t.string "telegram_webhook_id", default: "eb4ddba1-640c-4ac1-8070-9be5c7f36b2c", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" @@ -249,11 +235,11 @@ t.datetime "confirmed_at" t.datetime "confirmation_sent_at" t.datetime "blocked_at" - t.integer "role" - t.boolean "birthday_seen" + t.boolean "birthday_seen", default: false, null: false t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true t.index ["email"], name: "index_users_on_email", unique: true t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "jobs", "trainings" end diff --git a/db/seeds.rb b/db/seeds.rb index 422c1e7..173c4e0 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -14,49 +14,50 @@ %w[Приседания Подтягивания].each do |name| Metric.find_or_create_by(name: name, units: 'повторы', kind_id: 1) end -Metric.create(name: 'Жим штанги лёжа', units: 'повторы', kind_id: 1) -Metric.create(name: 'Становая тяга', units: 'повторы', kind_id: 1) +Metric.find_or_create_by(name: 'Жим штанги лёжа', units: 'повторы', kind_id: 1) +Metric.find_or_create_by(name: 'Становая тяга', units: 'повторы', kind_id: 1) puts 'Created strength metrics' -ExerciseType.create(name: 'Bench press with chest standing', description: '') -ExerciseType.create(name: 'Press of dumbbells', description: '') -ExerciseType.create(name: 'Mahi dumbbells in the sides', description: '') -ExerciseType.create(name: 'Pulling the head with a wide grip', description: '') -ExerciseType.create(name: 'Push-ups from the floor with a wide grip', description: '') -ExerciseType.create(name: 'Pressing dumbbells at an angle of 30-40 °', description: '') -ExerciseType.create(name: 'Press the rod at an angle of 30-40 °', description: '') -ExerciseType.create(name: 'Hyperextension', description: '') -ExerciseType.create(name: 'Deadlift on straight legs', description: '') -ExerciseType.create(name: 'Static draft with dumbbells', description: '') -ExerciseType.create(name: 'Pulling up to the chest with a wide grip', description: '') -ExerciseType.create(name: 'Thrust of horizontal block', description: '') -ExerciseType.create(name: 'Thrust T-neck in slope', description: '') -ExerciseType.create(name: 'Pulling in a Smith machine', description: '') -ExerciseType.create(name: 'Thrust from the upper block with a narrow handle', description: '') -ExerciseType.create(name: 'Pull-ups', description: '') -ExerciseType.create(name: 'Bending of arms with a standing post', description: '') -ExerciseType.create(name: 'Bending of hands with dumbbells', description: '') -ExerciseType.create(name: 'Push-ups from the beams on the triceps', description: '') -ExerciseType.create(name: 'Push-ups with a narrow grip from the floor', description: '') -ExerciseType.create(name: 'Press bar with a narrow grip', description: '') -ExerciseType.create(name: 'Flexion of the wrists with the bar sitting', description: '') -ExerciseType.create(name: 'Extension of hands with a bar sitting', description: '') -ExerciseType.create(name: 'Lifting the legs in the vise', description: '') -ExerciseType.create(name: 'Lifting the legs on an incline bench', description: '') -ExerciseType.create(name: 'Twisting on an incline bench', description: '') -ExerciseType.create(name: 'Twisting in a Roman chair', description: '') -ExerciseType.create(name: 'Squats', description: '') -ExerciseType.create(name: 'Impacts with a barbell', description: '') -ExerciseType.create(name: 'Dumbbells with dumbbells', description: '') -ExerciseType.create(name: 'Standing rod standing on a stand', description: '') -ExerciseType.create(name: 'Squats', description: '') -ExerciseType.create(name: 'Squats with a barbell on the chest', description: '') -ExerciseType.create(name: 'Pressing your feet in the machine', description: '') -ExerciseType.create(name: 'Deadlift on straight legs', description: '') -ExerciseType.create(name: 'Leg bending in the machine', description: '') -ExerciseType.create(name: 'Side Effects', description: '') -ExerciseType.create(name: 'Bringing the hip in a crossover', description: '') -ExerciseType.create(name: 'Ascent to the socks in a standing machine', description: '') -ExerciseType.create(name: 'Ascent to the socks in a sitting simulator', description: '') +ExerciseType.find_or_create_by(name: 'Bench press with chest standing', description: '') +ExerciseType.find_or_create_by(name: 'Press of dumbbells', description: '') +ExerciseType.find_or_create_by(name: 'Mahi dumbbells in the sides', description: '') +ExerciseType.find_or_create_by(name: 'Pulling the head with a wide grip', description: '') +ExerciseType.find_or_create_by(name: 'Push-ups from the floor with a wide grip', description: '') +ExerciseType.find_or_create_by(name: 'Pressing dumbbells at an angle of 30-40 °', description: '') +ExerciseType.find_or_create_by(name: 'Press the rod at an angle of 30-40 °', description: '') +ExerciseType.find_or_create_by(name: 'Hyperextension', description: '') +ExerciseType.find_or_create_by(name: 'Deadlift on straight legs', description: '') +ExerciseType.find_or_create_by(name: 'Static draft with dumbbells', description: '') +ExerciseType.find_or_create_by(name: 'Pulling up to the chest with a wide grip', description: '') +ExerciseType.find_or_create_by(name: 'Thrust of horizontal block', description: '') +ExerciseType.find_or_create_by(name: 'Thrust T-neck in slope', description: '') +ExerciseType.find_or_create_by(name: 'Pulling in a Smith machine', description: '') +ExerciseType.find_or_create_by(name: 'Thrust from the upper block with a narrow handle', description: '') +ExerciseType.find_or_create_by(name: 'Pull-ups', description: '') +ExerciseType.find_or_create_by(name: 'Bending of arms with a standing post', description: '') +ExerciseType.find_or_create_by(name: 'Bending of hands with dumbbells', description: '') +ExerciseType.find_or_create_by(name: 'Push-ups from the beams on the triceps', description: '') +ExerciseType.find_or_create_by(name: 'Push-ups with a narrow grip from the floor', description: '') +ExerciseType.find_or_create_by(name: 'Press bar with a narrow grip', description: '') +ExerciseType.find_or_create_by(name: 'Flexion of the wrists with the bar sitting', description: '') +ExerciseType.find_or_create_by(name: 'Extension of hands with a bar sitting', description: '') +ExerciseType.find_or_create_by(name: 'Lifting the legs in the vise', description: '') +ExerciseType.find_or_create_by(name: 'Lifting the legs on an incline bench', description: '') +ExerciseType.find_or_create_by(name: 'Twisting on an incline bench', description: '') +ExerciseType.find_or_create_by(name: 'Twisting in a Roman chair', description: '') +ExerciseType.find_or_create_by(name: 'Squats', description: '') +ExerciseType.find_or_create_by(name: 'Impacts with a barbell', description: '') +ExerciseType.find_or_create_by(name: 'Dumbbells with dumbbells', description: '') +ExerciseType.find_or_create_by(name: 'Standing rod standing on a stand', description: '') +ExerciseType.find_or_create_by(name: 'Squats', description: '') +ExerciseType.find_or_create_by(name: 'Squats with a barbell on the chest', description: '') +ExerciseType.find_or_create_by(name: 'Pressing your feet in the machine', description: '') +ExerciseType.find_or_create_by(name: 'Deadlift on straight legs', description: '') +ExerciseType.find_or_create_by(name: 'Leg bending in the machine', description: '') +ExerciseType.find_or_create_by(name: 'Side Effects', description: '') +ExerciseType.find_or_create_by(name: 'Bringing the hip in a crossover', description: '') +ExerciseType.find_or_create_by(name: 'Ascent to the socks in a standing machine', description: '') +ExerciseType.find_or_create_by(name: 'Ascent to the socks in a sitting simulator', description: '') +puts 'Created default exercise types' superadmin = Administrator.create(email: 'superadmin@gmail.com', password: admin_password, diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..6441ed4 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,9 @@ +version: '2' + +services: + app: + build: + args: + BRANCH: Alex + REPOSITORY: git@github.com:rubizza-survival-camp/fitfree.git + PROJECT_NAME: fitfree \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f5a7e8e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,55 @@ +version: '2' + +services: + # todo: ngnix, https:// + postgres: + image: postgres:10.5 + restart: always + volumes: + - /data:/var/lib/postgresql/data + env_file: + - .env + + redis: + image: redis:5.0-rc4 + restart: always + command: redis-server + ports: + - $REDIS_PORT:$REDIS_PORT + volumes: + - /data:/var/data/redis + env_file: + - .env + + app: + depends_on: + - postgres + build: + context: . + dockerfile: ./docker/app/Dockerfile + volumes: + - .:/app + + web: + build: + context: . + dockerfile: ./docker/nginx/Dockerfile + depends_on: + - app + ports: + - 90:90 + - 443:443 + + sidekiq: + depends_on: + - redis + build: + context: . + dockerfile: ./docker/app/Dockerfile + command: bundle exec sidekiq + volumes: + - .:/app + +volumes: + redis: + postgres: diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile new file mode 100644 index 0000000..0838e5e --- /dev/null +++ b/docker/app/Dockerfile @@ -0,0 +1,30 @@ +# todo: +-git cloning + +FROM rubyroidlabs/ruby:2-5-1-node-stretch + +ARG BRANCH +ARG REPOSITORY +ARG PROJECT_NAME + +LABEL maintainer="Aleksei Lazarenko " + +ENV RAILS_ROOT /var/www/fitfree +RUN mkdir -p $RAILS_ROOT + +# Set working directory +WORKDIR $RAILS_ROOT + +# Adding gems +COPY Gemfile Gemfile +COPY Gemfile.lock Gemfile.lock + +RUN bundle install + +# Adding project files +COPY . . + +#RUN rails assets:precompile + +EXPOSE 3000 + +CMD [ "bundle", "exec", "puma", "-C", "config/puma.rb" ] diff --git a/docker/nginx/Dockerfile b/docker/nginx/Dockerfile new file mode 100644 index 0000000..d99cebe --- /dev/null +++ b/docker/nginx/Dockerfile @@ -0,0 +1,23 @@ +FROM valian/docker-nginx-auto-ssl + +# establish where Nginx should look for files +ENV RAILS_ROOT /var/www/fitfree + +# Set our working directory inside the image +WORKDIR $RAILS_ROOT + +# create log directory +RUN mkdir log + +# copy over static assets +COPY public public/ + +# Copy Nginx config template +COPY docker/nginx/nginx.conf /usr/local/openresty/nginx/conf/ +COPY docker/ssl_keys/localhost.crt /usr/local/openresty/nginx/conf/localhost.crt +COPY docker/ssl_keys/localhost.key /usr/local/openresty/nginx/conf/localhost.key + +EXPOSE 90 443 + +# Use the "exec" form of CMD so Nginx shuts down gracefully on SIGTERM (i.e. `docker stop`) +CMD [ "nginx", "-g", "daemon off;" ] \ No newline at end of file diff --git a/docker/nginx/index.html b/docker/nginx/index.html new file mode 100644 index 0000000..9de2253 --- /dev/null +++ b/docker/nginx/index.html @@ -0,0 +1,18 @@ + + + + + + + Document + + +
+

Here I am

+
+

+ Some other text +

+ + \ No newline at end of file diff --git a/docker/nginx/nginx.conf b/docker/nginx/nginx.conf new file mode 100644 index 0000000..3e54e23 --- /dev/null +++ b/docker/nginx/nginx.conf @@ -0,0 +1,37 @@ +events { + worker_connections 1024; +} + +http { + upstream puma_rails_app { + server app:3000; + } + + include resty-http.conf; + + server { + listen 443 ssl; + server_name my_app.com; + include resty-server-https.conf; + location / { + try_files $uri $uri/@rails_app; + } + location @rails_app { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_pass https://puma_rails_app; + # limit_req zone=one; + access_log /var/www/fitfree/log/nginx.access.log; + error_log /var/www/fitfree/log/nginx.error.log; + } + ssl_certificate /usr/local/openresty/nginx/conf/localhost.crt; + ssl_certificate_key /usr/local/openresty/nginx/conf/localhost.key; + } + + server { + listen 90 default_server; + server_name my_app.com; + include resty-server-http.conf; + } +} \ No newline at end of file diff --git a/dump.rdb b/dump.rdb deleted file mode 100644 index 2643490..0000000 Binary files a/dump.rdb and /dev/null differ diff --git a/localhost.crt b/localhost.crt new file mode 100644 index 0000000..be06efd --- /dev/null +++ b/localhost.crt @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIJAMqTj9uW0y7FMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xODA5MTcwNjQ2MTJaFw0xODEwMTcwNjQ2MTJaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALZHXpQy12W1+hTRhRckSqjyT9xkHXo7XDc08dJgo2SFp4uB6ltKdZbNiJvn +wv9JVWok3BcKLgENkpPhyPwfOqw6H8TH1JdKoZ/tMISpgNoz1YhAKKjgrs/RBWmR +xRK/Kbyn2buNuKOtutfPrfemXUEk18/Jfj2HdNmrY3IkOvrsUmu4dfxzjIBgTBIt +laxdxHoznp1YB12aknNZDmZwN6eaZRtnA+2AdSLXTTPsbNR81vGIv4pR5KXXJkoZ +2/NDNDsXTVvx1ZzY/7p3vEafeYfpsGExAimJevxcQ/AYV07BxiuNgKCLndXCyXK9 +5IYNYXfu51CvgWjCcq6ZmQS1vCUCAwEAAaM6MDgwFAYDVR0RBA0wC4IJbG9jYWxo +b3N0MAsGA1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0B +AQsFAAOCAQEAEq+2Bi0v7iKH+8d7MF79iEi+Q9xG9iMlPPAKro6yw+0mJX4EGKsa +xE9tn4lbmCn/cOVKSHiLMIVng3iTGQdLmq1z9O4OWeszhemQ3BaP3lgPTuk7OmPL +NbEw7H4JQA651vf5tdtd3IR/LM36U36TOnPdB2FJkrj3Ga7l9ZX61RRQBkhjzpmo +9BN45gtdS8gBD3pHyWgVdlAciX+y84g4uXX/XWeOys4BhYmGdNNPAqYAphR936ys +rv4RaPcyNFzzcPeoOM8Cx6X6lapw0bEeZVA8ETF510Sz8I6sE88qrEaZmeljC94V +/JX2bE1aljgmVHUELkHSjrM8lWIcG81rbw== +-----END CERTIFICATE----- diff --git a/localhost.key b/localhost.key new file mode 100644 index 0000000..172f7fd --- /dev/null +++ b/localhost.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC2R16UMtdltfoU +0YUXJEqo8k/cZB16O1w3NPHSYKNkhaeLgepbSnWWzYib58L/SVVqJNwXCi4BDZKT +4cj8HzqsOh/Ex9SXSqGf7TCEqYDaM9WIQCio4K7P0QVpkcUSvym8p9m7jbijrbrX +z633pl1BJNfPyX49h3TZq2NyJDr67FJruHX8c4yAYEwSLZWsXcR6M56dWAddmpJz +WQ5mcDenmmUbZwPtgHUi100z7GzUfNbxiL+KUeSl1yZKGdvzQzQ7F01b8dWc2P+6 +d7xGn3mH6bBhMQIpiXr8XEPwGFdOwcYrjYCgi53VwslyveSGDWF37udQr4FownKu +mZkEtbwlAgMBAAECggEAbIsfZPzJi4XL/+2sZVV1KBnzOHhdnVYP2cgrYG2vnsKA +PPEGD4rNbxnBiaV/VunidSyx6v5i2rmsWWeQeaJXHAwYsuOUUutcR5HE3JrbYhSP +yWz7SWVSc+oyYOUvB7TSM8d4Ptlr4/wmUTEYlWp6CbrY0KFaDWXGTYBj3ap5fMWP +etODZI9zXCxkc3M8veW2UMFiLnU1qcLnGkCfyR6tEUGLU6YQ3GvobdhWD6v2uJc8 +PpdOkp+yAyUEJm6aUw6o6KT0ANOuOnhY7rimnZIpujkZ3fDpjczMUYgju9svCrLM +C1zy0vhQEnAXe4dsfcd3d9egrCVxvEMOoWCy9XUBwQKBgQDn8V2JItT4r8LIxrDp +2P2Hy2dpRixkyBLx0tMnD0VqHGejH0hcg/TXJPSKtZQ3w+wcOUdxLndDH5xz21ZE +u7rwGRh8+vRq1cEA3D9KeVLTPK/OUmK9lRU9Yn8EcVyjABltX90gSoRxSIJeG+7Z +ZLpKJw+jxa47KNB+hk+vc5ZfiQKBgQDJL04r8OoAbvFKJcVF5Ka5+9LyE/1cqgTI +Cx7WQrlbk1CxSgA2pbgjlrxOpg6XZ4+OZ0Itbe5OVA3BHfF25+q9s8eaYXAjzOo9 +I5yuel2/tCZtIWC16gsI7/bZUhugvzXjSJsfHqgNFhzdt48PS1VW5bfjk1x+qla3 +7E+aoEaUvQKBgE91zQmSOUwJSr3l8+3pPNIsyPyz4bmVIYhfJZ+YB7vWh1rG+M9Z +FaQvMOfkVSbVpCn3JZaMyKbiSYMXfXKGrgBbWJxYjSucl0ZoLfahodJkVAZnCxTP +4jrpZ4JqI8Zj3lIuKV9KqBz3LlJ3V1h6vadxwlXk/0+dJ/BwqxP8kWOhAoGBAJU5 +vG8FZFxr7hfEil38atq6+k3LG/v2tFM5RGdC2MAfNhQ6wovGQh5LuWNQ8rPFAgtr +df/Ccaex2v3qWueKwGhziFNvgMFdRkWRO6+DXjRKyNHblyN39TVs4JlzuMBz8+Gh +QkZD8/y48TJX7Ao5I5SwEcUA0fO2H1qPMsCLr661AoGAImj3kx1SSNEsLJHnPy7y +28V+ieNLo0Q9iDNJzH+dxx155sMzN3NWKvpWKzYSR1Bop8VslGd1XSt2fz9JkKcF +gNDSMW2CR7wwe+IVJjxiCsBk4e+t7/axi4NnS6jbkNxZdFXmCG4RU1KpLDMcXKUE +bsw8Iyi7La45Y5xVVg7O5s4= +-----END PRIVATE KEY-----