Deploying a Shopify Remix app to your own cloud server gives you more control over performance, security, and cost.
I’ll show you the exact steps I follow.
This works for any cloud server — I use Hetzner, but you can use DigitalOcean, AWS EC2, or similar VPS providers.
No fluff. Straight to the point.
Table of Contents
- Prerequisites
- Create the Server
- Update the Server
- Install Node.js
- Install PM2
- Install Nginx and Configure SSL
- Clone the Project
- Create and Configure the
.envFile - Install Dependencies
- Build the App
- Start the App with PM2
- Wrap Up
1. Prerequisites
You’ll need:
- A cloud server (Hetzner, DigitalOcean, AWS EC2, etc.).
- A registered domain.
- Basic Linux command-line knowledge.
- A Shopify Partner app built with Remix.
- A Git repository for your project.
2. Create the Server
You can use any provider:
- Hetzner Cloud: great pricing and reliable.
- DigitalOcean Droplets: beginner-friendly.
- AWS EC2: more advanced and flexible.
Spin up a new Ubuntu 22.04 instance (2GB RAM or higher is fine for most apps).
Add your SSH key for secure access.
3. Update the Server
Once you SSH into your new server:
#First create new user:
sudo adduser tutorial
#Give sudo permission:
sudo usermod -aG sudo tutorial
#Switch user
su - tutorial
sudo apt update && sudo apt upgrade -y
This ensures all packages are up to date.
4. Install Node.js
Remix apps require Node.js.
Install the LTS version (22.x):
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node -v
npm -v
5. Install PM2
PM2 will keep your Remix app running and restart it automatically on crashes or reboots.
sudo npm install pm2@latest -g
pm2 -v
6. Install Nginx and Configure SSL
Nginx acts as a reverse proxy to route traffic to your Remix app.
sudo apt install nginx -y
sudo ufw allow 'Nginx Full'
sudo systemctl enable nginx
sudo systemctl start nginx
Edit Nginx config:
sudo nano /etc/nginx/sites-available/storestats.invizo.io.conf
sudo ln -s /etc/nginx/sites-available/storestats.invizo.io.conf /etc/nginx/sites-enabled/storestats.invizo.io.conf
Example config:
# HTTP redirect
server {
server_name storestats.invizo.io;
#include nginxconfig.io/letsencrypt.conf
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/storestats.invizo.io/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/storestats.invizo.io/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
# reverse proxy
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;
}
}
server {
if ($host = storestats.invizo.io) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name storestats.invizo.io;
return 404; # managed by Certbot
}
Reload Nginx:
sudo ln -s /etc/nginx/sites-available/storestats.invizo.io /etc/nginx/sites-enabled/
sudo unlink /etc/nginx/sites-enabled/default
sudo nginx -t # should say syntax is ok
sudo systemctl restart nginx
Set up free SSL with Let’s Encrypt (Certbot):
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
7. Clone the Project
Move to your web directory and clone the app repository:
#Enter inside the:
cd /var/www/html
# Add permission
sudo chown -R $USER:www-data /var/www/html
chmod -R g+sw /var/www/html
sudo git clone https://github.com/yourusername/your-remix-shopify-app.git
cd your-remix-shopify-app
8. Create and Configure the .env File
This is critical for Shopify apps.
Make sure you use the exact variable name: SHOPIFY_APP_URL.
cp .env.example .env
nano .env
Add your environment variables:
SHOPIFY_API_KEY=your-key
SHOPIFY_API_SECRET=your-secret
SCOPES=read_products,write_products
# IMPORTANT: Use this exact variable name
SHOPIFY_APP_URL=https://yourdomain.com
DATABASE_URL=postgresql://user:password@host:5432/dbname
Save and exit.
⚠️ If you forget
SHOPIFY_APP_URLor name it incorrectly, you’ll get errors likeDetected an empty appUrl configurationduring app installation.
9. Install Dependencies
Install your project dependencies:
npm install
10. Build the App
Build the Remix app for production:
npm run build
11. Start the App with PM2
Run the app in the background:
pm2 start npm --name "shopify app" -- run start
pm2 save
pm2 startup
Check if it’s running:
pm2 list
12. Wrap Up
Your Shopify Remix app is now:
- Hosted on any cloud server (Hetzner, DigitalOcean, AWS, etc.).
- Served over HTTPS using Nginx.
- Managed by PM2 for automatic restarts and uptime.
Pro Tips
- Keep your
.envfile secure and do not commit it to Git. - Make sure
SHOPIFY_APP_URLmatches the App URL you configured in your Shopify Partner Dashboard. - For debugging:
pm2 logs shopify-remix-app - Set up CI/CD (GitHub Actions, GitLab CI) to automate future deployments.
✅ With this setup, you’ll avoid common mistakes like the Invalid appUrl error and have a stable, production-ready Shopify Remix app running on any cloud provider.