Dev Log
Shopify App Dev
November 5, 2025

How to Deploy a Shopify App to VPS Using Dokploy: Complete Guide

Shawn Shen avatar
Shawn Shen
Founder of Selofy
min read
Deploying a Shopify app to production can be challenging, especially when moving from local development to a live server. This guide walks you through deploying a Shopify Remix app to a VPS using Dokploy, a self-hosted deployment platform similar to Vercel or Heroku.

Watch Video Tutorial

Deploying a Shopify app to production can be challenging, especially when moving from local development to a live server. This guide walks you through deploying a Shopify Remix app to a VPS using Dokploy, a self-hosted deployment platform similar to Vercel or Heroku.

What You'll Learn

  • Setting up Dokploy on your VPS
  • Configuring PostgreSQL database
  • Deploying your Shopify app
  • Configuring environment variables
  • Setting up GDPR compliance webhooks
  • Connecting to Shopify Partner Dashboard

Prerequisites

Before starting, ensure you have:

  • A VPS server (we used Hostinger VPS)
  • A domain name pointing to your VPS (e.g., yourapp.selofy.com)
  • A Shopify Partner account with an app created
  • Basic knowledge of Git and terminal commands
  • Your Shopify app repository on GitHub

Step 1: Install Dokploy on Your VPS

Dokploy is an open-source Platform-as-a-Service that simplifies deployments. Install it with a single command:

curl -sSL https://dokploy.com/install.sh | sh

The installation takes 3-5 minutes. Once complete:

  1. Access Dokploy admin panel at http://your-vps-ip:3000
  2. Complete the initial setup wizard
  3. Create an admin account

Step 2: Create a PostgreSQL Database

Shopify apps need a database to store session data and app-specific information. (Or you cansuse supabase)

In Dokploy Dashboard:

  1. Navigate to Databases section
  2. Click Create Database
  3. Select PostgreSQL
  4. Configure settings:
    • Database Name: alttext
    • Username: postgres
    • Password: Create a strong password
    • Port: 5432 (default)
  5. Click Create

Dokploy will provision the database and provide a connection string:

postgresql://postgres:your_password@database-internal-hostname:5432/alttext

Important: Save this connection string - you'll need it for environment variables.

Step 3: Configure Your Shopify App Repository

Before deploying, ensure your app repository has the correct configuration files. (I use remix as an example)

Update package.json

Add these scripts to your package.json:

{
 "scripts": {
   "build": "remix vite:build",
   "start": "remix-serve ./build/server/index.js",
   "dev": "shopify app dev"
 }
}

The start script runs your production server, while build creates the production bundle.

Configure Prisma for PostgreSQL

Update your prisma/schema.prisma file to use PostgreSQL:

datasource db {
 provider = "postgresql"
 url      = env("DATABASE_URL")
}

generator client {
 provider = "prisma-client-js"
}

Update Migration Lock

Change prisma/migrations/migration_lock.toml to PostgreSQL:

provider = "postgresql"

If you previously used SQLite, you'll need to regenerate migrations:

# Delete old migrations (backup first!)
rm -rf prisma/migrations

# Create new migration for PostgreSQL
npx prisma migrate dev --name init

Configure Docker Ignore

Create or update .dockerignore to exclude unnecessary files:

node_modules
.env
.git
.cache
build
dist
*.log
.DS_Store

Critical: Exclude .env to prevent leaking secrets. Environment variables should be set in Dokploy, not bundled in the image.

Commit and Push Changes

git add .
git commit -m "Configure for production deployment"
git push origin main

Step 4: Create Application in Dokploy

Now deploy your app to Dokploy:

  1. Go to Applications in Dokploy
  2. Click Create Application
  3. Select GitHub as source
  4. Authorize Dokploy to access your repository
  5. Select your Shopify app repository
  6. Configure build settings:
    • Branch: main (or your production branch)
    • Build Pack: nixpacks (auto-detects Node.js)
    • Port: 3000
deploy shopify app on vps using dokploy

Step 5: Configure Environment Variables

This is the most critical step. Your app needs specific environment variables to function.

In Dokploy Application Settings → Environment Variables:

