base on Launch Rails with 1 shell command! # Rails 7. Start Kit <img alt="Rails 7. Start kit. v2.1" src="https://github.com/the-teacher/rails7-startkit/assets/496713/e90eaf2a-ed8a-4e37-9fdd-a4edb6174de1"> <h2>Install and Run <code>Ruby&nbsp;on&nbsp;Rails</code> in&nbsp;Minutes!</h2> <i>Copy & Paste in your terminal</i> ❀️ **Linux / MacOS** ```sh git clone https://github.com/the-teacher/rails7-startkit.git && \ cd rails7-startkit && \ ruby bin/setup ``` πŸ’™ **Windows** ```sh git clone https://github.com/the-teacher/rails7-startkit.git & cd rails7-startkit & ruby bin/setup ``` ### What Is That? Rails App in a Docker container with some popular preinstalled tools. ### Why Do I Need It? Save hours, days or weeks on setting up a typical Rails app. ### What Cases for Using It? - You start new Rails project - You need a playground for experiments - You learn Rails and related technologies - You teach people or record videos about Rails - You are going to write a new article about Rails ### How it works ![Rails 7. Start Kit](https://user-images.githubusercontent.com/496713/222904528-185c312f-88cc-42d5-9d52-068690a5db05.gif) ## What Is Under the Hood? <table> <thead> <tr> <th>Logotype</th> <th>Description</th> <th>Why it was added</th> </tr> </thead> <tbody> <tr> <td colspan="3"><h3>Main</h3></td> </tr> <tr> <td><img width="100px" alt="docker" src="Rails7StartKit/assets/images/docker.png"></td> <td><b>Docker</b></td> <td>Helps to keep all required services in containers. To have fast and predictable installation process in minutes. <a href="https://hub.docker.com/r/iamteacher/rails7/tags" target="_blank">Docker Images are here.</a></td> </tr> <tr> <td><img width="100px" alt="ruby" src="Rails7StartKit/assets/images/ruby.png"></td> <td><b>Ruby 3.2</b></td> <td>Most recent version of Ruby</td> </tr> <tr> <td><img width="100px" alt="rails7" src="Rails7StartKit/assets/images/rails7.png"></td> <td><b>Rails 7</b></td> <td>Most recent version of Rails</td> </tr> <tr> <td><img width="100px" alt="pgsql" src="Rails7StartKit/assets/images/pgsql.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/SQL_Database_Adapters">PostgresSQL</a></b></td> <td>Most popular relational database</td> </tr> <tr> <td colspan="3"><h3>Cache and Delayed Jobs</h3></td> </tr> <tr> <td><img width="100px" alt="redis" src="Rails7StartKit/assets/images/redis.png"></td> <td><b><a href="https://redis.io">Redis</a></b></td> <td>In-memory data store. For caching and as a dependency of Sidekiq</td> </tr> <tr> <td><img width="100px" alt="sidekiq" src="Rails7StartKit/assets/images/sidekiq.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/Background_Jobs">Sidekiq</a></b></td> <td>Job Scheduler and Async Tasks Executor. Can be used as a stand alone tool or as ActiveJob backend</td> </tr> <tr> <td><img width="100px" alt="whenever" src="Rails7StartKit/assets/images/whenever.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/scheduling">whenever</a></b></td> <td>Linux Cron based periodical tasks</td> </tr> <tr> <td colspan="3"><h3>Full Text Search</h3></td> </tr> <tr> <td><img width="100px" alt="elastic" src="Rails7StartKit/assets/images/elastic.png"></td> <td><b><a href="https://www.elastic.co">Elasticsearch</a></b></td> <td>The world’s leading Search engine</td> </tr> <tr> <td><img width="100px" alt="chewy" src="Rails7StartKit/assets/images/chewy.png"></td> <td><b><a href="https://www.ruby-toolbox.com/projects/chewy">Chewy</a></b></td> <td>Ruby Connector to Elasticsearch</td> </tr> <tr> <td colspan="3"><h3>Front-end</h3></td> </tr> <tr> <td><img width="100px" alt="bootstrap" src="Rails7StartKit/assets/images/bootstrap.png"></td> <td><b><a href="https://github.com/twbs/bootstrap">Bootstrap</a></b></td> <td>Old but Gold Framework for Web</td> </tr> <tr> <td><img width="100px" alt="import-maps" src="Rails7StartKit/assets/images/esbuild.png"></td> <td><b><a href="https://esbuild.github.io/">ES Build</a></b></td> <td>An extremely fast bundler for the web</td> </tr> <tr> <td><img width="100px" alt="import-maps" src="Rails7StartKit/assets/images/import-maps.png"></td> <td><b><a href="https://github.com/rails/importmap-rails">Import Maps</a></b></td> <td>Rails' recommended way to process JavaScript</td> </tr> <tr> <td><img width="100px" alt="sprockets" src="Rails7StartKit/assets/images/sprockets.png"></td> <td><b><a href="https://github.com/rails/sprockets">Sprockets</a></b></td> <td>Rack-based asset packager</td> </tr> <tr> <td colspan="3"><h3>Application Configuration</h3></td> </tr> <tr> <td><img width="100px" alt="gem dotenv-rails" src="Rails7StartKit/assets/images/dotenv.png"></td> <td><b><a href="https://www.ruby-toolbox.com/projects/dotenv">gem&nbsp;"dotenv"</a></b></td> <td>ENV variables management tool</td> </tr> <tr> <td><img width="100px" alt="gem config" src="Rails7StartKit/assets/images/config.png"></td> <td><b><a href="https://www.ruby-toolbox.com/projects/config">gem&nbsp;"config"</a></b></td> <td>Configuration management tool</td> </tr> <tr> <td colspan="3"><h3>Application Level</h3></td> </tr> <tr> <td><img width="100px" alt="puma" src="Rails7StartKit/assets/images/nginx.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/web_servers">Nginx</a></b></td> <td>Web Server. Reverse Proxy. Load Balancer. Caching, Streaming etc.</td> </tr> <tr> <td><img width="100px" alt="puma" src="Rails7StartKit/assets/images/puma.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/web_servers">Puma</a></b></td> <td>Application Web Server. To launch Rails app</td> </tr> <tr> <td><img width="100px" alt="devise" src="Rails7StartKit/assets/images/devise.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/rails_authentication">Devise</b></a></td> <td>Authentication solution for Rails + Emails confirmations</td> </tr> <tr> <td><img width="100px" alt="ActiveStorage" src="Rails7StartKit/assets/images/active-storage.png"></td> <td><b><a href="https://github.com/rails/rails/tree/main/activestorage">ActiveStorage</b></a></td> <td>Default Cloud Storage Solution for Rails</td> </tr> <tr> <td><img width="100px" alt="faker" src="Rails7StartKit/assets/images/faker.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/random_data_generation">Faker</a></b></td> <td>Fake data for development and testing</td> </tr> <tr> <td><img width="100px" alt="kaminari" src="Rails7StartKit/assets/images/kaminari.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/pagination">Kaminari</a></b></td> <td>Pagination solution</td> </tr> <tr> <td><img width="100px" alt="sanitize" src="Rails7StartKit/assets/images/sanitize.png"></td> <td><b><a href="https://www.ruby-toolbox.com/projects/sanitize">Sanitize</a></b></td> <td>Sanitization of a dangerous users' input</td> </tr> <tr> <td><img width="100px" alt="letter_opener" src="Rails7StartKit/assets/images/mailcatcher.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/EMail_Fake_Servers">mailcatcher</a></b></td> <td>Email previewer for development</td> </tr> <tr> <td colspan="3"><h3>Code Quality</h3></td> </tr> <tr> <td><img width="100px" alt="rspec" src="Rails7StartKit/assets/images/rspec.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/testing_frameworks">RSpec</a></b></td> <td>Testing Framework for Rails</td> </tr> <tr> <td><img width="100px" alt="rspec" src="Rails7StartKit/assets/images/rubocop.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/code_metrics">Rubocop</a></b></td> <td>Ruby static code analyzer (a.k.a. linter) and formatter.</td> </tr> <tr> <td><img width="100px" alt="breakman" src="Rails7StartKit/assets/images/breakman.png"></td> <td><b><a href="https://github.com/presidentbeef/brakeman">Breakman</a></b></td> <td>Static analysis tool | Security Vulnerabilities.</td> </tr> <tr> <td><img width="100px" alt="rspec" src="Rails7StartKit/assets/images/simple-cov.png"></td> <td><b><a href="https://github.com/simplecov-ruby/simplecov">SimpleCov</a></b></td> <td>Code coverage for Ruby (and Rails)</td> </tr> </tbody> </table> What I'm going to add... <table> <thead> <tr> <th>Logotype</th> <th>Description</th> <th>Why it was added</th> </tr> </thead> <tbody> <tr> <td><img width="100px" alt="devise" src="Rails7StartKit/assets/images/devise.png"></td> <td><b><a href="https://www.ruby-toolbox.com/categories/rails_authentication">Devise</b></a></td> <td>Login with Facebook and Google</td> </tr> </tbody> </table> *All trademarks, logos and brand names are the property of their respective owners.* ## Installation and Running <i>Copy & Paste in your terminal</i> ❀️ **Linux / MacOS** ```sh git clone https://github.com/the-teacher/rails7-startkit.git && \ cd rails7-startkit && \ ruby bin/setup ``` πŸ’™ **Windows** ```sh git clone https://github.com/the-teacher/rails7-startkit.git & cd rails7-startkit & ruby bin/setup ``` You will see something like that: ```js ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Rails 7. StartKit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ What was done: 1. Pull all required Images 2. Launching ElasticSearch Container 3. Launching Mailcatcher Container 4. Launching PgSQL Container 5. Launching Redis Container 6. Launching Rails Container 7. Correcting Permissions for Linux 8. Installing Gems 9. Turn off some ElasticSearch settings 10. Prepare Database (Create, Migrate, Create Seeds) 11. Indexing Article Model 12. Quality: Rubocop 13. Quality: RSpec with SimpleConv 14. Quality: Breakman 15. Yarn: Install Node Packages 16. Yarn: Build JS/CSS Assets 17. Precompile Assets 18. Launching Sidekiq 19. Launching Rails App with Puma 20. Visit Rails App: http://localhost:3000 21. Visit Mail Service: http://localhost:1080 22. Visit ElasticSearch: http://localhost:9200 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Welcome to RAILS 7! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ``` ## `bin/` commands ❀️ :warning: `bin/exec` - Linux and MacOS users can skip using `ruby` πŸ’™ :warning: `ruby bin/exec` - Windows users should use `ruby` explicitly From the root of the project <table> <thead> <tr> <th>Command</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td colspan="2">Most important</td> </tr> <tr> <td><b>ruby bin/setup</b></td> <td>Download images, run containers, initialize data, launch all processes.</td> </tr> <tr> <td><b>ruby bin/open</b></td> <td>Get in <b>Rails</b> Container</td> </tr> <tr> <td><b>rubyc&nbsp;bin/exec&nbsp;[CMD]</b></td> <td>Execute a command (<i>[CMD]</i>) from <code>Rails7StartKit</code> module</td> </tr> </tbody> </table> ## `bin/open` command <table> <thead> <tr> <th>Command</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td colspan="2">Get in a container</td> </tr> <tr> <td><b>ruby&nbsp;bin/open&nbsp;[NAME]</b></td> <td> Get in a Container. <code>[NAME]</code> <br /><br /> <i>[NAME]</i> Values: <code>rails</code>,<code>psql</code>, <code>redis</code>, <code>elastic</code>, <code>mailcatcher</code>. <br /><br /> Default value is: <code>rails</code>. </td> </tr> </tbody> </table> ## `bin/exec` command <details> <summary>All Possible Module Methods</summary> <br> <ul> <li>breakman</li> <li>cache</li> <li>check_docker!</li> <li>check_docker_compose_v2!</li> <li>check_docker_running!</li> <li>chewy_index</li> <li>chewy_reset</li> <li>container_bash_exec</li> <li>container_exec</li> <li>containers_information</li> <li>cron_start</li> <li>cron_stop</li> <li>docker_compose</li> <li>init_nvm</li> <li>log_puma</li> <li>log_server</li> <li>log_sidekiq</li> <li>print_methods</li> <li>prompt!</li> <li>puma_dev_start</li> <li>puma_restart</li> <li>puma_start</li> <li>puma_stop</li> <li>rails7_header</li> <li>rails7_ready</li> <li>rails7_startkit_greetings!</li> <li>rails_assets_precompile</li> <li>rails_db_migrate</li> <li>rails_db_prepare</li> <li>rails_install_gems</li> <li>reset</li> <li>restart</li> <li>restart_all</li> <li>rspec</li> <li>rspec_with_cov</li> <li>rubocop</li> <li>rubocop_fix</li> <li>setup!</li> <li>sidekiq_start</li> <li>sidekiq_stop</li> <li>start</li> <li>start_all</li> <li>start_all_containers</li> <li>status</li> <li>stop</li> <li>stop_all</li> <li>stop_all_containers</li> <li>system!</li> <li>turn_off_elastic_settings</li> <li>whenever_show</li> <li>whenever_start</li> <li>whenever_stop</li> <li>yarn_build</li> <li>yarn_install</li> </ul> </details> <table> <thead> <tr> <th>Command</th> <th>Description</th> </tr> </thead> <tbody> <tr> <td colspan="2"><h3>:arrow_right: Execute</h3></td> </tr> <tr> <td><b>ruby bin/exec&nbsp;[CMD]</b></td> <td>Execute a command (<i>[CMD]</i>) from <code>Rails7StartKit</code> module</td> </tr> <tr> <td colspan="2"><h3>:arrow_right: Start/Stop/Restart</h3></td> </tr> <tr> <td><b>ruby bin/exec start</b></td> <td>Start processes in <b>rails</b> container</td> </tr> <tr> <td><b>ruby bin/exec stop</b></td> <td>Stop processes in <b>rails</b> container</td> </tr> <tr> <td><b>ruby bin/exec restart</b></td> <td><code>bin/exec&nbsp;stop</code> + <code>bin/exec&nbsp;start</code></td> </tr> <tr> <td><b>ruby bin/exec&nbsp;start_all</b></td> <td>Start processes and containers</td> </tr> <tr> <td><b>ruby bin/exec&nbsp;stop_all</b></td> <td>Stop processes and containers</td> </tr> <tr> <td><b>ruby bin/exec restart_all</b></td> <td><code>bin/exec&nbsp;stop_all</code> + <code>bin/exec&nbsp;start_all</code></td> </tr> <tr> <td colspan="2"><h3>:arrow_right: Helpers<h3></td> </tr> <tr> <td><b>ruby bin/exec status</b></td> <td>To see running containers and launched services</td> </tr> <tr> <td><b>ruby bin/exec cache</b></td> <td>Toggle caching in development and restart web server</td> </tr> <tr> <td><b>ruby bin/exec index</b></td> <td>Run Search engines indexation</td> </tr> <tr> <td><b>ruby bin/exec reset</b></td> <td>Reset data of services in <b>./db</b> folder</td> </tr> </tbody> </table> ### Prerequisites On your host you have: - **Any version** of Ruby - **Any version** of Git - **Any version** of Docker ### Conventions and Agreements <details> <summary>Show details</summary> <br> For <b>demonstration</b>, education and maintainance purposes I use a bit unsusual approach to name some files. I `_UNDERSCORE` and `UPPERCASE` some files and folders <b>to move them on the top of a folder</b> and to make them more visible and to highlight their importance. **Data** - All services' data related folders are placed in `./db` - All folders are `UPPERCASED` ``` ./db β”œβ”€β”€ ELASTIC β”œβ”€β”€ PGSQL └── REDIS ``` **Configuration Files** - All services' configurations are placed in `./config` - All configs are `_UNDERSCORED` and `UPPERCASED` ``` ./config β”œβ”€β”€ _CONFIG.yml β”œβ”€β”€ _PUMA.rb └── _SIDEKIQ.yml ``` **Initialazers** - All services' initializers are placed in `./config/initializers` - All files are `_UNDERSCORED` and `UPPERCASED` ``` ./config/initializers/ β”œβ”€β”€ _CHEWY.rb β”œβ”€β”€ _CONFIG.rb β”œβ”€β”€ _REDIS.rb └── _SIDEKIQ.rb ``` </details> ### Rails user <details> <summary>Show Details</summary> As a user to own files and run Rails inside a container I use `user:group` => `lucky:lucky` => `7777:7777` If you would like to run the project on a linux environment then: - create group `lucky (7777)` and user `lucky (7777)` - run the project with `RUN_AS=7777:7777` option </details> ### Questions and Answers <details> <summary>What is an idea of this project?</summary> <br> <p>For many years Rails gives you freedom to choose development tools. Different databases, different paginators, different search engines, different delayed job solutions.</p> <p>It is great. But all the time you need to choose something and install it from scratch.</p> <p>I think I did my choice about many solutions and tools.</p> <p>I want to install my minimal pack of tools now and reuse my StartKit every time when I start a new project.</p> <p>With Docker I can roll out my minimal application with all required preinstalled tools in minutes, not in hours or in days.</p> </details> <details> <summary>Why did you create this project?</summary> <br> <p> I didn't work with Rails last 4 or 5 years. I wanted to learn new approaches and techniques. I found that there is still no a simple way to setup a blank app with most popular tools. </p> <p>So. Why not to make my own playground?</p> </details> <details> <summary>How do you choose technologies for the StartKit?</summary> <br> <p>I use tools that I like or want to learn.</p> <p>I use tools that I think are the most popular ones.</p> </details> <details> <summary>It looks good for development. What about production?</summary> <br> <p>I'm not a DevOps, but I have a vision how to deploy this code to production.</p> <p>Right now it is not described somehow. It is in my plans.</p> </details> ### TODO <details> <summary>Show details</summary> - Nginx - Production roll up - Action Cable [Link](https://guides.rubyonrails.org/action_cable_overview.html) </details> ## Sponsorship These amazing companies and teams support the project: <table width="100%"> <thead> <tr> <th>JetBrains.com</th> <th>Hoodies.team</th> </tr> </thead> <tbody> <tr> <td><img width="200px" src="./Rails7StartKit/assets/logos/JB-logo.png" /></td> <td><img width="200px" src="./Rails7StartKit/assets/logos/Hoodies-logo.svg" /></td> </tr> </tbody> </table> # License [MIT License. 2023. Ilya N. Zykin](./LICENSE.md) ", Assign "at most 3 tags" to the expected json: {"id":"838","tags":[]} "only from the tags list I provide: [{"id":77,"name":"3d"},{"id":89,"name":"agent"},{"id":17,"name":"ai"},{"id":54,"name":"algorithm"},{"id":24,"name":"api"},{"id":44,"name":"authentication"},{"id":3,"name":"aws"},{"id":27,"name":"backend"},{"id":60,"name":"benchmark"},{"id":72,"name":"best-practices"},{"id":39,"name":"bitcoin"},{"id":37,"name":"blockchain"},{"id":1,"name":"blog"},{"id":45,"name":"bundler"},{"id":58,"name":"cache"},{"id":21,"name":"chat"},{"id":49,"name":"cicd"},{"id":4,"name":"cli"},{"id":64,"name":"cloud-native"},{"id":48,"name":"cms"},{"id":61,"name":"compiler"},{"id":68,"name":"containerization"},{"id":92,"name":"crm"},{"id":34,"name":"data"},{"id":47,"name":"database"},{"id":8,"name":"declarative-gui "},{"id":9,"name":"deploy-tool"},{"id":53,"name":"desktop-app"},{"id":6,"name":"dev-exp-lib"},{"id":59,"name":"dev-tool"},{"id":13,"name":"ecommerce"},{"id":26,"name":"editor"},{"id":66,"name":"emulator"},{"id":62,"name":"filesystem"},{"id":80,"name":"finance"},{"id":15,"name":"firmware"},{"id":73,"name":"for-fun"},{"id":2,"name":"framework"},{"id":11,"name":"frontend"},{"id":22,"name":"game"},{"id":81,"name":"game-engine "},{"id":23,"name":"graphql"},{"id":84,"name":"gui"},{"id":91,"name":"http"},{"id":5,"name":"http-client"},{"id":51,"name":"iac"},{"id":30,"name":"ide"},{"id":78,"name":"iot"},{"id":40,"name":"json"},{"id":83,"name":"julian"},{"id":38,"name":"k8s"},{"id":31,"name":"language"},{"id":10,"name":"learning-resource"},{"id":33,"name":"lib"},{"id":41,"name":"linter"},{"id":28,"name":"lms"},{"id":16,"name":"logging"},{"id":76,"name":"low-code"},{"id":90,"name":"message-queue"},{"id":42,"name":"mobile-app"},{"id":18,"name":"monitoring"},{"id":36,"name":"networking"},{"id":7,"name":"node-version"},{"id":55,"name":"nosql"},{"id":57,"name":"observability"},{"id":46,"name":"orm"},{"id":52,"name":"os"},{"id":14,"name":"parser"},{"id":74,"name":"react"},{"id":82,"name":"real-time"},{"id":56,"name":"robot"},{"id":65,"name":"runtime"},{"id":32,"name":"sdk"},{"id":71,"name":"search"},{"id":63,"name":"secrets"},{"id":25,"name":"security"},{"id":85,"name":"server"},{"id":86,"name":"serverless"},{"id":70,"name":"storage"},{"id":75,"name":"system-design"},{"id":79,"name":"terminal"},{"id":29,"name":"testing"},{"id":12,"name":"ui"},{"id":50,"name":"ux"},{"id":88,"name":"video"},{"id":20,"name":"web-app"},{"id":35,"name":"web-server"},{"id":43,"name":"webassembly"},{"id":69,"name":"workflow"},{"id":87,"name":"yaml"}]" returns me the "expected json"