mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-03-25 01:14:43 +00:00
218 lines
11 KiB
Markdown
218 lines
11 KiB
Markdown
# README
|
|
This application is being created to run a wrestling tournament.
|
|
|
|
# Info
|
|
**License:** MIT License
|
|
|
|
**Public Production Url:** [https://wrestlingdev.com](https://wrestlingdev.com)
|
|
|
|
**App Info**
|
|
* Ruby 3.2.0
|
|
* Rails 8.0.2
|
|
* DB MySQL/MariaDB
|
|
* Solid Cache -> MySQL/MariaDB for html partial caching
|
|
* Solid Queue -> MySQL/MariaDB for background job processing
|
|
* Solid Cable -> MySQL/MariaDB for websocket channels
|
|
* Hotwired Stimulus for client-side JavaScript
|
|
|
|
# Development
|
|
|
|
## Develop with docker
|
|
All dependencies are wrapped in docker. Tests can be run with `bash bin/run-tests-with-docker.sh`. That is the same command used in CI.
|
|
|
|
If you want to run a full rails environment shell in docker run: `bash bin/rails-dev-run.sh wrestlingdev-dev`
|
|
From here, you can run the normal rails commands.
|
|
|
|
Special rake tasks:
|
|
* `tournament:assign_random_wins` will complete all matches for tournament 204 from seed data. This task takes a while since it waits for the worker to complete tasks. In my testing, it takes about 3.5 hours to complete.
|
|
* `rake tournament:assign_random_wins` to run locally
|
|
* `docker-compose -f deploy/docker-compose-test.yml exec -T app rails tournament:assign_random_wins` to run on the dev server
|
|
|
|
To deploy a full local version of the app `bash deploy/deploy-test.sh` (this requires docker-compose to be installed). This deploys a full version of the app including Rails app, Solid Queue background workers, Memcached, and MariaDB. Now, you can open [http://localhost](http://localhost).
|
|
|
|
In development environments, background jobs run inline (synchronously) by default. In production and staging environments, jobs are processed asynchronously by separate worker processes.
|
|
|
|
To run a single test file:
|
|
1. Get a shell with ruby and rails: `bash bin/rails-dev-run.sh wrestlingdev-development`
|
|
2. `rake test TEST=test/models/match_test.rb`
|
|
|
|
To run a single test inside a file:
|
|
1. Get a shell with ruby and rails: `bash bin/rails-dev-run.sh wrestlingdev-development`
|
|
2. `rake test TEST=test/models/match_test.rb TESTOPTS="--name='/test_Match_should_not_be_valid_if_an_incorrect_win_type_is_given/'"`
|
|
|
|
## Develop with rvm
|
|
With rvm installed, run `rvm install ruby-3.2.0`
|
|
Then, `cd ../; cd wrestlingApp`. This will load the gemset file in this repo.
|
|
|
|
## Quick Rails Commands Without Local Installation
|
|
You can run one-off Rails commands without installing Rails locally by using the development Docker image:
|
|
|
|
```bash
|
|
# Build the development image
|
|
docker build -t wrestlingdev-dev -f deploy/rails-dev-Dockerfile .
|
|
|
|
# Run a specific Rails command
|
|
docker run -it -v $(pwd):/rails wrestlingdev-dev rails db:migrate
|
|
|
|
# Run the Rails console
|
|
docker run -it -v $(pwd):/rails wrestlingdev-dev rails console
|
|
|
|
# Run a custom Rake task
|
|
docker run -it -v $(pwd):/rails wrestlingdev-dev rake jobs:create_running
|
|
```
|
|
|
|
This approach is useful for quick commands without the need to set up a full development environment. The image contains all required dependencies for the application.
|
|
|
|
For a more convenient experience with a persistent shell, use the included wrapper script:
|
|
|
|
```bash
|
|
bash bin/rails-dev-run.sh wrestlingdev-dev
|
|
```
|
|
|
|
## Rails commands
|
|
Whether you have a shell from docker or are using rvm you can now run normal rails commands:
|
|
* `bundle config set --local without 'production'`
|
|
* `bundle install`
|
|
* `rake db:seed` Development login email from seed data: `test@test.com` password: `password`
|
|
* `rake test`
|
|
* `rails generate blah blah blah`
|
|
* ` rails s -b 0.0.0.0` port 3000 is exposed. You can open [http://localhost:3000](http://localhost:3000) after running that command
|
|
* etc.
|
|
* `rake finish_seed_tournaments` will complete all matches from the seed data. This command takes about 5 minutes to execute
|
|
* `rake assets:clobber` - removes previously compiled assets stored in `public/assets` forcing Rails to recompile them from scratch the next time they are requested.
|
|
|
|
## Testing Job Status
|
|
|
|
To help with testing the job status display in the UI, several rake tasks are provided:
|
|
|
|
```bash
|
|
# Create a test "Running" job for the first tournament
|
|
rails jobs:create_running
|
|
|
|
# Create a test "Completed" job for the first tournament
|
|
rails jobs:create_completed
|
|
|
|
# Create a test "Error" job for the first tournament
|
|
rails jobs:create_failed
|
|
```
|
|
|
|
See `SOLID_QUEUE.md` for more details about the job system.
|
|
|
|
## Update gems
|
|
|
|
1. `bash bin/rails-dev-run.sh wrestlingdev-dev` to open a contianer with a rails shell available
|
|
2. `bundle config --delete without` to remove the bundle config that ignores production gems
|
|
3. `bundle update`
|
|
4. `bundle config set --local without 'production'` to reset your without locally
|
|
|
|
Note: If updating rails, do not change the version in `Gemfile` until after you run `bash bin/rails-dev-run.sh wrestlingdev-dev`. Creating the container will fail due to a mismatch in Gemfile and Gemfile.lock.
|
|
Then run `rails app:update` to update rails.
|
|
|
|
## Stimulus Controllers
|
|
|
|
The application uses Hotwired Stimulus for client-side JavaScript interactivity. Controllers can be found in `app/asssets/javascripts/controllers`
|
|
|
|
### Testing Stimulus Controllers
|
|
|
|
The Stimulus controllers are tested using Cypress end-to-end tests:
|
|
|
|
```bash
|
|
# Run Cypress tests in headless mode
|
|
bash cypress-tests/run-cypress-tests.sh
|
|
```
|
|
|
|
# Deployment
|
|
|
|
The production version of this is currently deployed in Kubernetes (via K3s). See [Deploying with Kubernetes](deploy/kubernetes/README.md)
|
|
|
|
I'm using a Hetzner dedicated server with an i7-8700, 500GB NVME (RAID1), and 64GB ECC RAM. I have a hot standby (SQL read only replication) in my homelab.
|
|
|
|
## Server Configuration
|
|
|
|
### Puma and SolidQueue
|
|
|
|
The application uses an intelligent auto-scaling configuration for Puma (the web server) and SolidQueue (background job processing):
|
|
|
|
- **Auto Detection**: The server automatically detects available CPU cores and memory, and scales accordingly.
|
|
- **Worker Scaling**: In production, the number of Puma workers is calculated based on available memory (assuming ~400MB per worker) and CPU cores.
|
|
- **Thread Configuration**: Each Puma worker uses 5-12 threads by default, optimized for mixed I/O and CPU workloads.
|
|
- **SolidQueue Integration**: When `SOLID_QUEUE_IN_PUMA=true`, background jobs run within the Puma process.
|
|
- **Database Connection Pool**: Automatically sized based on the maximum number of threads across all workers.
|
|
|
|
All of these settings can be overridden with environment variables if needed.
|
|
|
|
To see the current configuration in the logs, look for these lines on startup:
|
|
```
|
|
Puma starting with X worker(s), Y-Z threads per worker
|
|
Available system resources: X CPU(s), YMMMB RAM
|
|
SolidQueue plugin enabled in Puma
|
|
```
|
|
|
|
I have deployed Mission Control as a UI for SolidQueue. The uri for mission control is `/jobs`.
|
|
For the development environment, the user/password is dev/secret. For the production environment, it is defined by environment variables WRESTLINGDEV_MISSION_CONTROL_USER/WRESTLINGDEV_MISSION_CONTROL_PASSWORD. You can see this in `config/environments/production.rb` and `config/environments/development.rb`.
|
|
|
|
## Environment Variables
|
|
|
|
### Required Environment Variables
|
|
* `WRESTLINGDEV_DB_NAME` - Database name for the main application
|
|
* `WRESTLINGDEV_DB_USR` - Database username
|
|
* `WRESTLINGDEV_DB_PWD` - Database password
|
|
* `WRESTLINGDEV_DB_HOST` - Database hostname
|
|
* `WRESTLINGDEV_DB_PORT` - Database port
|
|
* `WRESTLINGDEV_DEVISE_SECRET_KEY` - Secret key for Devise (can be generated with `rake secret`)
|
|
* `WRESTLINGDEV_SECRET_KEY_BASE` - Rails application secret key (can be generated with `rake secret`)
|
|
* `WRESTLINGDEV_EMAIL` - Email address (currently must be a Gmail account)
|
|
* `WRESTLINGDEV_EMAIL_PWD` - Email password
|
|
* `WRESTLINGDEV_MISSION_CONTROL_USER` - mission control username
|
|
* `WRESTLINGDEV_MISSION_CONTROL_PASSWORD` - mission control password
|
|
|
|
### Optional Environment Variables
|
|
* `SOLID_QUEUE_IN_PUMA` - Set to "true" to run Solid Queue workers inside Puma (default in development)
|
|
* `WEB_CONCURRENCY` - Number of Puma workers (auto-detected based on CPU/memory if not specified)
|
|
* `RAILS_MIN_THREADS` - Minimum number of threads per Puma worker (defaults to 5)
|
|
* `RAILS_MAX_THREADS` - Maximum number of threads per Puma worker (defaults to 12)
|
|
* `DATABASE_POOL_SIZE` - Database connection pool size (auto-calculated if not specified)
|
|
* `SOLID_QUEUE_WORKERS` - Number of SolidQueue workers (auto-calculated if not specified)
|
|
* `SOLID_QUEUE_THREADS` - Number of threads per SolidQueue worker (auto-calculated if not specified)
|
|
* `PORT` - Port for Puma server to listen on (defaults to 3000)
|
|
* `RAILS_LOG_LEVEL` - Log level for Rails in production (defaults to "info")
|
|
* `PIDFILE` - PID file location for Puma
|
|
* `RAILS_SSL_TERMINATION` - Set to "true" to enable force_ssl in production (HTTPS enforcement)
|
|
* `REVERSE_PROXY_SSL_TERMINATION` - Set to "true" if the app is behind a SSL-terminating reverse proxy
|
|
* `CI` - Set in CI environments to enable eager loading in test environment
|
|
* `WRESTLINGDEV_NEW_RELIC_LICENSE_KEY` - New Relic license key for monitoring
|
|
|
|
### InfluxDB Configuration (all required if using InfluxDB)
|
|
* `WRESTLINGDEV_INFLUXDB_DATABASE` - InfluxDB database name
|
|
* `WRESTLINGDEV_INFLUXDB_HOST` - InfluxDB hostname
|
|
* `WRESTLINGDEV_INFLUXDB_PORT` - InfluxDB port
|
|
* `WRESTLINGDEV_INFLUXDB_USERNAME` - InfluxDB username (optional)
|
|
* `WRESTLINGDEV_INFLUXDB_PASSWORD` - InfluxDB password (optional)
|
|
|
|
This project provides multiple ways to develop and deploy, with Docker being the primary method.
|
|
|
|
# Frontend Assets
|
|
|
|
## Sprockets to Propshaft Migration
|
|
|
|
- Propshaft will automatically include in its search paths the folders vendor/assets, lib/assets and app/assets of your project and of all the gems in your Gemfile. You can see all included files by using the reveal rake task: `rake assets:reveal`. When importing you'll use the relative path from this command.
|
|
- All css files are imported via `app/assets/stylesheets/application.css`. This is imported on `app/views/layouts/application.html.erb`.
|
|
- Bootstrap and fontawesome have been downloaded locally to `vendor/`
|
|
- All js files are imported with a combination of "pinning" with `config/importmaps.rb` and `app/assets/javascript/application.js` and imported to `app/views/layouts/application.html.erb`
|
|
- Jquery, bootstrap, datatables have been downloaded locally to `vendor/`
|
|
- Turbo and action cable are gems and get pathed properly by propshaft.
|
|
- development is "nobuild" with `config.assets.build_assets = false` in `config/environments/development.rb`
|
|
- production needs to run rake assets:precompile. This is done in the `deploy/rails-prod-Dockerfile`.
|
|
|
|
## Stimulus Implementation
|
|
|
|
The application has been migrated from using vanilla JavaScript to Hotwired Stimulus. The Stimulus controllers are organized in:
|
|
|
|
- `app/assets/javascripts/controllers/` - Contains all Stimulus controllers
|
|
- `app/assets/javascripts/application.js` - Registers and loads all controllers
|
|
|
|
The importmap configuration in `config/importmap.rb` handles the loading of all JavaScript dependencies including Stimulus controllers.
|
|
|
|
# Using Repomix with LLMs
|
|
`npx repomix app test`
|