Using Inertia SSR
Inertia allows you to work with your Laravel monolith application, and still use frontend libraries and frameworks such as React, Vue, and Svelte! Furthermore, it supports Server-side Rendering, which allows HTML content to be rendered from the server instead of the client.
Once you’ve completed the Server-side Rendering setup for your local app, dive in below to deploy your server-side rendered, Laravel Inertia-SPA at Fly.io!
Dockerfile Changes
Inertia SSR requires a background Node process that will render requested html pages. You’ll have to update Fly.io’s generated Dockerfile
for your Laravel app in order to include support for Node
. You can follow any of the below options to include Node
:
Option 1: Quick copy of Node to Final Image
The Laravel fly-scanner already generates a Dockerfile that makes use of a Node
image, but uses a different final image. The quickest way to include Node into your app’s final image, is to copy over the Node
image’s node
binaries and generated node_modules
to the final fly-laravel
image:
FROM base
+ COPY --from=node_modules_go_brrr /usr/local/bin/node /usr/local/bin/node
+ COPY --from=node_modules_go_brrr /app/node_modules /var/www/html/node_modules
Option 2: Install Node in Final Image
Of course, you can also instead opt to fully install Node
in your final fly-laravel
image. So, revise your Dockerfile to include instructions to install node
, and build the necessary assets/node_modules into your final image:
# Install node in fly-laravel image
RUN cd ~ \
&& curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh \
&& bash nodesource_setup.sh \
&& apt install nodejs \
&& cd /var/www/html
# The snippet below already exists in the Dockerfile btw,
# In the multi-stage build set up:
RUN if [ -f "vite.config.js" ]; then \
ASSET_CMD="build"; \
else \
ASSET_CMD="production"; \
fi; \
if [ -f "yarn.lock" ]; then \
yarn install --frozen-lockfile; \
yarn $ASSET_CMD; \
elif [ -f "pnpm-lock.yaml" ]; then \
corepack enable && corepack prepare pnpm@latest-8 --activate; \
pnpm install --frozen-lockfile; \
pnpm run $ASSET_CMD; \
elif [ -f "package-lock.json" ]; then \
npm ci --no-audit; \
npm run $ASSET_CMD; \
else \
npm install; \
npm run $ASSET_CMD; \
fi;
RUN chown -R www-data:www-data /var/www/html/public
EXPOSE 8080
ENTRYPOINT ["/entrypoint"]
Since we now have node and its assets/modules in the fly-laravel
image, we can remove our multi-build setup where we use a separate FROM node
image ( to build and copy assets and node_modules ):
# Remove the "multi stage build setup" lines below:
- FROM node:${NODE_VERSION} as node_modules_go_brrr
- RUN mkdir /app
- RUN mkdir -p /app
- WORKDIR /app
- COPY . .
- COPY --from=base /var/www/html/vendor /app/vendor
# Remove the "set up to copy asset folder from node image to fly-laravel image"
# lines below:
- COPY --from=node_modules_go_brrr /app/public /var/www/html/public-npm
- RUN rsync -ar /var/www/html/public-npm/ /var/www/html/public/ && rm -rf /var/www/html/public-npm
Running SSR as A Process
After getting your Dockerfile set up for Inertia SSR to work, you can run the SSR Server as a background process. Here at Fly.io, you can easily run a separate VM for your SSR server instead of a monitoring tool like Supervisor.
Update your fly.toml
file to include an ssr
process group:
[processes]
app=""
ssr="php /var/www/html/artisan inertia:start-ssr"
Adding the SSR process above creates a new machine specially for your SSR server. You’ll now have separate machines for your web app, and ssr server: Notice there are four machines above? The two machines listed at the bottom are back ups.
Now that you have more than one process group for your Fly.io app, you’ll have to make sure that the [http_service]
is properly mapped to your app
process. Update your fly.toml
‘s http_service
section with the app
process:
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
+ processes = ["app"]
Web and SSR Communication
The SSR server will be created as a separate VM from your web app. You’ll have to configure your Laravel web VM to talk with it. To do so, first revise the fly.toml
file to include an SSR_URL
that will contain the ssr process’ .internal address routed to SSR’s applicable port ( in the case below, 13714):
[env]
SSR_URL="ssr.process.<yourAppNameHerePlease>.internal:13714"
// other envs here
Finally, pull the inertia.php config file into your config directory, and update it to use the SSR_URL
env variable:
/* config/inertia.php */
'ssr' => [
'enabled' => true,
'url' => env('SSR_URL','http://127.0.0.1:13714')
],
With that, do a quick fly deploy
and you’re good to go!