#Nixpacks build commands
NIXPACKS_INSTALL_CMD=pnpm install --frozen-lockfile --ignore-scripts
NIXPACKS_BUILD_CMD=pnpm run build
NIXPACKS_START_CMD=pnpm run start
#Network Configuration
HOST=0.0.0.0
PORT=3000
#Shopify Configuration
#Get these values from your Shopify Partner Dashboard → Apps → [Your App]:
SHOPIFY_API_KEY=your_client_id_here
SHOPIFY_API_SECRET=your_api_secret_here
SHOPIFY_APP_URL=https://your-domain.com
#Scopes
#Your app needs specific API permissions:
SCOPES=read_products,write_products,read_files,write_files,read_content,write_content
#Database Configuration
#Important: Replace your-db-hostname with the internal database hostname provided by Dokploy (usually something like shopify-app-db-xxxxx).
DATABASE_URL=postgresql://postgres:your_password@your-db-hostname:5432/alttext
#Optional Session Security
#SHOPIFY_SESSION_SECRET=your_secure_random_string_here
#Production Environment
NODE_ENV=production
deploy shopify app on vps using dokploy

Step 6: Deploy Your Application

With all environment variables configured:

  1. Click Deploy in Dokploy
  2. Monitor build logs in real-time
  3. Wait for deployment to complete (3-5 minutes)

Common Build Issues:

Issue: prisma:generate fails Solution: Add --ignore-scripts to install command (already included above)

Issue: Database connection error Solution: Verify DATABASE_URL format and database hostname

Issue: Port binding error Solution: Ensure HOST=0.0.0.0 (not localhost)

Step 7: Run Database Migrations

After successful deployment, your database needs the schema:

  1. Go to Dokploy Application → Terminal
  2. Open a terminal session in your running container
  3. Run Prisma migrations:

npx prisma migrate deploy

This creates all necessary database tables.

Step 8: Configure Domain and SSL

