# How to auto-deploy from Replit

- Tool: Replit
- Difficulty: Advanced
- Time required: 25 minutes
- Compatibility: Replit Core ($25/mo) and Pro ($100/mo) — Starter deployments expire after 30 days
- Last updated: March 2026

## TL;DR

Replit offers four deployment types: Autoscale (scales to zero, usage-based), Reserved VM (always-on), Static (free HTML hosting), and Scheduled (cron-style tasks). Configure deployments through the Deployments pane by setting build and run commands in your .replit file, adding production secrets separately from workspace secrets, and clicking Publish. For automated deployments triggered by code changes, connect your Repl to GitHub and use webhooks or CI pipelines to trigger redeployment on push.

## Configure Automatic Deployments from Replit to Production

This tutorial covers the complete deployment workflow in Replit, from configuring the .replit file for production builds to choosing the right deployment type for your application. You will learn how to set up Autoscale deployments that handle variable traffic, Reserved VM deployments for always-on services, and how to automate the deployment pipeline using GitHub integration. The guide also covers the most common deployment failure and how to avoid it.

## Before you start

- A Replit account on Core or Pro plan
- A working web application in your Repl
- Your server binds to 0.0.0.0 (not localhost) on a configured port
- Basic understanding of build processes (npm run build, etc.)
- A GitHub account if setting up automated deployments

## Step-by-step guide

### 1. Configure deployment commands in .replit

Open your .replit file (show hidden files from the file tree menu). Add a [deployment] section with build and run commands. The build command runs once before the app starts (e.g., compiling TypeScript, bundling assets). The run command starts your server in production. These are separate from the workspace run command, which is used only during development. Set deploymentTarget to cloudrun, which is Replit's Google Cloud-backed infrastructure.

```
entrypoint = "src/index.ts"
run = ["npx", "tsx", "src/index.ts"]

[nix]
channel = "stable-24_05"

[[ports]]
localPort = 3000
externalPort = 80

[deployment]
build = ["npm", "run", "build"]
run = ["node", "dist/index.js"]
deploymentTarget = "cloudrun"
```

**Expected result:** Your .replit file has separate development and deployment configurations.

### 2. Add deployment-specific secrets

This is the single most important deployment step that beginners miss. Workspace secrets are NOT automatically available in deployed apps. Open the Deployments pane from the left sidebar, find the Secrets section, and add every environment variable your app needs in production. This includes database connection strings, API keys, and any other sensitive values. If you skip this step, your app will start with undefined values and crash immediately. The error is usually process.env.VAR_NAME returns undefined.

**Expected result:** All required environment variables are listed in the Deployments pane Secrets section with their production values.

### 3. Choose your deployment type

Open the Deployments pane and select your deployment type. Autoscale is the most common choice for web apps. It scales from zero to multiple instances based on traffic and costs about $1/month base plus compute usage. Reserved VM is for apps that need to run continuously, like WebSocket servers or background workers, starting around $10-20/month. Static is free and works for HTML/CSS/JS sites without a backend. Scheduled runs commands on a timer for periodic tasks like backups.

**Expected result:** You have selected the appropriate deployment type for your application's needs.

### 4. Publish your first deployment

Click the Publish button in the Deployments pane. Replit runs your build command, starts your app with the deployment run command, and performs a health check by sending a request to your homepage. The health check must receive a response within 5 seconds or deployment fails. If everything succeeds, your app is live at your-app-name.replit.app. You can see deployment logs in the Deployments pane to debug any issues.

**Expected result:** Your app is live and accessible at the .replit.app URL shown in the Deployments pane.

### 5. Connect GitHub for version-controlled deployments

To automate deployments when you push code, connect your Repl to GitHub. Open the Git tool from the left sidebar. Click Connect to GitHub and authorize Replit to access your repositories. Choose an existing repo or create a new one. Replit syncs your code to the main branch. Now when you push code from your local machine or another editor, the changes appear in your Repl. You still need to click Publish manually, but your code is always in sync.

**Expected result:** Your Repl is connected to a GitHub repository and code syncs bidirectionally.

### 6. Set up automated redeployment with a webhook

For true continuous deployment, create an endpoint in your app that triggers a redeployment when called. Add a webhook endpoint that responds to GitHub push events. When you push code to GitHub, a webhook fires, your Repl pulls the latest code, and the deployment updates. Alternatively, use a scheduled deployment to periodically check for updates and redeploy. For production applications with complex CI/CD requirements, teams can work with RapidDev to design robust deployment pipelines that include testing and staging environments.

```
// Webhook endpoint for automated redeployment
import express from 'express';
import { execSync } from 'child_process';
import crypto from 'crypto';

const app = express();
const WEBHOOK_SECRET = process.env.GITHUB_WEBHOOK_SECRET;

app.post('/webhook/deploy', express.json(), (req, res) => {
  // Verify GitHub signature
  const signature = req.headers['x-hub-signature-256'];
  const hmac = crypto.createHmac('sha256', WEBHOOK_SECRET);
  const digest = 'sha256=' + hmac.update(JSON.stringify(req.body)).digest('hex');

  if (signature !== digest) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Pull latest code
  try {
    execSync('git pull origin main', { cwd: process.cwd() });
    execSync('npm install', { cwd: process.cwd() });
    console.log('Code updated successfully');
    res.json({ success: true, message: 'Deployment triggered' });
  } catch (error) {
    console.error('Deploy failed:', error.message);
    res.status(500).json({ error: 'Deployment failed' });
  }
});

app.listen(3000, '0.0.0.0');
```

