Deploying Remix applications with Laravel Forge
For the demo I'm using the base Remix template, and deploying it on Digital Ocean droplet In this case we don't need a database to run the app, so we'll start with a Web Server preset (don't worry we'll get rid of PHP later!).
With Shopify buying Remix it will be a default choice for Shopify Apps, check out this article on Shopify's new checkout extensibility, to learn more about the change.
After the server provisions, you need to sync the application with your repository by passing the account-name/project-name and selecting a branch. Once the repository is successfully connected and installed there are just a couple steps left.
Update Node version if required
Forge can install older version of node then required. You can SSH into a server or run the script below as Forge Recipe to update Node to v20. The alternative would be to install NVM (node version manager) on the server.
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
NODE_MAJOR=20
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
sudo apt-get update --allow-releaseinfo-change && sudo apt-get install nodejs -y
Create a daemon to run Remix app
Let's start with creating a daemon to run the Remix application. The command we want to use is npm run start
and it should be run in the folder the app is installed. This is /home/forge/domain-name.com
Once the daemon is installed we'll need to grab the ID of the process to restart it during deployment.
Configure deployment script
The most important part is to configure the deployment script. During deployment the app will be built, and we'll restart the application daemon. Below is the basic deployment script for deploying a Remix application on Laravel Forge.
git pull origin $FORGE_SITE_BRANCH
npm ci
npm run build
sudo -S supervisorctl restart daemon-845353:*
Replace 845353
with the ID of the daemon created earlier.
If you're using NVM add nvm use
after git pull
command to default to the Node version in .nvmrc
file of your project.
Update nginx configuration for Remix application
The last part of the process is to update the nginx configuration. Laravel Forge provides the basic configuration that is meant for PHP applications.
## Default configuration
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
## Node/Remix configuration
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection ‘upgrade’;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
We need to replace initial configuration for root of the site to route to the Remix application running on the server.
Server cleanup, disable php-fpm
Since we're not using PHP, we can safely disable php-fpm process to save resources for serving Remix application. I suggest to run this as a Forge Recipe, but you can also do it directly on the server.
sudo systemctl stop php8.3-fpm
sudo systemctl disable php8.3-fpm
Deploy the app
It's time to deploy the app and visit the domain to confirm it's available! With Quick Deploys enabled the application will be automatically re-deployed on every new commit to the current branch.
For more advanced deployment scenarios, especially when using databases like TursoDB with Shopify Remix apps, you might find this guide on seamless Shopify Remix deployment with TursoDB useful. It covers the setup and deployment process in detail.