A modern BitTorrent tracker built with Rails 8.1, featuring:
- BitTorrent announce/scrape endpoints for peer discovery
- GraphQL API with JWT authentication for user and torrent management
- Torrent categorization system
- Real-time statistics tracking
- Automated peer cleanup and stats updates via background jobs
Note: This is a toy project created to get back into Ruby development after more than a year away from Ruby coding. It is not production-ready and is intended for learning and experimentation purposes only.
- Ruby 4.0.0 and Bundler
- PostgreSQL 16+ and Redis 7 (docker-compose.yml provides both)
SECRET_KEY_BASE(or Rails credentials) for JWT signingDATABASE_*environment variables to override local DB defaults
- Install gems:
bundle install - Boot services:
docker compose up -d postgres redis - Prepare the DB:
bin/rails db:setup - Start the app:
bin/rails server(orbin/devfor development with auto-reload) - Run background jobs:
bin/rails solid_queue:start(or usebin/jobsfor recurring jobs)
Run the full development environment:
docker compose upThe project includes Docker and Kamal configuration for production deployment.
Build and run with Docker:
docker compose -f docker-compose.prod.yml up -dEnsure these environment variables are set:
SECRET_KEY_BASEDATABASE_URLREDIS_URL
bundle exec rspec
BitTorrent clients use these endpoints for peer discovery and statistics.
GET /announce
Required parameters:
info_hash- Torrent info hash (40-character hex or 20-byte raw)peer_id- Unique peer identifier (20 bytes)port- Client listening portuploaded- Total bytes uploadeddownloaded- Total bytes downloadedleft- Bytes remaining to downloaduser_id- User ID for authentication
Optional parameters:
event- One of:started,completed,stopped
Response: Bencoded dictionary with peer list and tracker interval
Example:
curl "http://localhost:3000/announce?info_hash=0123456789abcdef0123456789abcdef01234567&peer_id=ABCDEFGHIJKLMNOPQRST&port=6881&uploaded=0&downloaded=0&left=12345&event=started&user_id=1"GET /scrape
Parameters:
info_hash- One or multiple info hashes to query
Response: Bencoded dictionary with stats (seeders, leechers, completed) per torrent
Example:
curl "http://localhost:3000/scrape?info_hash=0123456789abcdef0123456789abcdef01234567"GraphQL endpoint for managing users, torrents, and categories.
- Endpoint:
POST /graphql - Authentication:
Authorization: Bearer <JWT_token> - Introspection: Available in development mode for exploring the schema
Refer to the GraphQL schema introspection or the source files in app/graphql/ for detailed documentation on each operation.
The application uses Solid Queue for background job processing. See app/jobs/ for individual job documentation.
Job Management:
# Start job worker
bin/rails solid_queue:start
# Run jobs with recurring schedule
bin/jobs
# Monitor jobs
bin/rails solid_queue:statusRecurring job schedule is configured in config/recurring.yml.
Code quality tools:
# Run test suite
bundle exec rspec
# Security audit
bin/brakeman
bin/bundler-audit
# Code style
bin/rubocop
# Full CI check
bin/ciSee LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Run the CI checks:
bin/ci - Submit a pull request