How to develop safely on shared hosting that supports FTP/SSH but blocks direct IDE connections

If you’ve ever worked on a client project hosted on shared hosting—the kind that offers FTP and SSH access but doesn’t allow your IDE to connect directly to the server—you know the frustration. You can’t use remote development features, live sync, or server-side debugging the way you might on a VPS or managed platform. So how do you work safely without editing files directly on production?

The answer is a local-first workflow with SFTP sync. Here’s how to set it up and avoid the pitfalls.

The Problem

Many shared hosting providers give you:

  • FTP/SFTP access for file transfer
  • SSH access (often on non-standard ports)
  • No support for remote development extensions or direct IDE-to-server connections

That means you can’t “open folder on server” or use tools that assume a persistent, low-latency connection. You’re left with:

  1. Editing directly on the server — Risky, no version control, no local testing
  2. Manual FTP uploads — Tedious and error-prone
  3. A proper local workflow — What we’re aiming for

The Solution: Local Development + SFTP Sync

The workflow is simple:

  1. Clone or download the site to your machine
  2. Run it locally (e.g., XAMPP, MAMP, Laragon, or Docker)
  3. Develop and test locally
  4. Sync changes to the server via an SFTP plugin when you’re ready

Your IDE stays connected to local files. The SFTP plugin handles uploads. You never edit production directly.

Step 1: Get the Site Running Locally

1.1 Get the Files

Download the site via SFTP or use your host’s file manager. You need the full application (e.g., framework files, public_html, config templates—everything except sensitive production configs you’ll recreate locally).

1.2 Set Up a Local Stack

Use XAMPP, MAMP, Laragon, or Docker—whatever you prefer. Point the document root to your project folder.

1.3 Configure Your Hosts File

Add a local domain so you can use something like myproject.local instead of localhost/myproject:

127.0.0.1 myproject.local
127.0.0.1 www.myproject.local

On Windows: C:\Windows\System32\drivers\etc\hosts
On macOS/Linux: /etc/hosts

1.4 Adjust Local Config

Update your framework config (e.g., config.phpdatabase.php) for local use:

  • Base URLhttp://myproject.local/ (or your chosen local domain)
  • Database: Local MySQL credentials and database name

Important: Add these config files to your SFTP ignore list so you never overwrite production config with local values.

Step 2: Configure the SFTP Plugin

VS Code users can use the SFTP extension (by Natizyskunk). Cursor and other VS Code–based editors support it too.

Create .vscode/sftp.json in your project:

{
"name": "Production Server",
"host": "ssh.yourdomain.com",
"protocol": "sftp",
"port": 18765,
"username": "your-username",
"privateKeyPath": "C:/path/to/your/private-key",
"remotePath": "/home/username/www/yourdomain.com/public_html/",
"uploadOnSave": false,
"syncMode": "update",
"ignore": [
".vscode",
".git",
"node_modules",
"**/application/config/config.php",
"**/application/config/database.php"
]
}

Key Settings Explained

SettingRecommendationWhy
uploadOnSavefalsePrevents accidental uploads before you’ve tested locally
syncMode"update"Only uploads changed files; doesn’t delete remote files you might have only on the server
ignoreConfig files, .git.vscodeKeeps local config and tooling out of production

Authentication

Use SSH key authentication when possible. Generate a key pair, add the public key in your host’s control panel, and point privateKeyPath to the private key. It’s more secure than passwords and avoids repeated prompts.

Note: Shared hosts often use non-standard SSH ports (e.g., 18765 instead of 22). Check your hosting docs for the correct port.

Step 3: Handle Redirects and Environment-Specific Rules

If your .htaccess (or equivalent) forces HTTPS and redirects to the live domain, it will redirect your local site too. Exclude your local domain from those rules.

Example for Apache:

# Force HTTPS + WWW (skip for local development)
RewriteCond %{HTTP_HOST} !^myproject\.local$ [NC]
RewriteCond %{HTTP_HOST} !^www\.myproject\.local$ [NC]
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.yourdomain.com/$1 [L,R=301]

This keeps production redirects intact while allowing myproject.local to work locally.

Step 4: Watch Out for PHP Version Mismatches

Your local PHP version may differ from the server. If the live site runs PHP 7.4 and you’re on PHP 8.2+, you can hit deprecation warnings (e.g., dynamic properties) that don’t appear in production.

Options:

  1. Match production — Use the same PHP version locally (e.g., switch XAMPP to PHP 7.4)
  2. Suppress deprecations in development — In your index.php or bootstrap, exclude E_DEPRECATED and E_USER_DEPRECATED when ENVIRONMENT is development

Matching production is ideal for parity; suppressing deprecations is a practical shortcut if you need to move quickly.

Step 5: Your Day-to-Day Workflow

  1. Pull or sync — If others work on the project, get the latest files first
  2. Develop locally — Edit, run, test in the browser at http://myproject.local
  3. Verify — Check functionality, forms, and key pages
  4. Upload — Right-click the project (or a folder) in the file explorer → SFTP: Upload (or use the command palette)
  5. Smoke test on live — Do a quick check on the real site

Because uploadOnSave is off, you control when changes go up. Because config files are ignored, you won’t overwrite production settings.

Tips and Best Practices

  • Use version control — Even if the client doesn’t use Git, keep a local repo. It gives you history and rollback options.
  • Document your setup — Note the SFTP port, config differences, and any host-specific quirks. Future-you (or another dev) will thank you.
  • Test before uploading — A quick click-through locally can save you from breaking production.
  • Back up before big changes — Use your host’s backup tool or download a copy before major updates.
  • Consider a staging subdomain — If the host allows it, use a staging URL for final checks before going to the main domain.

When This Approach Makes Sense

This workflow fits:

  • Shared hosting with FTP/SSH but no direct IDE support
  • PHP apps (WordPress, CodeIgniter, Laravel, custom)
  • Small teams or solo developers
  • Projects where a full CI/CD pipeline isn’t in place

It’s not a replacement for proper staging environments or deployment pipelines, but it’s a solid, practical approach when those aren’t available.

Wrapping Up

You don’t need direct IDE-to-server access to work safely. A local stack, a hosts entry, careful config management, and an SFTP plugin give you a clean, repeatable workflow. Develop locally, test locally, upload when ready—and keep production configs out of the sync.

If you’ve set up a similar workflow or hit different obstacles, sharing your experience can help others in the same situation.

Leave a comment