diff --git a/.env b/.env new file mode 100644 index 0000000..2173ca3 --- /dev/null +++ b/.env @@ -0,0 +1,5 @@ +DATABASE_NAME=rails_development +DATABASE_USER=sammy +DATABASE_PASSWORD=shark +DATABASE_HOST=database +REDIS_HOST=redis \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f01b460 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,49 @@ +FROM ruby:2.5.1-alpine + +ENV BUNDLER_VERSION=2.0.2 + +RUN apk add --update --no-cache \ + binutils-gold \ + build-base \ + curl \ + file \ + g++ \ + gcc \ + git \ + less \ + libstdc++ \ + libffi-dev \ + libc-dev \ + linux-headers \ + libxml2-dev \ + libxslt-dev \ + libgcrypt-dev \ + make \ + netcat-openbsd \ + nodejs \ + openssl \ + pkgconfig \ + postgresql-dev \ + python \ + tzdata \ + yarn + +RUN gem install bundler -v 2.0.2 + +WORKDIR /app + +COPY Gemfile Gemfile.lock ./ + +RUN bundle config build.nokogiri --use-system-libraries + +RUN bundle check || bundle install + +COPY package.json yarn.lock ./ + +RUN yarn install --check-files + +COPY . ./ + +RUN bundle exec rake webpacker:compile + +CMD ["./entrypoints/docker-entrypoint.sh"] diff --git a/Gemfile b/Gemfile index 1504c6f..61fe627 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ ruby '2.5.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.2.3' # Use sqlite3 as the database for Active Record -gem 'sqlite3' +# gem 'sqlite3' # Use Puma as the app server gem 'puma', '~> 3.12' # Use SCSS for stylesheets @@ -38,6 +38,7 @@ gem 'jbuilder', '~> 2.5' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false gem 'sidekiq', '~>6.0.0' +gem 'pg', '~>1.1.3' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console @@ -50,7 +51,7 @@ group :development do gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' - gem 'spring-watcher-listen', '~> 2.0.0' + # gem 'spring-watcher-listen', '~> 2.0.0' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index e033804..84c80ff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,43 +1,43 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.2.3) - actionpack (= 5.2.3) + actioncable (5.2.6) + actionpack (= 5.2.6) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailer (5.2.3) - actionpack (= 5.2.3) - actionview (= 5.2.3) - activejob (= 5.2.3) + actionmailer (5.2.6) + actionpack (= 5.2.6) + actionview (= 5.2.6) + activejob (= 5.2.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.2.3) - actionview (= 5.2.3) - activesupport (= 5.2.3) - rack (~> 2.0) + actionpack (5.2.6) + actionview (= 5.2.6) + activesupport (= 5.2.6) + rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.2.3) - activesupport (= 5.2.3) + actionview (5.2.6) + activesupport (= 5.2.6) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (5.2.3) - activesupport (= 5.2.3) + activejob (5.2.6) + activesupport (= 5.2.6) globalid (>= 0.3.6) - activemodel (5.2.3) - activesupport (= 5.2.3) - activerecord (5.2.3) - activemodel (= 5.2.3) - activesupport (= 5.2.3) + activemodel (5.2.6) + activesupport (= 5.2.6) + activerecord (5.2.6) + activemodel (= 5.2.6) + activesupport (= 5.2.6) arel (>= 9.0) - activestorage (5.2.3) - actionpack (= 5.2.3) - activerecord (= 5.2.3) - marcel (~> 0.3.1) - activesupport (5.2.3) + activestorage (5.2.6) + actionpack (= 5.2.6) + activerecord (= 5.2.6) + marcel (~> 1.0.0) + activesupport (5.2.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) @@ -50,7 +50,7 @@ GEM bindex (0.8.1) bootsnap (1.4.5) msgpack (~> 1.0) - builder (3.2.3) + builder (3.2.4) byebug (11.0.1) capybara (3.29.0) addressable @@ -72,17 +72,17 @@ GEM coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.9) connection_pool (2.2.2) - crass (1.0.5) - erubi (1.9.0) + crass (1.0.6) + erubi (1.10.0) execjs (2.7.0) ffi (1.11.1) font-awesome-rails (4.7.0.5) railties (>= 3.2, < 6.1) - globalid (0.4.2) - activesupport (>= 4.2.0) - i18n (1.6.0) + globalid (0.5.2) + activesupport (>= 5.0) + i18n (1.8.10) concurrent-ruby (~> 1.0) io-like (0.3.0) jbuilder (2.9.1) @@ -91,52 +91,53 @@ GEM rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) - loofah (2.3.1) + loofah (2.12.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.7.1) mini_mime (>= 0.1.1) - marcel (0.3.3) - mimemagic (~> 0.3.2) - method_source (0.9.2) - mimemagic (0.3.3) - mini_mime (1.0.2) - mini_portile2 (2.4.0) - minitest (5.12.0) + marcel (1.0.2) + method_source (1.0.0) + mini_mime (1.1.2) + mini_portile2 (2.6.1) + minitest (5.14.4) msgpack (1.3.1) - nio4r (2.5.2) - nokogiri (1.10.5) - mini_portile2 (~> 2.4.0) + nio4r (2.5.8) + nokogiri (1.12.5) + mini_portile2 (~> 2.6.1) + racc (~> 1.4) + pg (1.1.4) public_suffix (4.0.1) puma (3.12.2) - rack (2.0.8) + racc (1.6.0) + rack (2.2.3) rack-protection (2.0.7) rack rack-proxy (0.6.5) rack rack-test (1.1.0) rack (>= 1.0, < 3) - rails (5.2.3) - actioncable (= 5.2.3) - actionmailer (= 5.2.3) - actionpack (= 5.2.3) - actionview (= 5.2.3) - activejob (= 5.2.3) - activemodel (= 5.2.3) - activerecord (= 5.2.3) - activestorage (= 5.2.3) - activesupport (= 5.2.3) + rails (5.2.6) + actioncable (= 5.2.6) + actionmailer (= 5.2.6) + actionpack (= 5.2.6) + actionview (= 5.2.6) + activejob (= 5.2.6) + activemodel (= 5.2.6) + activerecord (= 5.2.6) + activestorage (= 5.2.6) + activesupport (= 5.2.6) bundler (>= 1.3.0) - railties (= 5.2.3) + railties (= 5.2.6) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) - rails-html-sanitizer (1.2.0) - loofah (~> 2.2, >= 2.2.2) - railties (5.2.3) - actionpack (= 5.2.3) - activesupport (= 5.2.3) + rails-html-sanitizer (1.4.2) + loofah (~> 2.3) + railties (5.2.6) + actionpack (= 5.2.6) + activesupport (= 5.2.6) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) @@ -168,24 +169,20 @@ GEM rack-protection (>= 2.0.0) redis (>= 4.1.0) spring (2.1.0) - spring-watcher-listen (2.0.1) - listen (>= 2.7, < 4.0) - spring (>= 1.2, < 3.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.1) + sprockets-rails (3.2.2) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sqlite3 (1.4.1) - thor (0.20.3) + thor (1.1.0) thread_safe (0.3.6) tilt (2.0.10) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) - tzinfo (1.2.5) + tzinfo (1.2.9) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) @@ -198,9 +195,9 @@ GEM activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) - websocket-driver (0.7.1) + websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.4) + websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) @@ -216,14 +213,13 @@ DEPENDENCIES font-awesome-rails (~> 4.x) jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) + pg (~> 1.1.3) puma (~> 3.12) rails (~> 5.2.3) sass-rails (~> 5.0) selenium-webdriver sidekiq (~> 6.0.0) spring - spring-watcher-listen (~> 2.0.0) - sqlite3 turbolinks (~> 5) tzinfo-data uglifier (>= 1.3.0) diff --git a/README.md b/README.md index b395379..c26bbe2 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -Sample project demonstrating how to integrate Sidekiq and Redis into an existing Rails project, as described in [How To Add Sidekiq and Redis to a Ruby on Rails Application](https://www.digitalocean.com/community/tutorials/how-to-add-sidekiq-and-redis-to-a-ruby-on-rails-application) +Sample project demonstrating how to use Docker Compose to containerize a Ruby on Rails application, as described in [Containerizing a Ruby on Rails Application for Development with Docker Compose](https://www.digitalocean.com/community/tutorials/containerizing-a-ruby-on-rails-application-for-development-with-docker-compose). diff --git a/config/database.yml b/config/database.yml index 0d02f24..6b8498e 100644 --- a/config/database.yml +++ b/config/database.yml @@ -5,21 +5,25 @@ # gem 'sqlite3' # default: &default - adapter: sqlite3 + adapter: postgresql + encoding: unicode + database: <%= ENV['DATABASE_NAME'] %> + username: <%= ENV['DATABASE_USER'] %> + password: <%= ENV['DATABASE_PASSWORD'] %> + port: <%= ENV['DATABASE_PORT'] || '5432' %> + host: <%= ENV['DATABASE_HOST'] %> pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> timeout: 5000 development: <<: *default - database: db/development.sqlite3 + # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default - database: db/test.sqlite3 production: <<: *default - database: db/production.sqlite3 diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb new file mode 100644 index 0000000..2b14a34 --- /dev/null +++ b/config/initializers/sidekiq.rb @@ -0,0 +1,13 @@ +Sidekiq.configure_server do |config| + config.redis = { + host: ENV['REDIS_HOST'], + port: ENV['REDIS_PORT'] || '6379' + } +end + +Sidekiq.configure_client do |config| + config.redis = { + host: ENV['REDIS_HOST'], + port: ENV['REDIS_PORT'] || '6379' + } +end diff --git a/db/schema.rb b/db/schema.rb index 425f2a9..3036301 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -12,6 +12,9 @@ ActiveRecord::Schema.define(version: 2019_11_20_132043) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + create_table "endangereds", force: :cascade do |t| t.string "name" t.string "iucn" diff --git a/db/seeds.rb b/db/seeds.rb index 1beea2a..806247b 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,7 +1,3 @@ -# This file should contain all the record creation needed to seed the database with its default values. -# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). -# -# Examples: -# -# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) -# Character.create(name: 'Luke', movie: movies.first) +# Adding demo sharks +sharks = Shark.create([{ name: 'Great White', facts: 'Scary' }, { name: 'Megalodon', facts: 'Ancient' }, { name: 'Hammerhead', facts: 'Hammer-like' }, { name: 'Speartooth', facts: 'Endangered' }]) +Post.create(body: 'These sharks are misunderstood', shark: sharks.first) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..ac05f4f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,50 @@ +version: '3.4' + +services: + app: + build: + context: . + dockerfile: Dockerfile + depends_on: + - database + - redis + ports: + - "3000:3000" + volumes: + - .:/app + - gem_cache:/usr/local/bundle/gems + - node_modules:/app/node_modules + env_file: .env + environment: + RAILS_ENV: development + + database: + image: postgres:12.1 + volumes: + - db_data:/var/lib/postgresql/data + - ./init.sql:/docker-entrypoint-initdb.d/init.sql + + redis: + image: redis:5.0.7 + + sidekiq: + build: + context: . + dockerfile: Dockerfile + depends_on: + - app + - database + - redis + volumes: + - .:/app + - gem_cache:/usr/local/bundle/gems + - node_modules:/app/node_modules + env_file: .env + environment: + RAILS_ENV: development + entrypoint: ./entrypoints/sidekiq-entrypoint.sh + +volumes: + gem_cache: + db_data: + node_modules: diff --git a/entrypoints/docker-entrypoint.sh b/entrypoints/docker-entrypoint.sh new file mode 100755 index 0000000..5186382 --- /dev/null +++ b/entrypoints/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ -f tmp/pids/server.pid ]; then + rm tmp/pids/server.pid +fi + +bundle exec rails s -b 0.0.0.0 diff --git a/entrypoints/sidekiq-entrypoint.sh b/entrypoints/sidekiq-entrypoint.sh new file mode 100755 index 0000000..fe611a8 --- /dev/null +++ b/entrypoints/sidekiq-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +if [ -f tmp/pids/server.pid ]; then + rm tmp/pids/server.pid +fi + +bundle exec sidekiq diff --git a/init.sql b/init.sql new file mode 100755 index 0000000..58f3a42 --- /dev/null +++ b/init.sql @@ -0,0 +1,2 @@ +CREATE USER sammy; +ALTER USER sammy WITH SUPERUSER;