Add Domain in Dokploy

  1. Navigate to Application → Domains
  2. Click Add Domain
  3. Enter your domain: alttext.selofy.com
  4. Enable SSL/TLS (Let's Encrypt automatic)
  5. Save and wait for SSL provisioning (1-2 minutes)

Verify DNS Configuration

Ensure your domain's DNS A record points to your VPS IP:

Type: A
Name: alttext (or subdomain)
Value: your.vps.ip.address
TTL: 3600

Test SSL certificate:

curl -I https://alttext.selofy.com

You should see HTTP/2 200 with valid SSL.

Step 9: Configure Shopify Partner Dashboard

Now connect your deployed app to Shopify:

Update App URL

  1. Go to Shopify Partner Dashboard
  2. Select your app
  3. Navigate to Configuration → App URL
  4. Update to: https://alttext.selofy.com
  5. Save changes

Configure Redirect URLs

Still in ConfigurationURLs:

Add these redirect URLs:

https://alttext.selofy.com/auth/callback
https://alttext.selofy.com/auth/shopify/callback

These handle OAuth authentication after merchants install your app.

Configure Access Scopes

In ConfigurationAccess Scopes:

Add the same scopes from your environment variables:

  • read_products
  • write_products
  • read_files
  • write_files
  • read_content
  • write_content

Click Save.

Step 10: Set Up GDPR Compliance Webhooks

All Shopify apps must implement three GDPR compliance webhooks.

Create Webhook Handler Files

In your app repository, create these files:

app/routes/webhooks.customers.data_request.tsx

import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";

export const action = async ({ request }: ActionFunctionArgs) => {
 
const { shop, payload } = await authenticate.webhook(request);

 
const customerId = payload.customer?.id;
 console.log(`Customer data request: ${shop}, customer: ${customerId}`);

 
// TODO: Implement data retrieval and send to customer
 
// Collect all customer data from your database
 
// Format according to GDPR requirements
 
// Send via email or make available for download

 
return new Response();
};

app/routes/webhooks.customers.redact.tsx

import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
import db from "../db.server";

export const action = async ({ request }: ActionFunctionArgs) => {
 
const { shop, payload } = await authenticate.webhook(request);

 
const customerId = payload.customer?.id;
 console.log(`Customer redaction request: ${shop}, customer: ${customerId}`);

 
// Delete all customer-specific data from your database
 
// Example (adjust based on your schema):
 
// await db.customerData.deleteMany({
 
//   where: { customerId: customerId }
 
// });

 
return new Response();
};

app/routes/webhooks.shop.redact.tsx

import type { ActionFunctionArgs } from "@remix-run/node";
import { authenticate } from "../shopify.server";
import db from "../db.server";

export const action = async ({ request }: ActionFunctionArgs) => {
 
const { shop, payload } = await authenticate.webhook(request);

 
const shopDomain = payload.shop_domain || shop;
 console.log(`Shop redaction request: ${shopDomain}`);

 
try {
   
// Delete ALL shop data from your database
   
await db.session.deleteMany({ where: { shop: shopDomain } });
   
await db.userSettings.deleteMany({ where: { shopDomain } });
   
// Add all your other tables here

   console.log(`Successfully redacted all data for: ${shopDomain}`);
 }
catch (error) {
   console.error(`Error redacting shop data:`, error);
 }

 
return new Response();
};

Configure Webhooks in shopify.app.toml

Update your shopify.app.toml configuration file:

client_id = "your_client_id"
name = "Your App Name"
application_url = "https://alttext.selofy.com"
embedded = true

[build]
automatically_update_urls_on_dev = true

[webhooks]
api_version = "2025-07"

[[webhooks.subscriptions]]
topics = [ "app/uninstalled" ]
uri = "/webhooks/app/uninstalled"

[[webhooks.subscriptions]]
compliance_topics = [ "customers/data_request" ]
uri = "/webhooks/customers/data_request"

[[webhooks.subscriptions]]
compliance_topics = [ "customers/redact" ]
uri = "/webhooks/customers/redact"

[[webhooks.subscriptions]]
compliance_topics = [ "shop/redact" ]
uri = "/webhooks/shop/redact"

[access_scopes]
scopes = "read_products,write_products,read_content,write_content,read_files,write_files"

[auth]
redirect_urls = [
 "https://alttext.selofy.com/auth/callback",
 "https://alttext.selofy.com/auth/shopify/callback"
]

Critical: GDPR webhooks must use compliance_topics, not regular topics.

Deploy Webhook Configuration

Commit your changes:

git add app/routes/webhooks.* shopify.app.toml
git commit -m "Add GDPR compliance webhooks"
git push origin main

Redeploy in Dokploy (or wait for auto-deploy if configured).

Register Webhooks with Shopify

Use Shopify CLI to deploy the webhook configuration:

shopify app deploy --force

This registers all webhooks defined in shopify.app.toml with Shopify.

Verify in Partner Dashboard:

  1. Go to Configuration → Webhooks
  2. You should see all three GDPR compliance webhooks listed
  3. Each shows the correct URI and API version

Step 11: Test Your Deployment

Test Basic App Access

Visit your app URL:

https://alttext.selofy.com

You should see a Shopify login page asking for a store domain.

Install on Development Store

  1. Enter your development store domain (e.g., mystore.myshopify.com)
  2. Click "Log in"
  3. Shopify redirects to OAuth authorization page
  4. Click "Install app"
  5. App should load successfully in Shopify Admin

Verify Database Connection

Check your app's functionality:

  • Settings save correctly
  • Data persists after page refresh
  • No console errors about database connection

Test Webhooks

  1. In Shopify Admin, go to Settings → Apps and sales channels
  2. Find your app and click Uninstall (don't worry, you can reinstall)
  3. Check your application logs in Dokploy
  4. You should see the app/uninstalled webhook logged

Reinstall the app to continue testing.

Step 12: Monitor and Maintain

Application Logs

Monitor your app in Dokploy:

  1. Go to Application → Logs
  2. View real-time application output
  3. Filter by error/warning levels

Database Backups

Set up automatic backups in Dokploy:

  1. Navigate to Databases → Your Database
  2. Go to Backups tab
  3. Configure automatic backup schedule (daily recommended)
  4. Test restore process

Update Deployments

When pushing code updates:

Automatic Deployment (recommended):

  1. Enable auto-deploy in Dokploy application settings
  2. Push to your main branch
  3. Dokploy automatically rebuilds and deploys

Manual Deployment:

  1. Push code to GitHub
  2. Go to Dokploy application
  3. Click Deploy button

Zero-Downtime Deployments

Dokploy supports rolling deployments:

  1. New version builds while old version runs
  2. Traffic switches to new version when ready
  3. Old version terminates after health check passes

Production Best Practices

1. Environment Variables Security

  • Never commit .env files to Git
  • Use Dokploy's environment variable management
  • Rotate API secrets regularly
  • Use different secrets for development and production

2. Database Management

  • Enable automatic backups
  • Test restore process regularly
  • Use connection pooling for better performance
  • Monitor database size and query performance

3. Monitoring and Logging

  • Set up error tracking (e.g., Sentry)
  • Monitor application performance
  • Set up alerts for critical errors
  • Regularly review application logs

4. Scaling Considerations

  • Start with a single container
  • Scale horizontally when needed (Dokploy supports multiple instances)
  • Use Redis for session storage if scaling beyond one instance
  • Monitor CPU and memory usage

5. Updates and Maintenance

  • Test updates on staging environment first
  • Schedule maintenance during low-traffic periods
  • Keep dependencies updated
  • Follow Shopify API versioning guidelines

Cost Breakdown

Approximate monthly costs for this setup:

  • VPS Server: $10-50/month (depending on specs)
  • Domain Name: $10-15/year
  • Dokploy: Free (self-hosted)
  • PostgreSQL: Included with Dokploy
  • SSL Certificate: Free (Let's Encrypt)

Total: ~$15-55/month

Compare to alternatives:

  • Heroku: ~$50-100/month (with database)
  • Fly.io: ~$20-80/month
  • AWS/GCP: ~$30-150/month

Conclusion

You now have a production-ready Shopify app deployed on your VPS using Dokploy. This setup provides:

✅ Secure HTTPS connection with automatic SSL ✅ PostgreSQL database with automated backups ✅ GDPR compliance webhooks ✅ OAuth authentication ✅ Environment variable management ✅ Easy deployment and updates ✅ Application monitoring and logs

The self-hosted approach with Dokploy gives you full control, lower costs, and eliminates vendor lock-in while maintaining ease of use similar to Heroku or Vercel.

Next Steps

  1. Set up monitoring: Integrate error tracking and performance monitoring
  2. Add CI/CD: Automate testing before deployment
  3. Configure staging environment: Test updates before production
  4. Optimize performance: Add caching, CDN for static assets
  5. Submit to Shopify App Store: Follow Shopify's listing guidelines

Frequently Asked Questions

How to fix issue: "Invalid OAuth callback URL"
Howwto fix Issue: Database connection timeout
Issue: Webhook validation failed
Issue: Build fails with Prisma errors
Issue: App loads but shows 500 errors
Related Blogs
Cloud Proxy API Service Deployment Guide logo Image
Dev Log
Shopify App Dev
Cloud Proxy API Service Deployment Guide
Complete Guide to Google Merchant API Authorization for Shopify Apps logo Image
Dev Log
Shopify App Dev
Complete Guide to Google Merchant API Authorization for Shopify Apps
How to Self‑Host a Stable Shopify App Dev Tunnel with FRP + Cloudflared (Fixed Port Mode) logo Image
Dev Log
Shopify App Dev
How to Self‑Host a Stable Shopify App Dev Tunnel with FRP + Cloudflared (Fixed Port Mode)
How to Deploy FRP on Dokploy Platform logo Image
Dev Log
Shopify App Dev
How to Deploy FRP on Dokploy Platform
Configuring Fixed Port for Shopify App Dev Tunnel (Vite Modification) logo Image
Dev Log
Shopify App Dev
Configuring Fixed Port for Shopify App Dev Tunnel (Vite Modification)
Shopify App Dev Localhost Error: Invalid Webhook URI Fix logo Image
Dev Log
Dev Log
Shopify App Dev Localhost Error: Invalid Webhook URI Fix
How I Built an E-commerce Toolkit with Zero Coding Experience - Dev Log #001 logo Image
Dev Log
Dev Log
How I Built an E-commerce Toolkit with Zero Coding Experience - Dev Log #001