Why Your First Production Deploy Will Fail

The "Just Change Dev to Prod" Disaster

My first prod deploy broke during a busy sales day. The client was pissed. Turns out you can't just run shopify app dev pointed at production - learned that after watching error logs for 4 straight hours.

Here's what broke when I tried the obvious approach:

What seemed logical:

## Seemed reasonable at 2am
shopify app dev --store=production-store.myshopify.com
## Spoiler: dev server != production deployment

What actually exploded:

  • Development tunneling tried to connect to production URLs
  • Interactive authentication prompts hung the deployment forever
  • SQLite database got wiped on every restart
  • Environment variables were mixed between dev and prod
  • SSL certificates were completely fucked

TOML Files Will Ruin Your Day

Shopify CLI 3.x uses TOML files for configuration, and they're more finicky than the docs let on.

This breaks in production (learned the hard way):

## shopify.app.prod.toml - DON'T DO THIS
application_url = "http://localhost:3000"  # Whoops

This actually works:

## shopify.app.prod.toml 
name = "your-app"
client_id = "your_client_id"
application_url = "https://your-actual-domain.com"

[build]
  automatically_update_urls_on_dev = false  # CRITICAL for production

[app_proxy]
  url = "https://your-actual-domain.com/api/proxy"

The application_url has to match exactly. Burned 6 hours debugging auth loops because my TOML had https://app.example.com but I deployed to https://example-app.herokuapp.com. Shopify's TOML docs mention this but it's buried in paragraph 3.

Authentication Tokens: Expiry Hell at 2AM

Development uses interactive OAuth. Production needs CLI tokens. These tokens expire, and they'll do it at the worst possible moment.

Generate tokens in the Partner Dashboard under Settings > CLI Tokens. The CLI auth docs explain this but miss the expiry gotchas.

Token reality:

  • They expire without warning (usually 60-90 days based on GitHub issues)
  • Max 2 active tokens per Partner account
  • Failed deploys just say "Authentication failed" - zero context
  • No expiry date shown in the dashboard

Set this environment variable:

export SHOPIFY_CLI_PARTNERS_TOKEN="your_token_here"

Pro tip: Set up token expiry monitoring. I learned this after a deployment failed because the token expired at the worst possible moment.

The --force Flag Is Not Optional

The --force flag isn't a suggestion - it's mandatory for non-interactive deployments:

shopify app deploy --config=prod --force

Without --force, the CLI waits for interactive confirmation that'll never come in CI/CD. Your pipeline hangs for 10 minutes then times out. Yeah, I learned this the hard way at 11pm on a Friday.

After Trying Heroku, Vercel, Railway, and AWS

Database

Cost

Persistence

Concurrent Users

Backup

SQLite

Free

❌ Resets on deploy

1

Manual file copy

Render PostgreSQL

$7/month

✅ Persistent

Unlimited

Automated daily

Supabase

Free tier

✅ Persistent

Good

Built-in

GitHub Actions Config That Actually Works

The official Shopify CI/CD docs give you the basics, but miss the retry logic and timeout handling.

Here's what actually works:

name:

 Deploy to Production
on:
  push:
    branches: [main]
  workflow_dispatch:  # Manual trigger for emergencies

env:

  NODE_VERSION: 20

jobs:
  deploy:
    name:

 Deploy App
    runs-on: ubuntu-latest
    environment: production  # This is critical for approval gates
    timeout-minutes: 15      # Don't let it hang forever
    
    steps:

- name:

 Checkout
      uses: actions/checkout@v4
      
    
- name:

 Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: ${{ env.

NODE_VERSION }}
        cache: 'npm'
    
    
- name:

 Install dependencies
      run: npm ci --ignore-scripts  # Ignore scripts prevents malware
    
    
- name:

 Install Shopify CLI
      run: npm install -g @shopify/cli@3.84.1
    
    
- name:

 Deploy to Shopify with retry
      env:
        SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.

SHOPIFY_CLI_PARTNERS_TOKEN }}
        SHOPIFY_APP_URL: ${{ secrets.

SHOPIFY_APP_URL }}
      run: |
        # Retry logic added after Git

Hub Actions crapped out during a Friday deploy
        for attempt in 1 2 3; do
          if shopify app deploy --config=production --force --verbose; then
            echo "✅ Deployment successful on attempt $attempt"
            exit 0
          else
            echo "❌ Attempt $attempt failed, retrying in 30 seconds..."
            sleep 30
          fi
        done
        echo "💥 All deployment attempts failed"
        exit 1
    
    
- name:

 Notify on failure
      if: failure()
      uses: actions/github-script@v7
      with:
        script: |
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: '🚨 Production deployment failed!

 Check the logs.'
          })

The Secrets That'll Make or Break Your Deployment

Required secrets in GitHub > Settings > Secrets and variables > Actions:

