A Ruby on Rails monolith with React and Ember front-ends that powers panOpen's digital courseware platform. The repository now ships with a sanitized, open-source friendly workflow: secrets are stored outside the tree, Docker is the recommended runtime, and documentation explains how to stand up a local environment without access to internal services.
- Backend: Ruby 2.6.10, Rails 5.2, PostgreSQL, Redis, Sidekiq, Elasticsearch
- Front-end: React bundles in
client/, Ember app infaculty-client/, legacy Sprockets assets - Build & Tooling: Webpack, Yarn/NPM, Docker/Compose, Capistrano (optional), RSpec, Karma/Jasmine, Ember QUnit
- Install Docker Desktop (or Docker Engine on Linux) and Make.
- Copy the template env/config files:
cp .env.example .env cp config/database.example.yml config/database.yml
- Fill in any secrets in
.env(Rails master key, AWS keys, OAuth credentials). Never commit this file—git already ignores.env, so keep your populated copy in a safe, private location (password manager, encrypted disk, etc.). - Bootstrap everything with the helper script:
./docker-setup.sh
- Bring the stack up:
docker compose up --build
- Rails lives on
http://localhost:3000, Webpack dev server onhttp://localhost:8080.
See DOCKER_README.md for a full break-down of services, troubleshooting, and data import tips.
- Install prerequisites: Ruby 2.6.10 (rbenv/rvm), Bundler ≥ 2.3.26, Node 10.24.x via
nvm, Yarn/NPM, PostgreSQL ≥ 12, Redis ≥ 4, Elasticsearch ≥ 7.9, wkhtmltopdf. - Install gems and JS deps:
bundle install npm install (cd client && npm install) (cd faculty-client && npm install && bower install)
- Copy the sample env/database files as shown above and update them for your machine.
- Run services locally (
postgres,redis,elasticsearch) and then:bundle exec rails db:setup foreman start -f Procfile.dev
- Keep non-public artifacts (real
.env, AWS infrastructure notes, database dumps) outside the repository. By default.gitignoreexcludes.envand anysecret_files/directory you create locally. - Public templates (
.env.example,config/database.example.yml) define the required variables without bundling real credentials. - Initializers fetch tokens from
Rails.application.credentialsorENV; never hard-code them. - Capistrano’s EC2 integration is disabled unless you set
CAP_EC2_ENABLED=true. Leave it unset for open-source deployments to avoid referencing private AWS accounts. - If you discover additional sensitive assets (customer data, S3 dumps, etc.), delete them or move them into private infrastructure before publishing.
- Rails server:
bin/rails server - Webpack dev server:
cd client && npm run hot - Sidekiq:
bundle exec sidekiq - ElasticSearch reindex:
Then
Note.__elasticsearch__.create_index! force: true Page.__elasticsearch__.create_index! force: true
bundle exec rake books:copy_to_es. - PII scrubbing (sample data):
bundle exec rake clean:remove_pii
bundle exec rspec # Rails specs
bin/rails test # Minitest legacy suite
npm run test # React tests
(cd faculty-client && ember test)
npm run lint && npm run lint-ember
npm audit && bundle auditCI configuration lives under .github/workflows/ (see below) and runs the same commands.
Architecture.md– high-level system mapDEV_SETUP.md– verbose local setup, common issuesDEPLOYMENT.md– Docker image build/deploy workflowDOCKER_README.md– containerized environment referencelicenses/THIRD-PARTY.md– attribution for bundled OSSAWS_INFRASTRUCTURE.md– sanitized guidance; keep detailed runbooks in a private, access-controlled location
- Read
CONTRIBUTING.mdfor branch, commit, and PR expectations. - Follow the
CODE_OF_CONDUCT.mdand report issues perSECURITY.md. - Submit bug reports and feature requests via the templates in
.github/ISSUE_TEMPLATE/.
The panOpen Rails application is licensed under GNU AGPL v3.0 or later with the AGPL §7 attribution requirement described in LICENSE and ATTRIBUTION.md (display “Designed & Built by panOpen Education - https://panopen.com” in the UI). A copy of the license text lives in licenses/AGPL-3.0.txt. Contact support@panopen.com for commercial/white-label terms that permit removing the attribution.