Ruby on Rails is quickly becoming my framework of choice for my personal websites and projects. It's a pleasure to work with and has been easy to learn. But no framework is without its challenges. One of those challenges is of course deploying the app to a server. There are a lot of options for hosting and deploying a Rails app. But, I like to run my own servers which means I have to also take care of deploying to those servers. I'd prefer to be deploying images to AWS ECS but I don't need that kind of infrastructure for my personal website. It's just a blog it can suffer seconds of downtime when I deploy updates. So my approach these days is to use Ansible to handle the deploy steps.
--- - name: Deploy Rails hosts: app.roylindauer.com vars: branch: "main" homedir: "/myapp" handlers: - name: restart workers become: true become_user: root service: name: rails-workers state: restarted - name: restart web become: true become_user: root service: name: rails-web state: restarted - name: restart nginx become: true become_user: root service: name: nginx state: restarted tasks: - name: Get Latest Source git: repo: git@github.com:roylindauer/roylindauer.com.git dest: /myapp update: yes version: "{{ branch }}" force: yes notify: - restart workers - name: Bundle Install shell: chdir: "{{ homedir }}" cmd: "bin/bundle install --without development --path vendor/bundle" - name: Update Yarn shell: chdir: "{{ homedir }}" cmd: "bin/yarn install" - name: Check for Pending Migrations shell: chdir: "{{ homedir }}" cmd: "bin/rails db:migrate:status | grep -e '^ down' | wc -l" register: pending_migrations - debug: msg: "Pending Migrations: {{ pending_migrations['stdout'] }}" - name: Stop Workers become: true become_user: root service: name: rails-workers state: stopped when: pending_migrations['stdout'] != '0' - name: DB Migrations & Restart Services shell: chdir: "{{ homedir }}" cmd: "bin/rake db:migrate" when: pending_migrations['stdout'] != '0' notify: - restart workers - name: Webpack shell: chdir: "{{ homedir }}" cmd: "bin/webpack" notify: - restart web - restart nginx - name: Precompile Assets shell: chdir: "{{ homedir }}" cmd: "bin/rails assets:precompile" notify: - restart web - restart nginx
Basically, do a git pull, update gems, then check for pending migrations. If there are migrations, stop workers, run migrations. After that compile assets, then finally restart services.
For hosting a simple rails app on a single server this sort of deploy works very well.