diff --git a/.env.example b/.env.example index e60e932d..36e72adf 100644 --- a/.env.example +++ b/.env.example @@ -1,3 +1,3 @@ -PGHOST=db -PGUSER=postgres -PGPASSWORD=changeme +HOST=db +USER=mysql +PASSWORD=change_me_right_now diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 91bfdf1f..7b5a50dd 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -32,24 +32,24 @@ jobs: env: RAILS_ENV: test - DATABASE_URL: postgres://postgres:postgres@localhost:5432 DISABLE_BOOTSNAP: true DISABLE_BOOTSNAP_LOAD_PATH_CACHE: true services: - postgres: - image: postgres:12 - env: - POSTGRES_PASSWORD: postgres - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 + mysql: + image: mysql + # + env: + MYSQL_ROOT_PASSWORD: change_me_right_now + MYSQL_ALLOW_EMPTY_PASSWORD: true + MYSQL_ROOT_HOST: 172.18.0.1 + MYSQL_LOG_CONSOLE: true + MYSQL_PASSWORD: change_me_right_now + ports: + - 8888:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - steps: + steps: - uses: actions/checkout@v3 - name: Set up Ruby @@ -59,6 +59,11 @@ jobs: - name: Create database run: | + sudo /etc/init.d/mysql start --skip-grant-tables + mysql -h 127.0.0.1 --port 8888 -pchange_me_right_now -uroot -e "SHOW DATABASES" + echo "************" + printenv + echo "************" bundle exec rails db:create bundle exec rails db:schema:load diff --git a/Dockerfile b/Dockerfile index e5186667..254200f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,10 +5,11 @@ RUN apt-get update -qq && apt-get install -yq --no-install-recommends \ gnupg2 \ less \ git \ - libpq-dev \ - postgresql-client \ + telnet \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +RUN apt-get update -qq && apt-get install -y default-libmysqlclient-dev + ENV LANG=C.UTF-8 \ BUNDLE_JOBS=4 \ BUNDLE_RETRY=3 diff --git a/Gemfile b/Gemfile index acd2c741..12ce32ea 100644 --- a/Gemfile +++ b/Gemfile @@ -11,8 +11,8 @@ gem "rails", "~> 7.0.3" # The original asset pipeline for Rails [https://github.com/rails/sprockets-rails] gem "sprockets-rails" -# Use postgresql as the database for Active Record -gem "pg", "~> 1.4" +# Use mysql as the database for Active Record +gem "mysql2", "~> 0.5" # Use the Puma web server [https://github.com/puma/puma] gem "puma", "~> 5.6" diff --git a/Gemfile.lock b/Gemfile.lock index 08bac828..f71c3ccf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -124,6 +124,7 @@ GEM mini_mime (1.1.2) minitest (5.16.1) msgpack (1.5.2) + mysql2 (0.5.4) net-imap (0.2.3) digest net-protocol @@ -148,7 +149,6 @@ GEM parallel (1.22.1) parser (3.1.2.0) ast (~> 2.4.1) - pg (1.4.1) public_suffix (4.0.7) puma (5.6.4) nio4r (~> 2.0) @@ -285,7 +285,7 @@ DEPENDENCIES image_processing (~> 1.12) importmap-rails jbuilder - pg (~> 1.4) + mysql2 (~> 0.5) puma (~> 5.6) rack-mini-profiler rails (~> 7.0.3) diff --git a/README.md b/README.md index 9cda94b2..25ae0e66 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ ![Ruby](https://github.com/ryanwi/rails7-on-docker/workflows/Ruby/badge.svg) -# Rails 7 on Docker demo application +# Rails 7 on Docker ** MYSQL ** demo application -This app demonstrates Rails 7 with PostgreSQL, import maps, turbo, stimulus and hotwire, all running in Docker. - -**NOTE:** [There is also an example Rails 6 application working in Docker with Webpacker](https://github.com/ryanwi/rails-on-docker) +This app demonstrates Rails 7 with Mysql8, import maps, turbo, stimulus and hotwire, all running in Docker. ## Features +* Mysql 8 * Rails 7 * Ruby 3 * Dockerfile and Docker Compose configuration -* PostgreSQL database +* MYSQL database * Redis * GitHub Actions for * tests @@ -19,62 +18,35 @@ This app demonstrates Rails 7 with PostgreSQL, import maps, turbo, stimulus and * Security checks with [Brakeman](https://github.com/presidentbeef/brakeman) and [bundler-audit](https://github.com/rubysec/bundler-audit) * Dependabot for automated updates -## Initial setup -``` -cp .env.example .env -docker compose build -docker compose run --rm web bin/rails db:setup -``` - ## Running the Rails app ``` -docker compose up +sh start.sh ``` ## Running the Rails console When the app is already running with `docker-compose` up, attach to the container: ``` -docker compose exec web bin/rails c +docker-compose exec web bin/rails c ``` When no container running yet, start up a new one: ``` -docker compose run --rm web bin/rails c +docker-compose run --rm web bin/rails c ``` ## Running tests ``` -docker compose run --rm web bin/rspec +docker-compose run --rm web bin/rspec ``` ## Updating gems ``` -docker compose run --rm web bundle update -docker compose up --build -``` - -## Production build - -``` -docker build -f production.Dockerfile . +docker-compose run --rm web bundle update +docker-compose up --build ``` ## Credits/References +Thanks!! to ryanwi for the postgres version. The conversion to MYSQL8 was pretty easy!! -### Rails with Docker -* [Quickstart: Compose and Rails](https://docs.docker.com/compose/rails/) -* [Docker for Rails Developers -Build, Ship, and Run Your Applications Everywhere](https://pragprog.com/titles/ridocker/docker-for-rails-developers/) -* [Ruby on Whales: -Dockerizing Ruby and Rails development](https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development) - -### Rails 7 with importmaps - -* [Alpha preview: Modern JavaScript in Rails 7 without Webpack](https://www.youtube.com/watch?v=PtxZvFnL2i0) - -### Rails 7 with hotwire +https://github.com/ryanwi/rails7-on-docker -* [Stimulus 3 + Turbo 7 = Hotwire 1.0](https://world.hey.com/dhh/stimulus-3-turbo-7-hotwire-1-0-9d507133) -* [Turbo 7](https://world.hey.com/hotwired/turbo-7-0dd7a27f) -* [Rails 7 will have three great answers to JavaScript in 2021+](https://world.hey.com/dhh/rails-7-will-have-three-great-answers-to-javascript-in-2021-8d68191b) -* [Hotwire Turbo Replacing Rails UJS](https://www.driftingruby.com/episodes/hotwire-turbo-replacing-rails-ujs) diff --git a/clean.sh b/clean.sh new file mode 100644 index 00000000..7427edfc --- /dev/null +++ b/clean.sh @@ -0,0 +1 @@ +docker container stop $(docker container ls -aq) && docker system prune -af --volumes diff --git a/config/database.yml b/config/database.yml index 2858614c..47281c1a 100644 --- a/config/database.yml +++ b/config/database.yml @@ -1,22 +1,5 @@ -# PostgreSQL. Versions 9.3 and up are supported. -# -# Install the pg driver: -# gem install pg -# On macOS with Homebrew: -# gem install pg -- --with-pg-config=/usr/local/bin/pg_config -# On macOS with MacPorts: -# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config -# On Windows: -# gem install pg -# Choose the win32 build. -# Install PostgreSQL and put its /bin directory on your path. -# -# Configure Using Gemfile -# gem "pg" -# default: &default - adapter: postgresql - encoding: unicode + adapter: mysql2 # For details on connection pooling, see Rails configuration guide # https://guides.rubyonrails.org/configuring.html#database-pooling pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> @@ -24,33 +7,9 @@ default: &default development: <<: *default database: railsondocker_development - - # The specified database role being used to connect to postgres. - # To create additional roles in postgres see `$ createuser --help`. - # When left blank, postgres will use the default role. This is - # the same name as the operating system user running Rails. - #username: railsondocker - - # The password associated with the postgres role (username). - #password: - - # Connect on a TCP socket. Omitted by default since the client uses a - # domain socket that doesn't need configuration. Windows does not have - # domain sockets, so uncomment these lines. - #host: localhost - - # The TCP port the server listens on. Defaults to 5432. - # If your server runs on a different port number, change accordingly. - #port: 5432 - - # Schema search path. The server defaults to $user,public - #schema_search_path: myapp,sharedapp,public - - # Minimum log levels, in increasing order: - # debug5, debug4, debug3, debug2, debug1, - # log, notice, warning, error, fatal, and panic - # Defaults to warning. - #min_messages: notice + username: railsondocker + password: change_me_right_now + host: rails7-on-docker-mysql-db-1 # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". @@ -58,29 +17,13 @@ development: test: <<: *default database: railsondocker_test + username: root + password: change_me_right_now + host: 127.0.0.1 + port: 8888 -# As with config/credentials.yml, you never want to store sensitive information, -# like your database password, in your source code. If your source code is -# ever seen by anyone, they now have access to your database. -# -# Instead, provide the password or a full connection URL as an environment -# variable when you boot the app. For example: -# -# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" -# -# If the connection URL is provided in the special DATABASE_URL environment -# variable, Rails will automatically merge its configuration values on top of -# the values provided in this file. Alternatively, you can specify a connection -# URL environment variable explicitly: -# -# production: -# url: <%= ENV["MY_APP_DATABASE_URL"] %> -# -# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database -# for a full overview on how database connection configuration can be specified. -# production: <<: *default database: railsondocker_production username: railsondocker - password: <%= ENV["RAILSONDOCKER_DATABASE_PASSWORD"] %> + password: change_me_right_now diff --git a/db/schema.rb b/db/schema.rb index 1ea33849..e0201f85 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,32 +10,28 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2021_12_16_185503) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" - - create_table "action_text_rich_texts", force: :cascade do |t| +ActiveRecord::Schema[7.0].define(version: 2021_12_16_185503) do + create_table "action_text_rich_texts", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "name", null: false - t.text "body" + t.text "body", size: :long t.string "record_type", null: false t.bigint "record_id", null: false - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true end - create_table "active_storage_attachments", force: :cascade do |t| + create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "name", null: false t.string "record_type", null: false t.bigint "record_id", null: false t.bigint "blob_id", null: false - t.datetime "created_at", precision: 6, null: false + t.datetime "created_at", null: false t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true end - create_table "active_storage_blobs", force: :cascade do |t| + create_table "active_storage_blobs", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "key", null: false t.string "filename", null: false t.string "content_type" @@ -43,28 +39,28 @@ t.string "service_name", null: false t.bigint "byte_size", null: false t.string "checksum" - t.datetime "created_at", precision: 6, null: false + t.datetime "created_at", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end - create_table "active_storage_variant_records", force: :cascade do |t| + create_table "active_storage_variant_records", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "blob_id", null: false t.string "variation_digest", null: false t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true end - create_table "articles", force: :cascade do |t| + create_table "articles", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.string "title" t.text "content" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end - create_table "comments", force: :cascade do |t| + create_table "comments", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t| t.bigint "article_id", null: false t.text "content" - t.datetime "created_at", precision: 6, null: false - t.datetime "updated_at", precision: 6, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.index ["article_id"], name: "index_comments_on_article_id" end diff --git a/docker-compose.yml b/docker-compose.yml index 4c3cefc3..a3db971d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,19 +15,19 @@ services: - db - redis db: - image: postgres:13 + image: mysql ports: - - "5432:5432" + - "3306:3306" + restart: always environment: - - POSTGRES_PASSWORD=changeme + - MYSQL_ROOT_PASSWORD=change_me_right_now volumes: - - pg_data:/var/lib/postgresql/data + - ./init-script.sql:/docker-entrypoint-initdb.d/init-script.sql redis: image: redis volumes: - redis_data:/data volumes: - pg_data: redis_data: bundle: diff --git a/init-script.sql b/init-script.sql new file mode 100644 index 00000000..17892511 --- /dev/null +++ b/init-script.sql @@ -0,0 +1,3 @@ +CREATE USER IF NOT EXISTS 'railsondocker'@'172.%.%.%' IDENTIFIED BY 'change_me_right_now'; +GRANT ALL ON *.* to 'railsondocker'@'172.%.%.%'; +FLUSH HOSTS; diff --git a/start.sh b/start.sh new file mode 100755 index 00000000..e0cbf5e4 --- /dev/null +++ b/start.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash +test=`docker-compose --version` +if [ -z "$test" ]; then echo "Please install docker compose"; exit; fi + +if test -f ".env"; then + echo ".env exists." +else + cp .env.example .env +fi + + +cp .env.example .env +docker-compose build +docker-compose run --rm web bin/rails db:setup +docker-compose up diff --git a/stop.sh b/stop.sh new file mode 100644 index 00000000..eff851ae --- /dev/null +++ b/stop.sh @@ -0,0 +1 @@ +docker stop $(docker ps -aq);