Getting Started with Rails #
In this tutorial, you will deploy the sample application from Michael Hartl’s book Ruby on Rails Tutorial: Learn Web Development with Rails. It’s a simple micro-blogging application that lets you create posts and follow other users. It leverages a PostgreSQL database and stores file uploads in an S3 Object Store. We will explain all the necessary SetOps commands that we need to deploy the application. You can find a summary of all commands at the end.
Prepare your Code #
-
Get started by getting the code. The code is originally hosted at mhartl/sample_app_6th_ed, but for convenience, we recommend using our fork at setopsco/rails-sample-app
This will provide you with a verified version, and all necessary adjustments towards a Twelve-Factor App have already been made.
git clone https://github.com/setopsco/rails-sample-app
Prepare your SetOps Environment #
At first, you need to choose a name for project
, stage
, and app
. You can edit them in the form in the top right corner.
-
Now we’re ready to deploy this app to SetOps. Start by creating a Project.
setops -p <PROJECT> project:create
-
Create a Stage for your project.
setops -p <PROJECT> -s <STAGE> stage:create
project
andstage
must only contain lowercase lettersa-z
and numbers0-9
and start with a lowercase letter. The length ofproject
has to be between 3 and 20 characters and the length ofstage
between 3 and 12. It also has to start with a lowercase letter. A valid example isparkscheibe
&staging
. -
Create the Stage Definition containing the App and store it as
<STAGE>.setops.yaml
.schema_version: "2" project: <PROJECT> stage: <STAGE> apps: # The name for apps must only contain lowercase letters `a-z` and numbers `0-9` and dashes `-`. The name must be between 3 and 16 characters long and start with a lowercase letter. <APPNAME>: container: # To get the Rails app started inside the container, we need to set a command command: - bundle - exec - puma # Let's also configure a container health check, which is executed in the container and checks if our app is healthy. health_check: command: - /bin/sh - -c - curl -s http://localhost:$PORT/.well-known/health-check | grep ok interval: 15 retries: 10 start_period: 30 timeout: 5 env: # We map a secret (which we will set in the next step) to an env variable SECRET_KEY_BASE: description: "Key Base which is required for Rails Sessions" value: "{{ .Secrets.secret_key_base }}" links: database: env_key: DATABASE_URL store: env_key: S3_DATA_URL network: # We want it to be publicly reachable, so we set the network's public option to true. public: true # The app will accept http requests protocol: http # Rails will listen on port 5000, so we need to tell SetOps that ports: - 5000 health_check: status: "200" path: "/.well-known/health-check" resources: # we want only one instance running scale: 1 # the smallest cpu sizing is enough for this app cpu: 128 # we need to change the available memory for a container since Rails' memory consumption is higher then the default memory: 512 services: # The name for services must only contain lowercase letters `a-z` and numbers `0-9` and dashes `-`. The name must be between 3 and 18 characters long and start with a lowercase letter. database: type: postgresql plan: shared store: type: s3
-
Create the Secret which we map in the Stage Definition.
setops -p <PROJECT> -s <STAGE> secret:create secret_key_base=$(openssl rand -hex 64)
-
Apply the Stage Definition. You will see a diff to the current state and you will be asked to confirm that you want to apply these changes.
setops -p <PROJECT> -s <STAGE> stage:apply -f stage.setops.yaml
Deploy your Image #
-
Build and push the image from the repo cloned earlier to the SetOps Image Registry. Also initialize the database schema and load some sample data from the seeds (
db/seeds.rb
).cd /path/to/cloned/repository # from step 1 setops -p <PROJECT> -s <STAGE> --app <APPNAME> image:push --tag v1.0.0 --build-with-docker .
image:push
with the--build-with-docker
flag builds and pushes a new image to SetOps. You can find more information about the distinct steps and how to run them isolated here.If you encounter any errors during the image build, try to run the command without caching:
cd /path/to/cloned/repository # from step 1 setops -p <PROJECT> -s <STAGE> --app <APPNAME> image:push --tag v1.0.0 --build-with-docker . --no-cache
-
Run migrations and seed database before deploying the new image
setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run --image-tag v1.0.0 -- env DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:schema:load db:seed
-
Deploy the new image to your apps.
setops -p <PROJECT> -s <STAGE> stage:apply --image-tags <APPNAME>=v1.0.0
-
Verify your app is running with the correct image (
v1.0.0
) and its health status isHEALTHY
.setops -p <PROJECT> -s <STAGE> --app <APPNAME> task
-
Get the public domain to your app and copy the domain (
<APPNAME>.<STAGE>.<PROJECT>.$YOURDOMAIN
)setops -p <PROJECT> -s <STAGE> --app <APPNAME> domain
-
Open the application in your browser. You can log in with the sample user defined in
db/seeds.rb
: the username isexample@railstutorial.org
with passwordfoobar
. Enjoy!
If you want to remove the stage & project again, run these commands:
setops -p <PROJECT> -s <STAGE> stage:destroy --force
setops -p <PROJECT> project:destroy --force