<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sebastian Arrieta</title>
    <description>The latest articles on DEV Community by Sebastian Arrieta (@sarrietav).</description>
    <link>https://dev.to/sarrietav</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F361599%2F09ced4e7-9ac8-4491-aca7-a9ba840c997c.jpeg</url>
      <title>DEV Community: Sebastian Arrieta</title>
      <link>https://dev.to/sarrietav</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sarrietav"/>
    <language>en</language>
    <item>
      <title>Laravel 12 + Inertia on Railway: Step-by-Step Deployment Guide</title>
      <dc:creator>Sebastian Arrieta</dc:creator>
      <pubDate>Thu, 17 Jul 2025 15:36:55 +0000</pubDate>
      <link>https://dev.to/sarrietav/laravel-12-inertia-on-railway-step-by-step-deployment-guide-55hf</link>
      <guid>https://dev.to/sarrietav/laravel-12-inertia-on-railway-step-by-step-deployment-guide-55hf</guid>
      <description>&lt;p&gt;Today I had to deploy a basic Laravel 12 + Inertia app to &lt;a href="https://railway.app/" rel="noopener noreferrer"&gt;Railway&lt;/a&gt;, but if you follow the official Railway guide to the letter, you’re likely to run into errors (at least, I did). So I’m going to walk you through &lt;strong&gt;how I actually got it working&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Laravel project hosted on GitHub.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step-by-Step Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Railway Project
&lt;/h3&gt;

&lt;p&gt;Click the &lt;strong&gt;New&lt;/strong&gt; button and choose &lt;strong&gt;Empty Project&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Add a PostgreSQL Database
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Create&lt;/strong&gt;, choose &lt;strong&gt;Database&lt;/strong&gt;, and select &lt;strong&gt;PostgreSQL&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Add the Laravel Service
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Create &amp;gt; Empty Service&lt;/strong&gt;. Once it’s created:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the new service to open its settings.&lt;/li&gt;
&lt;li&gt;Rename it to something like &lt;strong&gt;Laravel App&lt;/strong&gt; (tip: click the icon to change it too).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Set Environment Variables
&lt;/h3&gt;

&lt;p&gt;Go to the &lt;strong&gt;Variables&lt;/strong&gt; tab, then open the &lt;strong&gt;Raw Editor&lt;/strong&gt;. Paste the contents of your &lt;code&gt;.env&lt;/code&gt; file, but before saving, make sure to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a new &lt;code&gt;APP_KEY&lt;/code&gt; with:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  php artisan key:generate &lt;span class="nt"&gt;--show&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Set &lt;code&gt;APP_ENV=production&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;APP_DEBUG=false&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update your database connection settings to use the Railway PostgreSQL instance:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  DB_CONNECTION=pgsql
  DB_URL=${{Postgres.DATABASE_URL}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Important:&lt;/strong&gt; The &lt;code&gt;DATABASE_URL&lt;/code&gt; points to the internal private address of your Railway PostgreSQL instance. This is good (no ingress data charges), but it’s &lt;strong&gt;not available during the build phase&lt;/strong&gt;. So &lt;strong&gt;don’t&lt;/strong&gt; run database migrations during build — you’ll get an error like:&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SQLSTATE[08006] [7] could not translate host name "postgres.railway.internal" to address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  5. Connect Your GitHub Repository
&lt;/h3&gt;

&lt;p&gt;Under &lt;strong&gt;Settings &amp;gt; Source&lt;/strong&gt;, connect your GitHub repo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Alternatively, if you're using the &lt;a href="https://docs.railway.app/develop/cli" rel="noopener noreferrer"&gt;Railway CLI&lt;/a&gt;, you can run:&lt;/p&gt;


&lt;pre class="highlight shell"&gt;&lt;code&gt;railway up
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  6. Switch to Railpack
&lt;/h3&gt;

&lt;p&gt;In the &lt;strong&gt;Build&lt;/strong&gt; section, change the builder from &lt;strong&gt;Nixpacks&lt;/strong&gt; to &lt;strong&gt;Railpack&lt;/strong&gt; (beta). This builder uses &lt;strong&gt;FrankenPHP&lt;/strong&gt; instead of PHP-FPM and automatically runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;php artisan optimize&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;php artisan migrate --force&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Add Worker and Cron Services
&lt;/h2&gt;

&lt;p&gt;You’ll need two additional services: one for running &lt;strong&gt;cron jobs&lt;/strong&gt; and another for &lt;strong&gt;queue workers&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create Startup Scripts
&lt;/h3&gt;

&lt;p&gt;Add the following to your project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Make sure this file is executable: chmod +x run-cron.sh&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running the scheduler..."&lt;/span&gt;
    php artisan schedule:run &lt;span class="nt"&gt;--verbose&lt;/span&gt; &lt;span class="nt"&gt;--no-interaction&lt;/span&gt; &amp;amp;
    &lt;span class="nb"&gt;sleep &lt;/span&gt;60
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Make sure this file is executable: chmod +x run-worker.sh&lt;/span&gt;

php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Create Cron and Worker Services
&lt;/h3&gt;

&lt;p&gt;In Railway:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right-click your Laravel service and &lt;strong&gt;Duplicate&lt;/strong&gt; it twice.&lt;/li&gt;
&lt;li&gt;Name one &lt;strong&gt;Cron&lt;/strong&gt;, and the other &lt;strong&gt;Worker&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In each duplicated service:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; Deploy &amp;gt; Custom Start Command&lt;/strong&gt; and add:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For Cron:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./run-cron.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sh ./run-cron.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Worker:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./run-worker.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sh ./run-worker.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Force HTTPS in Production
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;AppServiceProvider.php&lt;/code&gt;, add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;boot&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'production'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forceScheme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'https'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;Illuminate\Support\Facades\URL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This avoids issues like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Mixed Content:&lt;/strong&gt; The page at ... was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ...&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Final Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Deploy&lt;/strong&gt; on your Laravel service.&lt;/li&gt;
&lt;li&gt;Once deployed, go to &lt;strong&gt;Settings &amp;gt; Networking&lt;/strong&gt;, and generate a &lt;strong&gt;public domain&lt;/strong&gt;. Your app will be accessible at port &lt;code&gt;8080&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update your service secrets to include the new domain:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APP_URL=https://your-new-url.railway.app
ASSET_URL=https://your-new-url.railway.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  You're Done
&lt;/h2&gt;

&lt;p&gt;And that’s it! You’ve successfully deployed your Laravel 12 + Inertia app to Railway with working cron jobs, queue workers, HTTPS support, and a live domain. Here's the template of the setup if you want to copy it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://railway.com/deploy/aUl2lW?referralCode=oWmpD1" rel="noopener noreferrer"&gt;Deploy on Railway&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>railway</category>
    </item>
  </channel>
</rss>
