{"id":2433,"date":"2023-07-10T01:41:21","date_gmt":"2023-07-10T05:41:21","guid":{"rendered":"https:\/\/www.rexfeng.com\/blog\/?p=2433"},"modified":"2023-07-10T02:11:34","modified_gmt":"2023-07-10T06:11:34","slug":"updating-web-app-from-rails-4-to-rails-7","status":"publish","type":"post","link":"https:\/\/www.rexfeng.com\/blog\/2023\/07\/updating-web-app-from-rails-4-to-rails-7\/","title":{"rendered":"Updating web app from Rails 4 to Rails 7"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A few months ago, <a href=\"https:\/\/certbot.eff.org\/\">certbot<\/a> gave me the warning &#8220;Your system is not supported by certbot-auto anymore.&#8221;. With my Rails 4 app running on old Ubuntu 14.04, it was time to update the app &amp; environment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Since I&#8217;m using Digital Ocean&#8217;s droplets, it was easy to spin up a new droplet, setup the new droplet, and then destroy the old droplet. This is way better than operating in situ.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This blog post will provide a high level overview of update steps &amp; pitfalls encountered.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Spin up a Ruby on Rails (v7.0.4.2, OS Ubuntu 22.04) droplet <a href=\"https:\/\/marketplace.digitalocean.com\/apps\/ruby-on-rails\">https:\/\/marketplace.digitalocean.com\/apps\/ruby-on-rails<\/a> This also involved setting up a SSH key to access the new droplet server.<br><br><\/li>\n\n\n\n<li>Exfiltrate the example Rails 7 app from the server to my local machine <code style=\"background-color: rgb(254 215 170)\">scp -r root@{SERVER_IP}:\/home\/rails\/example .<\/code><br><\/li>\n<br>\n\n\n\n<li>Create a new private GitHub repo for this example Rails 7 app<br><br><\/li>\n\n\n\n<li>Run the new example Rails 7 app locally This step should be super simple, but it was not. Getting RVM to run Ruby 3.2.0 with OpenSSL was not trivial on my Intel Mac. Here&#8217;s what I ran to setup Ruby 3.2.0 locally: <br><br><code style=\"background-color: rgb(254 215 170)\">sudo -i <\/code><br><code style=\"background-color: rgb(254 215 170)\">cd \/usr\/local\/src <\/code><br><code style=\"background-color: rgb(254 215 170)\">curl -O https:\/\/www.openssl.org\/source\/openssl-1.0.2t.tar.gz <\/code><br><code style=\"background-color: rgb(254 215 170)\">tar xzf openssl-1.0.2t.tar.gz <\/code><br><code style=\"background-color: rgb(254 215 170)\">cd openssl-1.0.2t <\/code><br><code style=\"background-color: rgb(254 215 170)\">.\/Configure darwin64-x86_64-cc <\/code><br><code style=\"background-color: rgb(254 215 170)\">make <\/code><br><code style=\"background-color: rgb(254 215 170)\">make install <\/code><br><br><code style=\"background-color: rgb(254 215 170)\">rvm reinstall 3.2.0 --with-openssl-dir=\/usr\/local\/ssl<\/code><br><br><\/li>\n\n\n\n<li>In the new Rails 7 app, I moved my psql DB migrations over by hand. I copied the files and had to update the <code>ActiveRecord::Migration<\/code> with <code>ActiveRecord::Migration[7.0]<\/code>.<br><br><\/li>\n\n\n\n<li>Draw the rest of the owl. I had to port lots of Rails files over from my Rails 4 to the target Rails 7 app. <br><br>I ran into an issue with a model validation callback. To fix my issue, I created a migration to add uniqueness validation at the postgres layer and removed the <code>uniqueness<\/code> check in my model. <br><br>This also include various site fixes. Such as Open Street Map tiles, using 3rd party APIs, and Font Awesome icons.<br><br><\/li>\n\n\n\n<li>Setup deployment to the server using Capistrano. <br><br>Setting up Capistrano with Puma on Digital Ocean was not trivial at all. I followed this guide by Matthew Hoelter <a href=\"https:\/\/www.matthewhoelter.com\/2020\/11\/10\/deploying-ruby-on-rails-for-ubuntu-2004.html\">https:\/\/www.matthewhoelter.com\/2020\/11\/10\/deploying-ruby-on-rails-for-ubuntu-2004.html<\/a> <br><br>In my config\/deploy.rb file, I had to add this <code style=\"background-color: rgb(254 215 170)\">set :branch, :main<\/code> <br><br>In my root Capfile, I had to use <code style=\"background-color: rgb(254 215 170)\">install_plugin Capistrano::Puma::Systemd<\/code> due to using Puma 5.6.5. <br><br>After a ton of trial and error, I had setup my nginx config at <code style=\"background-color: rgb(254 215 170)\">\/etc\/nginx\/sites-available\/rails<\/code>. <br><br>There was a ton of issues with the .sock file from Puma not getting generated. <br><br>Setting up the <code style=\"background-color: rgb(254 215 170)\">secret_key_base<\/code> is a newer Rails convention. Luckily Matthew&#8217;s blog post goes into detail on how to set it up in <code style=\"background-color: rgb(254 215 170)\">\/etc\/environment<\/code> <br><br>Using <code style=\"background-color: rgb(254 215 170)\">systemctl<\/code>, I got puma setup to run the command <code style=\"background-color: rgb(254 215 170)\">bundle exec puma -C \/home\/rails\/apps\/[APP_NAME]\/shared\/puma.rb<\/code>. <br><br>Also, due to running on Digital Ocean, I had to update permissions for the rails user. <code style=\"background-color: rgb(254 215 170)\">cd \/home; chmod o=rx rails<\/code>. See Stack Overflow for details <a href=\"https:\/\/stackoverflow.com\/questions\/70028324\/nginx-permission-denied-accessing-puma-socket-that-does-exist-in-the-correct-loc\">https:\/\/stackoverflow.com\/questions\/70028324\/nginx-permission-denied-accessing-puma-socket-that-does-exist-in-the-correct-loc<\/a> Without running this, I was getting a 502 (Bad Gateway) error, even though everything else was setup. I can see traffic in my nginx.access.log, but I was still getting the 502 (before running this command).<br><br><\/li>\n\n\n\n<li>Move psql data over. This step is going to vary a lot on your setup. I was able to run <code style=\"background-color: rgb(254 215 170)\">pg_dump<\/code> to export my data and import data using <code style=\"background-color: rgb(254 215 170)\">psql APP_NAME_production &lt; latest_pg_dump.sql<\/code>.<br><br><\/li>\n\n\n\n<li>Update A record. In order to point my domain to my new droplet, I went into Digital Ocean and updated the A record from my old IP to my new IP. This is going to vary depending who you&#8217;re using for domain names.<br><br><\/li>\n\n\n\n<li>Run certbot. Running certbot for SSL was super easy. <a href=\"https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=ubuntufocal\">https:\/\/certbot.eff.org\/instructions?ws=nginx&amp;os=ubuntufocal<\/a><br><br><\/li>\n\n\n\n<li>Destroy old droplet. When you&#8217;ve verified everything is working with your new Rails 7 app, you can destroy the old droplet in Digital Ocean.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">My app, <a href=\"https:\/\/geographapp.com\/\">GeoGraph<\/a>, is now running on Rails 7 and <a href=\"https:\/\/geographapp.com\/\">lets anyone bookmark their location<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few months ago, certbot gave me the warning &#8220;Your system is not supported by certbot-auto anymore.&#8221;. With my Rails 4 app running on old Ubuntu 14.04, it was time to update the app &amp; environment. Since I&#8217;m using Digital Ocean&#8217;s droplets, it was easy to spin up a new droplet, setup the new droplet, [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1029],"tags":[1498,1501,1504,1505,1506,1094,1499],"class_list":["post-2433","post","type-post","status-publish","format-standard","hentry","category-programming","tag-digitalocean","tag-droplet","tag-postgres","tag-psql","tag-puma","tag-rails","tag-rails7"],"_links":{"self":[{"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/posts\/2433","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/comments?post=2433"}],"version-history":[{"count":14,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/posts\/2433\/revisions"}],"predecessor-version":[{"id":2448,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/posts\/2433\/revisions\/2448"}],"wp:attachment":[{"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/media?parent=2433"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/categories?post=2433"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rexfeng.com\/blog\/wp-json\/wp\/v2\/tags?post=2433"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}