A slightly opinionated template for getting you to your mvp as fast as possible!!!
This project uses docker for development has two main components:
ui
- A typescript-react app that powers the front-end for the app.api
- A rails api-only app that powers the back-end for the app.
The api
component is supported by a postgresql docker instance. There is an nginx
reverse proxy thats acts as an edge server between the developer's machine and these docker containers.
Features
- React with typescript
- Rails 7 api mode backend
ruby 3.1.0
nodejs 16.13.0
- Docker for development
- Postgresql for persistence
- Secret management with rails encrypted credentials
- Rubocop + eslint for linting
- CircleCI configuration (coming soon)
Take it all the way to production!
- AWS ECR for Docker image registry
- Lets Encrypt for SSL CA certs
- Kubernetes for container orchestration with EKS
- AWS Cloud services for deployment with Terraform
- DataDog for observability with Terraform
┌──────────────┐
│ │
│ │
┌───────┐ │ ui │
│ │ ┌───────► │
│ │ │ │ │
┌─────────┐ │ │ │ └──────────────┘
│ local │ │ │ │
│ machine ├───────────► nginx ├─────┤
│ │ │ │ │
├─────────┤ │ │ │ ┌──────────────┐ ┌──────────────┐
│┼┼┼┼┼┼┼┼┼│ │ │ │ │ │ │ │
└─────────┘ │ │ └───────► ├────────► │
│ │ │ api │ │ postgresql │
└───────┘ │ │ │ │
│ │ │ │
└────---───────┘ └──────────────┘
git clone <git url for your repo created from this template> && cd <your dir>
echo "RAILS_MASTER_KEY=$(hexdump -vn16 -e'4/4 "%08X" 1 "\n"' /dev/urandom)" > .env
docker-compose up -d
Then visit http://localhost:5050. api
container might take a few minutes to start for the first time.
- Install
docker
if required. https://www.docker.com/ - Create three 32-bit hex codes randomly and make note of them in a secure place. This is your master keys for all your environments so avoid committing this into your github.
- One for development env. This is to be shared with every developer in your team.
- One for test env. This is to be shared with every developer in your team.
- One for production env. This is to be shared with members with production access only.
- Create
.env
file in the project root and addRAILS_MASTER_KEY=development key from step 2
. - Run
docker-compose up
. Add-d
option to run in detached mode. - http://localhost:5050
All dependencies and required libs for this app live completely in the docker container and isolated from your host machine. This means all the rails and npm commands must be run inside a shell process in the container.
- Add new gem to
Gemfile
- Run
docker exec api bundle install
. All new changes to theGemfile.lock
file must be committed to git
- Run
docker exec api bundle exec rails new migration <name of migration>
- Run
docker exec api bundle exec rails db:migrate
. All new changes to theschema.rb
file must be committed to git
- Run
docker exec api bundle exec rails test
- Alternatively use the
./shell
executable inapi
to enter the container's bash shell to run individual tests
- Add new package to
package.json
- Run
docker exec ui npm install
. All new changes to thepackage-lock.json
file must be committed to git
- Run
docker exec ui npm run test
- Alternatively use the
./shell
inui
executable to enter the container's bash shell to run individual tests
In api
Rails 7 app - There are two important keys by default:
-
Master key: This is used to encrypt a file called
api/config/credentials.yml.enc
. This file stores an encrypts version of every secret you want to use in your rails app in a particular environment. This should never be committed to your version control. By default at runtime Rails checks for the value of this master in key in the following order:ENV["RAILS_MASTER_KEY"]
config/master.key
file
-
Secret Key Base: This key the default secret key that comes up with a fresh rails app. This is used to sign and encrypt session cookies. By default in development Rails randomly generates one on the fly and stores it in
api/tmp/development_secret.txt
. In other environments - In all other environments, we look for it the following order:ENV["SECRET_KEY_BASE"]
Rails.application.credentials.secret_key_base
This is from theconfig/credentials.yml.enc
. The location of this file can vary in different environments. You can commit this file to git or vcs without any worries - even for production as long as master key remains secure.Rails.application.secrets.secret_key_base
This is basically for backwards compatibility with older rails versions. This comes from when we stores secrets insecrets.yml
files. For most applications, the correct place to store it is in the encrypted credentials file. The location of the secrets file varies in different environment.
So if you want to add any other secrets you can just simple add a new key into the yml.enc
file using rails binaries. This is the recommended practice. Read this for more info...
For other environment file precendence orders, Read this
The advantage of this is that the secrets can also be version controlled but better management.
- Copy the master key pertaining to your environment into your clipboard.
- Run
api/shell
to enter the shell for api container. - Run
RAILS_MASTER_KEY=<master key of the environment> bundle exec rails credentials:edit --environment <developent|test|production>
. The--environment
flag is important to place encrypted credential files in the correct directory. - This opens up a nano instance with a
.yml
file loaded add any secrets to the file and save. This creates an<env>.yml.enc
if its doesnt exist and saves your credentials there. If it does exists it modifies the file. - Access this secret in your code using
Rails.application.credentials.<key>
. - Make sure you commit any
<env>.yml.enc
you generate or mutate. This is encrypted by your master key so it should be safe as long as your master key is not compromised. - If your master key is compromised then you must rotate every credential in your
<env>.yml.enc
file. - To deploy secrets in production make sure to commit
production.yml.enc
into your vcs before deploying the code version. As long as its the correct key it should be decrypted at runtime in production.