Cloud-init modules, also known as "cloud-config modules," help automate the provisioning and configuration of servers. When provisioning a server for a Ruby on Rails application, you can use various cloud-init modules to set up your server environment, install required packages, and configure your application. Here are some useful cloud-init modules to consider:
package_upgrade: This module upgrades all packages on the system to their latest versions. It's useful for ensuring that the server starts with the latest security updates and package fixes.
package_upgrade: true
packages: This module installs a list of specified packages. For a Rails application, you may need to install packages such as Ruby, Node.js, Yarn, and a database server (e.g., PostgreSQL or MySQL).
packages:
- ruby
- nodejs
- yarn
- postgresql
- postgresql-contrib
users: This module creates and configures system users. You might want to create a dedicated user for your Rails application.
users:
- name: deploy
groups: sudo
shell: /bin/bash
sudo: ['ALL=(ALL) NOPASSWD:ALL']
ssh-authorized-keys:
- <your_public_ssh_key>
write_files: This module writes content to specified files. You can use it to create configuration files, such as the Rails database.yml, environment files, or any other required configuration files.
write_files:
- path: /home/deploy/my_app/shared/config/database.yml
owner: deploy:deploy
content: |
production:
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: deploy
password: mysecretpassword
runcmd: This module runs specified shell commands. It can be used to clone your Rails application repository, set up the database, run bundler, precompile assets, and start the Rails server.
runcmd:
- sudo -u deploy -H git clone <your_app_repository> /home/deploy/my_app/current
- sudo -u deploy -H bundle install --deployment --without development test --path /home/deploy/my_app/shared/bundle
- sudo -u deploy -H yarn install --check-files --production
- sudo -u deploy -H RAILS_ENV=production bundle exec rake db:create db:migrate
- sudo -u deploy -H RAILS_ENV=production bundle exec rake assets:precompile
- sudo -u deploy -H systemctl enable my_app
- sudo -u deploy -H systemctl start my_app
These are just some examples of cloud-init modules that you can use to provision a server for your Ruby on Rails application. The specific modules and configurations will depend on your application's requirements and your chosen server environment.
To use environment variables for the database username and password in the database.yml file, you can utilize the ERB (Embedded Ruby) syntax. Here's an example:
production:
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
In this example, the DB_USERNAME and DB_PASSWORD environment variables are used to set the username and password for the PostgreSQL database connection.
Before running your Rails application, make sure to set these environment variables in your server environment. You can do this in several ways:
Set the environment variables in your server's environment or user's .bashrc or .bash_profile file:
export DB_USERNAME=my_db_user
export DB_PASSWORD=my_db_password
If you're using a process manager like systemd or Supervisor, you can set the environment variables in the service configuration file.
For example, with systemd, you can create a service file /etc/systemd/system/my_app.service:
[Unit]
Description=My Rails App
[Service]
User=deploy
WorkingDirectory=/home/deploy/my_app/current
Environment="DB_USERNAME=my_db_user"
Environment="DB_PASSWORD=my_db_password"
ExecStart=/bin/bash -lc 'bundle exec puma -C config/puma.rb'
Restart=always
[Install]
WantedBy=multi-user.target
If you're using a tool like dotenv or Figaro, you can set environment variables in your Rails app using a configuration file such as .env or config/application.yml. These files should not be added to your version control system.
For example, with the dotenv gem, create a .env file in your Rails app root directory:
DB_USERNAME=my_db_user
DB_PASSWORD=my_db_password
Don't forget to add the dotenv gem to your Gemfile and load it in the config/application.rb file:
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]
# config/application.rb
require 'dotenv/load'
These are just a few methods for setting environment variables for your Rails application. Choose the one that best suits your deployment strategy and server environment.
To use environment variables for the database username and password in the database.yml file within the cloud-init configuration, you can use the ERB (Embedded Ruby) syntax and add the runcmd module to export the environment variables. Here's the revised cloud-init configuration:
write_files:
- path: /home/deploy/my_app/shared/config/database.yml
owner: deploy:deploy
content: |
production:
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
runcmd:
- export DB_USERNAME=deploy
- export DB_PASSWORD=mysecretpassword
However, keep in mind that this method of setting environment variables using runcmd is temporary and only applies to the current shell session. If you want to persist these variables for the deploy user, you should add them to the user's .bashrc or .bash_profile:
write_files:
- path: /home/deploy/.bashrc
owner: deploy:deploy
append: true
content: |
export DB_USERNAME=deploy
export DB_PASSWORD=mysecretpassword
- path: /home/deploy/my_app/shared/config/database.yml
owner: deploy:deploy
content: |
production:
adapter: postgresql
encoding: unicode
database: my_app_production
pool: 5
username: <%= ENV['DB_USERNAME'] %>
password: <%= ENV['DB_PASSWORD'] %>
This will add the environment variables to the .bashrc file of the deploy user, making them available for the Rails application.