{"id":64,"date":"2026-10-03T07:40:00","date_gmt":"2026-10-03T07:40:00","guid":{"rendered":"https:\/\/newsmagazinexpro.kinsta.cloud\/demo\/?p=64"},"modified":"2026-10-03T08:26:03","modified_gmt":"2026-10-03T08:26:03","slug":"deploy-ruby-apps-shared-web-hosting","status":"publish","type":"post","link":"https:\/\/www.firevm.com\/blog\/deploy-ruby-apps-shared-web-hosting\/","title":{"rendered":"Deploy Ruby apps on Shared Web Hosting"},"content":{"rendered":"\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>TL;DR:<\/strong> Most shared hosting plans can&#8217;t run a real Ruby on Rails app. There&#8217;s no bundler, no rake tasks, and no sane way to deploy without SSH access. <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.firevm.com\/web-hosting\/\">FireVM&#8217;s shared hosting<\/a> changes that, no terminal, no command line.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we&#8217;ll deploy Redmine, a popular open-source Ruby on Rails project management app, entirely through the browser using the FireVM control panel.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Why Ruby is usually a pain on shared hosting<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most shared hosting plans weren&#8217;t built with Ruby on Rails in mind. There&#8217;s no bundler exposed in the panel, no clean way to run rake tasks, and the moment something breaks, you&#8217;re told to drop into SSH, something a lot of shared hosting plans don&#8217;t even give you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s what that typically looks like, compared to running Ruby on FireVM.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">On most shared hosts (what usually goes wrong)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>No Ruby runtime exposed through the panel at all, or bolted on as a fragile CGI setup<\/li>\n\n\n\n<li>No Bundler support, so gems with native extensions fail with header file errors<\/li>\n\n\n\n<li>Rake tasks mean dropping into SSH, if you even have shell access<\/li>\n\n\n\n<li>Git deploys mean manually pulling and rebuilding over SSH every time<\/li>\n\n\n\n<li>Passenger\/CageFS quirks silently break app spawning with no useful error logs<\/li>\n\n\n\n<li>Database config files (<code>database.yml<\/code>) edited by hand, easy to get wrong<\/li>\n\n\n\n<li>Ruby support, where it exists at all, usually means paying several times the cost of shared hosting for a VPS<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">On FireVM shared hosting (everything else, taken care of)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Ruby runs as a real, persistent process, with gems and native extensions installing properly<\/li>\n\n\n\n<li>Bundler and rake tasks run directly from the panel, no shell needed<\/li>\n\n\n\n<li>Git-based deploys, including branch switching, handled through the UI<\/li>\n\n\n\n<li>Application startup, restarts, and environment variables managed from a dashboard<\/li>\n\n\n\n<li>SSH access is included too, if you&#8217;d rather work from the terminal<\/li>\n\n\n\n<li>All of this runs on the same shared hosting plan, no VPS required<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Here&#8217;s a full walkthrough deploying Redmine, a real Ruby on Rails app, entirely in the browser. If you&#8217;d rather work from an SSH terminal instead of the Web UI, that&#8217;s covered too, right after the UI-based walkthrough.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Installing Redmine, step by step<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Create a subdomain and enable SSL<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In the FireVM control panel, go to <strong>Websites &amp; Domains \u2192 Add Subdomain<\/strong>. Give it a name, we&#8217;re using <code>rails-demo<\/code>. Then enable SSL through Let&#8217;s Encrypt. This secures your site with HTTPS before we install anything.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Enable Ruby<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">From the subdomain&#8217;s <strong>Get Started<\/strong> tab, click <strong>Ruby<\/strong>, then <strong>Enable Ruby<\/strong>. Confirm the Ruby version shown matches what Redmine needs, more on version compatibility below.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Deploy Redmine via Git<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">From <strong>Get Started<\/strong>, click <strong>Deploy using Git \u2192 Add Repository<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Repository URL: https:\/\/github.com\/redmine\/redmine.git\nRepository name: redmine.git\nDeployment mode: Automatic\nServer path: \/rails-demo.inspirevilla.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Leave the Username and Password fields blank. <strong>If your browser autofills these and causes a &#8220;could not read Username&#8221; error, use an incognito window instead.<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Click <strong>Create<\/strong>. The clone can take up to about 10 minutes.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">If it looks stuck, refresh the page rather than retrying, the clone is likely still running in the background.<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">On the repository&#8217;s management page, switch the <strong>Branch<\/strong> dropdown to <code>6.1-stable<\/code>, then click <strong>Deploy now<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Set the document root<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Go to <strong>Hosting &amp; DNS \u2192 Hosting Settings<\/strong>. The Document root field may show a stale or incorrect default. <strong>Manually set it to <code>rails-demo.inspirevilla.com\/public<\/code> and save.<\/strong> Redmine&#8217;s public assets live in that folder, and the app won&#8217;t load correctly if the document root points anywhere else.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Configure the database<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In File Manager, go to <code>config\/<\/code> and create a new file called <code>database.yml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>production:\n  adapter: sqlite3\n  database: db\/redmine.sqlite3<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Step 6: Install gems and run setup tasks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">From the Ruby panel, click <strong>Bundle install<\/strong>. This installs all the gems Redmine needs, including ones with native extensions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then, from the Ruby panel&#8217;s rake task runner, run each of these one at a time:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>generate_secret_token<\/code><\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">This task shows no visible output, it just spins and returns to the panel. That&#8217;s normal, not a failure. Confirm it worked by checking that <code>config\/initializers\/secret_token.rb<\/code> was created in File Manager.<\/p>\n<\/blockquote>\n\n\n\n<pre class=\"wp-block-code\"><code>db:migrate<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>REDMINE_LANG=en redmine:load_default_data<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both of these show live output normally as they run.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 7: Verify<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Visit your subdomain, for example <code><a href=\"http:\/\/rails-demo.inspirevilla.com\" target=\"_blank\" rel=\"noopener\">http:\/\/rails-demo.inspirevilla.com<\/a><\/code>. The Redmine home page should load. Log in with <code>admin<\/code> \/ <code>admin<\/code>, and set a new password when prompted.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1001\" height=\"662\" src=\"https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08.png\" alt=\"\" class=\"wp-image-574\" style=\"box-shadow:var(--wp--preset--shadow--natural)\" srcset=\"https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08.png 1001w, https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08-150x100.png 150w, https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08-300x198.png 300w, https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08-767x507.png 767w, https:\/\/www.firevm.com\/blog\/wp-content\/uploads\/2025\/01\/2026-10-03_13-08-860x570.png 860w\" sizes=\"auto, (max-width: 1001px) 100vw, 1001px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Known gotchas<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A few things worth knowing before you hit them yourself.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Removing a subdomain doesn&#8217;t delete its files.<\/strong> If you remove a subdomain and recreate it with the same name, check File Manager afterward and delete any leftover folder from the old deployment. Old files and configs otherwise persist and conflict with the fresh deploy.<\/li>\n\n\n\n<li><strong>The document root field can default to a stale or wrong value<\/strong>, not necessarily the correct subdomain path. Always check and set it explicitly rather than assuming it&#8217;s correct, as covered in Step 4.<\/li>\n\n\n\n<li><strong>Check Ruby version compatibility against Redmine&#8217;s supported range<\/strong> before picking a branch. Redmine 5.1-stable needs Ruby 3.2 or earlier; 6.1-stable needs Ruby 3.2 through 3.4.<\/li>\n\n\n\n<li><strong>Domain naming convention:<\/strong> this guide uses <code>rails-demo<\/code> rather than <code>ruby-demo<\/code>, matching how developers typically name these subdomains, even though the panel&#8217;s button is labeled &#8220;Ruby.&#8221;<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">Prefer the terminal? Here&#8217;s the SSH version<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Everything above runs through FireVM&#8217;s control panel UI, but Developer and above plans include full SSH access too. If you&#8217;d rather work from the terminal, here&#8217;s the same install as a command sequence.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 1. Navigate to your subdomain's document root\ncd ~\/rails-demo.inspirevilla.com\n\n# 2. Clone Redmine directly into this folder\ngit clone https:\/\/github.com\/redmine\/redmine.git .\ngit checkout 6.1-stable\n\n# 3. Create the database config\nnano config\/database.yml\n# add:\n# production:\n#   adapter: sqlite3\n#   database: db\/redmine.sqlite3\n\n# 4. Install gems\nbundle install\n\n# 5. Generate the secret token\nRAILS_ENV=production bin\/rails generate_secret_token\n\n# 6. Run migrations\nRAILS_ENV=production bin\/rails db:migrate\n\n# 7. Load default data\nRAILS_ENV=production REDMINE_LANG=en bin\/rails redmine:load_default_data\n\n# 8. Tell Passenger to reload the app\nmkdir -p tmp\ntouch tmp\/restart.txt<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Double-check your document root path and Ruby version before running this, both are specific to your setup.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">What&#8217;s next<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">FireVM&#8217;s <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.firevm.com\/web-hosting\/\">Developer plan<\/a> runs Ruby apps like this. Anything below that won&#8217;t give you Bundler, Git deploys, or rake task support for Ruby apps.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you&#8217;re running client sites rather than just your own, the <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.firevm.com\/web-hosting\/\">Agency plan<\/a> is the better fit. It gives each client their own isolated account with a separate login, so you can hand off access without exposing anything else on your hosting.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your app genuinely needs more than shared web hosting can offer, heavier traffic, custom server-level configuration, or full root access, <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.firevm.com\/vps-hosting\/\">FireVM&#8217;s VPS hosting<\/a> is there too. And if you ever outgrow VPS as well, <a target=\"_blank\" rel=\"noopener\" href=\"https:\/\/www.firevm.com\/dedicated-servers\/\">FireVM&#8217;s dedicated servers<\/a> are there for when you need a machine entirely to yourself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Most shared hosts make Ruby on Rails painful or impossible without SSH. Here&#8217;s how to deploy a full Redmine app on FireVM shared hosting, entirely through the browser, start to finish.<\/p>\n","protected":false},"author":1,"featured_media":576,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[26],"class_list":["post-64","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guides","tag-web-hosting"],"_links":{"self":[{"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":3,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/posts\/64\/revisions"}],"predecessor-version":[{"id":577,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/posts\/64\/revisions\/577"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/media\/576"}],"wp:attachment":[{"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/media?parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/categories?post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.firevm.com\/blog\/wp-json\/wp\/v2\/tags?post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}