Deploying Cart Compass

Rick Glascock
5 min readSep 27, 2020

--

It’s week three of Shopping List (Cart Compass) development and, while it’s not quite ready for prime time, it’s getting closer.

The Story:

Our family has worked out week long cooking assignments for each of us. I’m not a big fan of hanging out in the local grocery store, so I wanted a shopping list that would allow me to add items, by category, and then reorder the categories to correspond to the layout of my local HEB (if you’ve ever lived in Texas, you know about HEB!). With the list in hand I can navigate the sections quickly, knowing that I won’t have to back track later on.

Features:
- The user can have more than one list (can create and delete lists).
- The user’s current list ( the list whose contents are displayed) is saved and can be changed.
- The user can add new items to the current list, and if that item is new, it will be added to a master list, which will in turn be shown as a search result the next time the user wants to add that item.
- Saved items can be deleted from the master list. (Maybe you’ve discovered Brussel sprouts aren’t your thing).
- The user can dynamically rearrange (drag and drop) the order that categories are displayed.
- The users information is persisted in a database.

Today I’ll give a run down of the process of deploying the app. I deployed the Rails API to Heroku. Heroku has made the process fairly painless by now, but there are a few tricks. Because this is just a personal project, I’ve opted to use a free account. The big drawback to the free accounts is that the dynos (essentially the virtual servers) go to sleep after a certain period of inactivity to save processes. Waking them up can take 8–9 seconds, which can be annoying, but understandable (you get what you pay for). If you have a good loading indicator on the front end, the delay seems less ominous. To bump your app to the ‘Hobby’ level will cost you $7 a month as of this writing.

First you’ll need a Heroku account and to download the Heroku CLI:

From your project’s local folder (I pull up a terminal in VSCode) you’ll need to login using:
heroku login — interactive
entering the email and password you used to sign up.
Once you’re setup and logged in, and your project’s main branch has been pushed to GitHub, you can create the Heroku app using:
heroku create <app-name>

The app name needs to be unique.
You can verify that the app has been created and that your local repo is linked to the Heroku remote with:
git heroko //should list heroku

You can push the branch using:
git push heroku master
You'll also need to migrate and, if you want, seed the Postgres DB:
heroku run rails db:migrate
heroku run rails db:seed

Now you can point your browser to dashboard.heroku.com/apps and you should be able to see the app listed in your main dashboard. Click on the app to see the app’s individual dashboard. On the right pane of the ‘Overview’ page you should see the result of your recent deployment. These should be an entry for the build (the process of setting up your Rails API in a production environment) and its actual deployment. Click on the “Open App” button to load your API’s public URL. If you navigate to a viable endpoint (for instance - https://my-app.com/api/v1/users) you should see the results of a GET request if it exists in your API and isn’t protected.

Click on the app’s ‘Settings’ tab and you will find a place to change the app’s name. If you change the name here, the app will no longer be synched to your local repo. There’s a process for reconnecting, but for now, best to stick with the name.
Also on this page you will see ‘Reveal Config Variables’. Click on the button and you can see the Environment variables (a series of key/value pairs) that Heroku automatically sets up for a Rails API build with a Postgres DB. Included is a SECRET_KEY_BASE. This value (or any other value you replace it with) can be accessed in your API’s code using:
Rails.application.secret_key_base
Accessing the keys this way allows you to use the same code in Develpment, Testing and Production modes while the actual keys can (and should be different).

ENV variables are not included as part of you code and are essentially invisible to users, and so provide a secure method of storing keys (I use the SECRET_KEY_BASE to sign and decode JWTs that I use for persisting a user’s session). You can also safely place API keys here. Back in your local terminal window type:
heroku config
to view these variables. You also can also set and unset the key/value pairs from your terminal:
heroku config:set <KEY>=<VALUE> (no quotes)
heroku config:unset <KEY>

A few more helpful Heroku command lines:
heroku logs -t Allows you to view your deployed app’s log in real time (like you would see running locally). Very useful for debugging!

heroku run rails console brings up a rails console for your deployed app. Once agin, handy for playing with the remote DB and debugging.

And finally, heroku pg:reset resets your database if you want a fresh start. You’ll need to confirm by entering the app name. WARNING — this will wipe the slate clean. Don’t use if you’re already in production!

Hopefully this gives you a clearer idea of how to go about deploying to Heroku. This is my third deployed Rails API, and I’m finally feeling pretty confident about the process.

I didn’t want to spend any time on actually talking about configuring Rails app for deployment to Heroku, but I’ll paste the code below for your convenience. Some of it is already included if you generate your rails API using:
rails new <app-name-backend> — api — database=postgresql

Here’s the code that’s worked for me:

add to config/environments/production.rb

# Force all access to the app over SSL, use Strict-Transport-Security,# and use secure cookies.config.force_ssl = true

add to config/puma.rb

max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }threads min_threads_count, max_threads_countport        ENV.fetch("PORT") { 3000 }environment ENV.fetch("RAILS_ENV") { ENV['RACK_ENV'] || "development" }pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }workers ENV.fetch("WEB_CONCURRENCY") { 2 }preload_app!plugin :tmp_restart

add to config/database.yml

production:adapter: postgresqlencoding: unicode# For details on connection pooling, see Rails configuration guide# https://guides.rubyonrails.org/configuring.html#database-poolingpool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>database: sample_app_productionusername: sample_apppassword: <%= ENV['SAMPLE_APP_DATABASE_PASSWORD'] %>

create and add to ./Procfile

web: bundle exec puma -C config/puma.rb

--

--

Rick Glascock
Rick Glascock

Written by Rick Glascock

After years of teaching music in Austin, Shanghai and Yangon, I’m making a career change to my other passion, software development.

No responses yet