Rails & PostgreSQL with CapRover on DigitalOcean Droplet (Part II)
Before deploying the rails application, let’s see how to remote access the droplet and container. To log into droplet, use ssh like this:
ssh -o "IdentitiesOnly=yes" -i .ssh/another_rsa root@droplet_ip_address
Connect to droplet as root and assign difference ssh key in case you use different ssh key for droplet. Once inside the droplet, use docker service ls
to list all containers.
To reboot droplet, just run reboot
. Everything should be online after that.
To view the status of running container, run docker ps
To go into the container with shell, run this:
docker exec -it f9a9635b2c8f /bin/sh
Note that alpine linux does not have bash, thus, sh is used instead. ‘f9a9635b2c8f’ is the container id. To use psql, just run docker exec -it container_id psql -U postgres_username
.
In case anything goes wrong, you can still access the droplet and container manually.
— — —
Let create a new Rails application and see how things go before deploy a real one. We also install stimulus to be sure the webpacker works. Run these commands in the local development platform and make sure it works.
rails new parrot --database=postgres
cd parrot
rake webpacker:install:stimulus
rails g scaffold user username email
Add these into app/view/user/index.html.erb
<div data-controller="hello">
<h1 data-target="hello.output"></h1>
</div>
Add root route in config/routes.rb like this
root 'users#index'
Adjust config/database.yml to work with local PostgreSQL and run
rake db:create
rake db:migrate
rails s -b 0.0.0.0
You should see the default Rails page at 0.0.0.0:3000 and “Hello Stimulus” in localhost:3000/users .
— — —
To deploy Rails with CapRover, create a “Captain Definition File” in the root of Rails application like this:
{
"schemaVersion": 2,
"dockerfilePath": "./Dockerfile"
}
Although CapRover offers predefined dockerfile for ruby-rack application, it would be better to write our own dockerfile so that we know the details inside.
You can find an example of dockerfile for Rails at docker website. That’s try it.
FROM ruby:2.6.5-alpine
# Ubuntu
#RUN apt-get update -qq && apt-get install -y nodejs yarn postgresql-client postgresql-dev
# Alpine
RUN apk update && apk add nodejs yarn postgresql-client postgresql-dev tzdata build-base
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install --deployment --without development test
COPY . /myapp
RUN bundle exec rake yarn:install# Set production environment
ENV RAILS_ENV production# Assets, to fix missing secret key issue during building
RUN SECRET_KEY_BASE=dumb bundle exec rails assets:precompile# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 80# Start the main process.
WORKDIR /myapp
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]
Here we use the 2.6.5-alpine image for ruby. ‘entrypoint.sh’ is also created as suggested. Please note that /bin/sh is used here due to alpine
#!/bin/sh
set -e# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
To link the production database, edit the database.yml like this:
production:
<<: *default
host: srv-captain--postgresql-db
database: parrot_production
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
Also set assets compile to be true
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -26,7 +26,7 @@ Rails.application.configure do
# config.assets.css_compressor = :sass# Do not fallback to assets pipeline if a precompiled asset is missed.
- config.assets.compile = false
+ config.assets.compile = true
Now, create a web app on CapRover by giving a name “parrot”.
It is an empty one. Click the app name and add Rails master key in “App Configs” section like this:
RAILS_MASTER_KEY=xxx
POSTGRES_USER=username
POSTGRES_PASSWORD=password
RAILS_SERVE_STATIC_FILES=true
Now, git commit everything in your local project directory and run caprover deploy
. Answer each question from caprover deploy. Please note that it often use arrow keys to choice options.
Once it is deployed, ssh into the droplet and go into the container mentioned at the beginning of this article. Set up the database via:
bundle exec rake db:create
bundle exec rake db:migrate
Finally, go to web app url and it should work properly.
By far, a simple do-nothing Rails application is running. It is not the optimized setup yet, but at least a good start. We will try to improve in the later parts.