Configure credentials
The next thing that's stopping us from charging money and delivering our software service right away is configuring the app to use our credentials.
We need, for example, to configure our Stripe API keys in the project so we can start processing payments; or our S3 access keys so we can upload and save attachments like user avatars.
Credentials are secure and encrypted
Credentials in RailsFast are encrypted. They can only be decrypted with the random encryption key (config/master.key) that was generated uniquely for you upon project setup (when we ran bin/railsfast init in the quickstart). This is a secure way to store private & sensitive credentials like access and API keys, without risking leaking them in plaintext in the codebase. No one can read your credentials even if they get access to the encrypted file (credentials.yml.enc), because they don't have the decryption key.
Never commit or make public your master.key file. It is already in the .gitignore to avoid it getting accidentally commited, so don't change that. Use the same caution for any other .key file in the project.
How to edit the encrypted credentials file
The RailsFast setup also generated a sample credentials file for you, to help you understand how the credentials file should be used in your project.
You'll see it's very straightforward. To view and edit your project credentials, run:
EDITOR="cursor --wait" bin/rails credentials:edit
And you'll view the decrypted credentials, ready to edit.
To save changes after editing, just save the file and close it, and the credentials will automatically get encrypted back, ready to be used by your app.
How the credentials file is organized
If you look at the credentials file, you'll see it's organized by environments: shared, production, and development.
You may (and probably should) have different credentials for your development and production environments. For example, for Stripe, you should use your sandbox / test keys in development; and you should only use the live keys in production, exclusively.
"Production" just means "your server": the environment where your project is live and ready to be used by other people. As opposed to "development": where the project is only running in your local development computer, and only accessible by you.
For some other services, this production vs development distinction may not make much sense, so to avoid duplication you can just put those credentials under the shared block, and both production and development will get them automatically.
I've included a sample demoservice to showcase how shared credentials work. You can also override any part of a shared credentials block like demoservice per environment, while the rest will be kept the same. In any case, demoservice is just there for demoing purposes: you can remove it.
Add all the necessary credentials
If you followed the Prerequisites section, you should already have accounts in all the key services we're going to use, so now it's just a matter of going service by service generating the right keys and plugging them in the right place.
For your RailsFast app to fully work, we'll need at least:
-
AWS: we'll just use AWS SES for sending emails. I'm not a fan of AWS, but SES is probably the cheapest & most reliable emailing service out there.
- Inside your AWS Dashboard, navigate to
AWS SES(Simple Email Service)- Add your domain in SES > Configuration > Identities and create all required DNS records
- For more detailed instructions, follow our perfect emailing guide and you'll also achieve a 10/10 deliverability score in your emails
- Now move away from SES and navigate to AWS IAM to generate an Access Key and Secret Access Key for SES
- Create a new IAM user
- Name it something descriptive like
yourprojectname-production - Give it enough SES permissions to send emails
- To do that, create a new policy, click on the [ Create policy ] button
- In the "Specify permissions window, switch from "Visual" to "JSON" and paste the following contents:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "ses:SetIdentityMailFromDomain", "ses:SendEmail", "ses:SendTemplatedEmail", "ses:SendCustomVerificationEmail", "ses:SendRawEmail", "ses:SendBulkTemplatedEmail", "ses:SetIdentityDkimEnabled", "ses:SetActiveReceiptRuleSet" ], "Resource": "*" } ] }- Give it a descriptive name like
ses-send-email-policyand create the policy
- Back on the create user screen, attach the new created policy to the user, and create it
- Once the user is created, click it to access the user details screen, navigate to the "Security credentials" tab, and create a new Access Key. When asked, select "Other" as your reason (your reason is direct AWS API calls, but that's not listed)
- Create the Access Key and copy the access key and private key to your RailsFast project's credentials file
- Inside your AWS Dashboard, navigate to
-
Cloudflare: DNS + DDoS protection, Turnstile for anti-bot signups, R2 for S3-compatible storage (for storing avatars, user uploads, etc.)
- R2: create an R2 bucket for your project. Then, on the R2 Overview screen, under the Account Details box, you'll see the "API Tokens" row and next to it, a
{Manage}button, click it. Now in the Manage R2 API tokens screen, create a User API Token for your bucket (give itObject Read & Writepermissions, click "Apply to specific buckets only" and specify just your bucket). Create the API Token and copy and paste theaccount_id,access_key_id,secret_access_keyand bucket name, and paste them in the right place in your credentials file. Go back to the R2 Overview screen, copy your Cloudflare account ID and paste it in the corresponding spot in the credentials file too. You only need to do this forproduction, not fordevelopment. - Turnstile: create a Turnstile widget to get your Turnstile site key and secret key. This will be used to protect your auth / signup forms from bots. As with R2, Turnstile credentials are only needed in
production, not indevelopment. You just need the site and secret keys, you don't need to do anything else with the widget, all is already configured and wired in RailsFast for you.
- R2: create an R2 bucket for your project. Then, on the R2 Overview screen, under the Account Details box, you'll see the "API Tokens" row and next to it, a
-
Stripe: payment processing
- Generate a publishable and a private key (both in live and sandbox mode, for
productionanddevelopment, respectively) - Create a webhook in live mode (webhook URL:
https://YOUR-DOMAIN-HERE/pay/webhooks/stripe), and add the webhook signing secret inproduction - Install the Stripe CLI and add the development webhook signing secret to
development
- Generate a publishable and a private key (both in live and sandbox mode, for
Configure database backups
RailsFast ships by default with automatic database backups. All your user's data gets backed up regularly outside of your server, so in case of disaster you can recover all your data and put your app back up. However, for this to work you need to let your app know where those backups should be uploaded to.
Luckily for us, we can use any S3-compatible storage solution for this. So, since we already have an AWS and a Cloudflare account, we could just use AWS S3 or Cloudflare R2 for our backups and be done with it. There's nothing wrong with that.
However, if you're like me and you want to add an extra bit of resilience to your setup (in the improbable case your AWS or Cloudflare accounts get compromised because you're already using them for other things), you can keep your backups in a completely different service that we're only going to use for backups. I use Backblaze B2 for that. Backblaze B2 is S3-compatible just like AWS S3 or Cloudflare R2, and they also have a free tier that makes your backups free or close to free as long as they're not too big.
Whatever the service you end up using for storing backups (again, AWS S3 and Cloudflare R2 are both good options if you don't want to complicate things early), you just need to add the S3-compatible credentials in the designated files under config/backups:
s3_access_key.keys3_bucket.keys3_region.keys3_secret_access_key.key
These credentials are the same for any S3-compatible storage service. Just replace the placeholder text in each file with your credentials, re-deploy the backups service with kamal accessory reboot pg-backup, and you'll be automatically backing up your entire production database every night.
If you want to adjust when to do backups, how often to do them, and how many backups to keep, you just need to adjust the pg-backup config in config/deploy.yml. Make sure to reboot the backups service after you make changes:
kamal accessory reboot pg-backup
We're using the kartoza/pg-backup Docker image for database backups. It's already wired up and configured to work with your credentials. It's also configured as a Kamal accessory so you can easily manage it as shown above. Read their docs to know more about available backup options.