SHOPIFY_CLI_PARTNERS_TOKEN=shpca_abcd1234...

SHOPIFY_APP_URL=https://your-actual-domain.com
DATABASE_URL=postgresql://user:pass@host:5432/db
SESSION_SECRET=super-long-random-string-minimum-32-chars

Gotchas that cost me hours:

  • Missing environment: production means every commit deploys (learned this during a late-night git rebase that deployed 15 commits at once)
  • Dev/prod apps use different tokens
  • Partner Dashboard shows which is which
  • No timeout = hung deploys waste your 2000 free minutes fast
  • The GitHub Actions documentation covers timeouts but examples don't use them

Environment Protection (Don't Skip This)

Go to Settings > Environments > production and set these up:

Required reviewers: Add at least one team member who can approve at 3am Wait timer: 10 minutes (gives you time to catch obvious fuckups) Branch protection: Only allow deployments from main

Saved my ass when I almost pushed broken code at 3am that would've fucked the checkout flow. GitHub environment protection docs explain the full setup.

When the CLI Randomly Breaks (And It Will)

Common CLI failures I've encountered in production:

Error: Authentication failed Fix: Token expired.

Generate a new one in Partner Dashboard.

Error: App not found
Fix: Wrong client_id in your TOML file or token is for wrong organization.

Error: Network request failed Fix: GitHub's network having issues.

The retry loop above handles this.

Error: Invalid configuration Fix: Your application_url doesn't match the actual deployed URL.

Error: Command hangs forever Fix: You forgot the --force flag, it's waiting for interactive input.

When Everything Goes to Shit (Rollback Process)

The CLI doesn't have a native rollback command, so you need this manual process:

  1. Go to Partner Dashboard > Apps > [Your App] > App versions
  2. Find the last working version and click "Make current"
  3. Wait 2-5 minutes for propagation (users will see old version)
  4. Fix the issue locally and deploy again

Pro tip: Tag your releases so you know which commit to revert to:

- name:

 Tag release
  run: git tag "release-$(date +%Y%m%d-%H%M%S)"

Stuff That Broke at the Worst Possible Times

Q

Deploy says success, app shows 500 errors

A

This happened during our Series A demo.

The CLI only pushes config to Shopify

  • your hosting deploy can fail separately. Check your hosting dashboard, not just the CLI output.Try this, if that doesn't work, restart everything:bashshopify app deploy --config=prod --force --no-release# Wait for hosting to actually finish# Manually release in Partner Dashboard
Q

Auth randomly stops working

A

CLI tokens expire every 60-90 days with zero warning. First sign is usually "Authentication failed" during deploy.Partner Dashboard Settings page shows active tokens but no expiry dates. Generate a new one, delete the old one. Max 2 tokens per account.

Q

Same token for dev and prod?

A

Nope. Dev and production are separate apps in Shopify. Dev token against production gives "App not found" errors. Took me 2 hours to figure this shit out.

Each environment needs:

  • Separate app in Partner Dashboard
  • Separate TOML configuration file
  • Separate CLI authentication token
  • Separate client_id and client_secret

There's no shortcut here. Create the production app properly.

Q

GitHub Actions deploy hangs for 10 minutes then fails

A

Missing --force flag. CLI waits for interactive confirmation that'll never come in CI. Official deploy docs mention this but it's easy to miss.

Always use in CI/CD:

shopify app deploy --config=prod --force

Never use in CI/CD:

shopify app deploy --config=prod  # This hangs forever

Set a timeout in your GitHub Actions workflow or it'll waste your free minutes:

timeout-minutes: 15
Q

Database keeps getting wiped on every deployment - how do I fix this?

A

You're using SQLite in production. SQLite files get deleted on every deployment because containers are ephemeral.

Fix #1: Use PostgreSQL

DATABASE_URL="postgresql://user:pass@host:5432/db"

Fix #2: If stuck with SQLite, use persistent volumes
Most hosting services support this, but it's a pain to set up and doesn't scale.

Services with easy PostgreSQL:

  • Render: $7/month, just works
  • Supabase: Free tier, PostgreSQL + real-time
  • PlanetScale: MySQL, generous free tier
Q

Env vars work locally, break in production

A

.env files don't get deployed.

Set vars in your hosting dashboard

Q

Rollback after breaking production

A

No CLI rollback command exists. Manual process through Partner Dashboard:

  1. Apps > Your App > App versions
  2. Click "Make current" on last working version
  3. Wait 2-5 minutes for global propagation

This only rolls back Shopify config. Your hosting (Render/Heroku) needs separate rollback - usually involves redeploying old git commit.

Related Tools & Recommendations

howto
Similar content

Install Node.js & NVM on Mac M1/M2/M3: A Complete Guide

My M1 Mac setup broke at 2am before a deployment. Here's how I fixed it so you don't have to suffer.

Node Version Manager (NVM)
/howto/install-nodejs-nvm-mac-m1/complete-installation-guide
100%
integration
Similar content

Claude API Node.js Express: Advanced Code Execution & Tools Guide

Build production-ready applications with Claude's code execution and file processing tools

Claude API
/integration/claude-api-nodejs-express/advanced-tools-integration
94%
tool
Similar content

Node.js Production Troubleshooting: Debug Crashes & Memory Leaks

When your Node.js app crashes in production and nobody knows why. The complete survival guide for debugging real-world disasters.

Node.js
/tool/node.js/production-troubleshooting
77%
tool
Similar content

Kibana - Because Raw Elasticsearch JSON Makes Your Eyes Bleed

Stop manually parsing Elasticsearch responses and build dashboards that actually help debug production issues.

Kibana
/tool/kibana/overview
77%
tool
Similar content

React Production Debugging: Fix App Crashes & White Screens

Five ways React apps crash in production that'll make you question your life choices.

React
/tool/react/debugging-production-issues
68%
howto
Similar content

Mastering ML Model Deployment: From Jupyter to Production

Tired of "it works on my machine" but crashes with real users? Here's what actually works.

Docker
/howto/deploy-machine-learning-models-to-production/production-deployment-guide
66%
troubleshoot
Similar content

Fix MySQL Error 1045 Access Denied: Solutions & Troubleshooting

Stop fucking around with generic fixes - these authentication solutions are tested on thousands of production systems

MySQL
/troubleshoot/mysql-error-1045-access-denied/authentication-error-solutions
64%
tool
Similar content

GitLab CI/CD Overview: Features, Setup, & Real-World Use

CI/CD, security scanning, and project management in one place - when it works, it's great

GitLab CI/CD
/tool/gitlab-ci-cd/overview
62%
tool
Similar content

Hardhat Advanced Debugging & Testing: Debug Smart Contracts

Master console.log, stack traces, mainnet forking, and advanced testing techniques that actually work in production

Hardhat
/tool/hardhat/debugging-testing-advanced
62%
tool
Similar content

LM Studio Performance: Fix Crashes & Speed Up Local AI

Stop fighting memory crashes and thermal throttling. Here's how to make LM Studio actually work on real hardware.

LM Studio
/tool/lm-studio/performance-optimization
60%
tool
Similar content

Certbot: Get Free SSL Certificates & Simplify Installation

Learn how Certbot simplifies obtaining and installing free SSL/TLS certificates. This guide covers installation, common issues like renewal failures, and config

Certbot
/tool/certbot/overview
58%
tool
Similar content

Debugging AI Coding Assistant Failures: Copilot, Cursor & More

Your AI assistant just crashed VS Code again? Welcome to the club - here's how to actually fix it

GitHub Copilot
/tool/ai-coding-assistants/debugging-production-failures
58%
tool
Similar content

mongoexport: Export MongoDB Data to JSON & CSV - Overview

MongoDB's way of dumping collection data into readable JSON or CSV files

mongoexport
/tool/mongoexport/overview
58%
tool
Similar content

Binance API Security Hardening: Protect Your Trading Bots

The complete security checklist for running Binance trading bots in production without losing your shirt

Binance API
/tool/binance-api/production-security-hardening
54%
howto
Similar content

Git: How to Merge Specific Files from Another Branch

November 15th, 2023, 11:47 PM: Production is fucked. You need the bug fix from the feature branch. You do NOT need the 47 experimental commits that Jim pushed a

Git
/howto/merge-git-branch-specific-files/selective-file-merge-guide
54%
tool
Similar content

Node.js Security Hardening Guide: Protect Your Apps

Master Node.js security hardening. Learn to manage npm dependencies, fix vulnerabilities, implement secure authentication, HTTPS, and input validation.

Node.js
/tool/node.js/security-hardening
52%
howto
Similar content

Install GitHub CLI: A Step-by-Step Setup Guide

Tired of alt-tabbing between terminal and GitHub? Get gh working so you can stop clicking through web interfaces

GitHub CLI
/howto/github-cli-install/complete-setup-guide
50%
integration
Similar content

Claude API Node.js Express Integration: Complete Guide

Stop fucking around with tutorials that don't work in production

Claude API
/integration/claude-api-nodejs-express/complete-implementation-guide
50%
tool
Similar content

PostgreSQL: Why It Excels & Production Troubleshooting Guide

Explore PostgreSQL's advantages over other databases, dive into real-world production horror stories, solutions for common issues, and expert debugging tips.

PostgreSQL
/tool/postgresql/overview
48%
tool
Similar content

Node.js Performance Optimization: Boost App Speed & Scale

Master Node.js performance optimization techniques. Learn to speed up your V8 engine, effectively use clustering & worker threads, and scale your applications e

Node.js
/tool/node.js/performance-optimization
48%

Recommendations combine user behavior, content similarity, research intelligence, and SEO optimization