**Expected result:** Pushing code to GitHub triggers an automatic pull and update in your deployed Replit app.

## Complete code example

File: `.replit`

```toml
# .replit — Full deployment configuration
# Development and production use separate commands

entrypoint = "src/index.ts"

# Development run command (used when clicking Run)
run = ["npx", "tsx", "watch", "src/index.ts"]

# Hide build artifacts and lock files from the file tree
hidden = [".config", "dist", "node_modules", "package-lock.json"]

# Nix environment
[nix]
channel = "stable-24_05"
packages = ["nodejs-20_x"]

# Port mapping — externalPort MUST be 80
[[ports]]
localPort = 3000
externalPort = 80

# Production deployment configuration
[deployment]
build = ["npm", "run", "build"]
run = ["node", "dist/index.js"]
deploymentTarget = "cloudrun"

# Development environment variables
[run.env]
NODE_ENV = "development"

# Boot command — runs on container start
onBoot = "npm install"

# Deployment checklist:
# 1. Verify server binds to 0.0.0.0 (NOT localhost)
# 2. Add ALL secrets to Deployments pane (separate from workspace)
# 3. Test build command locally: npm run build
# 4. Ensure homepage responds within 5 seconds
# 5. Set externalPort to 80 in [[ports]]
```

## Common mistakes

- **Forgetting to add secrets to the Deployments pane, causing the app to crash with undefined environment variables** — undefined Fix: Open the Deployments pane and add every environment variable your app needs. Workspace secrets do not carry over to deployments automatically.
- **Binding the server to localhost or 127.0.0.1 instead of 0.0.0.0** — undefined Fix: Change your server's listen address to 0.0.0.0. For example, app.listen(3000, '0.0.0.0'). Replit deployments cannot route traffic to localhost-bound servers.
- **Setting externalPort to something other than 80 in the [[ports]] configuration** — undefined Fix: Always set externalPort to 80 in .replit. Your localPort can be any valid port (3000, 5000, 8080), but externalPort must be 80 for the deployment health check to work.
- **Using REPLIT_DEV_DOMAIN in production code, which only exists in the development workspace** — undefined Fix: Use REPLIT_DOMAINS instead, which is available in both development and production environments. REPLIT_DEV_DOMAIN is intentionally absent in deployments.
- **Expecting files written to disk at runtime to persist across deployments** — undefined Fix: The filesystem resets on every publish. Use Object Storage or a database for persistent data. Only files in your source code directory survive redeployment.

## Best practices

- Always add deployment secrets separately from workspace secrets — this is the number one cause of deployment failures
- Bind your server to 0.0.0.0 on the port specified in [[ports]] with externalPort set to 80
- Use compiled output in deployment run commands instead of dev tools like tsx or ts-node
- Test your build command in the Shell before publishing to catch compilation errors early
- Ensure your homepage responds within 5 seconds to pass the Replit health check
- Set budget alerts in the deployment settings to avoid unexpected Autoscale costs during traffic spikes
- Use Reserved VM instead of Autoscale if your app cannot tolerate 10-30 second cold starts
- Check deployment logs immediately after publishing to catch startup errors

## Frequently asked questions

### What is the difference between Autoscale and Reserved VM deployments?

Autoscale scales from zero instances to multiple based on traffic and charges per usage (about $1/month base plus compute). It has a cold start of 10-30 seconds after 15 minutes idle. Reserved VM runs continuously with dedicated resources starting around $10-20/month. Use Autoscale for web apps with variable traffic and Reserved VM for always-on services like WebSocket servers.

### Why does my deployment fail with hostingpid1: an open port was not detected?

Your server is binding to localhost or 127.0.0.1 instead of 0.0.0.0, or the externalPort in your .replit [[ports]] section is not set to 80. Fix both issues and redeploy.

### Do workspace secrets automatically carry over to deployments?

No. This is the most common deployment mistake. You must add every environment variable separately in the Deployments pane Secrets section. Workspace secrets and deployment secrets are completely independent.

### Can I deploy for free on Replit?

Static deployments are free but only serve HTML, CSS, and JavaScript without a backend. Starter plan deployments expire after 30 days. For persistent deployments with a backend, you need a Core or Pro plan.

### How do I set up a custom domain for my deployment?

In the Deployments pane, go to Settings and click Link a domain. Enter your domain name, copy the A records and TXT records Replit generates, and add them to your domain registrar's DNS settings. TLS certificates are automatically provisioned.

### How much does Autoscale deployment cost?

The base fee is $1/month plus compute usage and $0.40 per million requests. A personal blog with 50 visitors per day costs about $1.05/month. An API with 10,000 calls per day costs about $14.27/month. Set budget controls to avoid surprises.

### Can I roll back a failed deployment?

Yes. Replit creates checkpoints during Agent work that you can revert to. You can also use Git history to revert code changes and redeploy. The Deployments pane shows logs from previous deployments to help diagnose issues.

### Why does my app work in development but show Internal Server Error in production?

Almost always caused by missing deployment secrets. Check the Deployments pane logs for errors about undefined values. Also verify that you are not referencing REPLIT_DEV_DOMAIN, which does not exist in production.

---

Source: https://www.rapidevelopers.com/replit-tutorial/how-to-set-up-replit-to-automatically-deploy-changes-to-production-environments
© RapidDev — https://www.rapidevelopers.com/replit-tutorial/how-to-set-up-replit-to-automatically-deploy-changes-to-production-environments
