Web Development

Muse Can't SSH Into Your Server? The GitHub Deploy Route That Actually Works

By Asad Ali ·

When an AI assistant like Muse deploys your site, SSH and FTP can fail silently — the network blocks their ports and only HTTPS gets through. This guide explains the problem and the GitHub deploy route that fixes it, step by step.

12 min readLast updated

Muse can't SSH into your server — the GitHub deploy route that actually works. Laptop blocked by a wall, GitHub branch delivers to the server.

If you use an AI assistant like Muse to build or maintain your website, you may hit a strange wall: SSH will not connect. FTP will not connect. Nothing gives an error — the connection just dies, silently, every single time. The cause is simple once you see it: the cloud environment the AI runs in only lets web traffic (HTTPS) out. Every other port — SSH, FTP, SFTP — is quietly dropped by the network before it ever reaches your server. This guide explains how to recognise the problem, why the usual fixes do not work, and the route that solves it properly: deployment through GitHub, over HTTPS, with a complete step-by-step setup.

The problem: silent port blocking

AI coding assistants increasingly do real operational work: they edit your site, then deploy the changes to your server themselves. The traditional way to deploy is SSH (or its file-transfer sibling, SFTP), with FTP as the old fallback. That works fine from your own computer. From inside many AI sandboxes and cloud workspaces, it does not work at all.

The symptoms are always the same:

  • The connection dies at the very first step — the SSH handshake never starts. There is no "permission denied", no timeout message from the server, just a reset or endless silence.
  • Retrying never helps. Deployment scripts can retry hundreds of times, at any hour, and the result never changes — because the request never leaves the AI's network in the first place.
  • FTP is just as dead. Even with the right host, port 21 and correct credentials, the connection gets no response at all — not even the server's greeting banner.
  • Everything works from your own machine. The same server, same credentials, same network settings connect instantly from your laptop — proving the server, the password and the key were never the problem.

What is actually happening: the environment the AI runs in has an egress policy — a list of what is allowed to leave. Web traffic on port 443 (HTTPS) is allowed, because the AI needs it to browse and call APIs. Ports like 22 (SSH) or 21 (FTP), and custom variants like 65002, are not on the list, so the packets are silently discarded. "Silently" is the key word: a dropped packet produces no error message, which is why this problem eats hours — everything looks like a server or credentials problem, and it is neither.

Why PuTTY (or any other SSH client) does not fix it

The first instinct is to switch tools: try PuTTY, Termius, a different terminal, a different library. It cannot help, for one simple reason: the client is not the problem — the road is. Every SSH client, no matter how good, has to send its traffic out through the SSH port. If the network in front of the AI drops traffic on that port, PuTTY's packets drop exactly the way the built-in client's do.

PuTTY on your own computer works because your home or office network does not have this restriction. But then you are the one doing the deploying, by hand, every time — which defeats the entire point of having an AI assistant maintain the site.

For the same reason, SFTP and FTPS are not workarounds: SFTP rides on SSH and FTPS rides on FTP, so both inherit the blocked channel. When the port is dropped, every protocol built on top of it is dropped too.

The pattern, in one table

RoutePort / channelFrom the AI's environment
SSH / SCP / SFTP22 or a custom portSilently dropped
FTP / FTPS21Silently dropped — not even a greeting
Normal web traffic (HTTPS)443Works
Git over HTTPS443Works
Hosting control panel (browser)443Works

Read that table and the solution designs itself: move the deployment onto port 443. Git speaks HTTPS natively, and every serious hosting provider can pull code from a Git repository. Instead of the AI pushing files into the server over SSH, the AI pushes them to GitHub the normal way — and the server pulls them down. The blocked direction is simply never used.

The deploy route, at a glanceMuseedits codeSSH / FTP✕ blockedGitHubHTTPS :443Server pullto stagingLive site ✓verifiedBlocked ports are never used — everything rides on HTTPS (443).

The solution: GitHub server-pull deployment

The setup has four pieces:

  1. A private GitHub repository that holds only deployment payloads: the changed files, a small installer script, and a manifest listing exactly which files may be installed.
  2. The host's Git integration, which clones and pulls that repository into a staging folder on the server — a new folder that sits next to your live folders, never on top of them.
  3. A tiny applier script, run by a cron job every 5 minutes. It reads the manifest, and for each listed file it checks the checksum (MD5) of the live file first. Only if the live file is exactly the version the change was based on does it install the new one — with a backup copy, an atomic swap, and correct permissions. If anything has drifted, it skips that file and reports it instead of forcing the change.
  4. A status file that the script writes after every run, published under a hard-to-guess name, so the AI can verify over HTTPS exactly what was installed — file by file, checksum by checksum — without ever logging into the server.

Why the staging folder and the applier, instead of pointing the host's Git feature straight at the live site folder? Because a plain Git deployment copies a whole branch into the target directory. That is too blunt for a live site: configuration files, uploads, caches and storage folders must never be touched by a deploy. The two-step design — Git delivers to staging, a guarded script installs only the listed files — gives you Git's transport with a careful human's caution.

Step-by-step: setting up the GitHub deploy route

Step 1 — Create a private repository

Create a new GitHub repository and set it to Private. This repository is plumbing, not your project's public source code, so keep it separate. Name it something obvious, like your-site-deploy.

Step 2 — Add the applier script and a manifest

In the repo, add:

  • An applier script (a small bash script is enough) that: reads a manifest file; for each entry, compares the live file's MD5 with the expected "base" MD5; on a match, backs up the live file, installs the new file atomically with 644 permissions, and records the new MD5; on a mismatch, skips it and logs why. After installing, it clears the application's view cache (for a Laravel site, artisan view:clear) and writes a JSON status report.
  • A manifest listing the payload files for the current deploy: target path, expected base MD5, new MD5. Nothing installs unless it is in the manifest — that allowlist is the core safety rule.
  • A .gitignore that hard-excludes secrets and environment files (.env, keys, credentials). Secrets never travel through this route, ever.

What the two files look like in practice — fill in your real paths and checksums:

# .gitignore — secrets never travel this route
.env
*.key
*.pem
credentials/
{
  "files": [
    {"path": "app/Http/Controllers/HomeController.php",
     "base_md5": "paste-the-live-file-md5-here",
     "new_md5": "paste-the-new-file-md5-here"}
  ]
}

Step 3 — Connect the repository in your hosting panel

Most hosts put Git deployment in the control panel. On Hostinger, for example, it is hPanel → Websites → your site → Dashboard → Advanced → Git → Connect with GitHub. Sign in to GitHub and, on the authorization screen, choose "Only select repositories" and select just the deploy repository. The host does not need access to your other repositories — never grant "all repositories" for a deployment integration.

Step 4 — Deploy into a staging folder, not the live site

Add the repository with your main branch and set the target directory to a new folder (for example deploy-stage) sitting alongside your live folders. Run the deployment once and confirm the staging folder now contains your payload: the applier script, the manifest and the payload files.

Step 5 — Add the cron job

In the same panel, open Cron Jobs and create a job that runs every 5 minutes (*/5 * * * *), executing the applier script from the staging folder. From now on, anything pushed to the repository is pulled to staging and installed by the script within about five minutes — no SSH session involved anywhere.

# Cron job — every 5 minutes, run the applier from the staging folder
*/5 * * * * bash /path/to/deploy-stage/apply.sh

Step 6 — Prove it with a harmless probe

Before trusting the route with real changes, push one throwaway payload: a tiny text file with a random name, listed in the manifest. Wait one cycle, then open the probe file's URL and the script's status JSON in a browser. If the probe is live and the status file shows it as installed with the right checksum, the pipeline is proven end to end.

Step 7 — Ship your real change

Now push the real payload: the changed files plus an updated manifest, deleting the probe in the same commit. Verify the live site the way you always should: check the status JSON checksums, open the changed pages, and keep an eye on them for a few minutes.

The safety rules that make this route trustworthy

  • Checksum guard: a file installs only if the live file still matches the base version the change was built on. Drift means skip-and-report, never force.
  • Backups on every install: the previous version of each file is kept, timestamped, so any deploy can be rolled back.
  • Atomic swaps: files are written to a temporary name and renamed into place, so visitors never see a half-written file.
  • Allowlist only: the manifest is the complete list of what may change in a deploy. The script cannot wander.
  • No database migrations through this route: it moves files, nothing else. Database changes stay a deliberate, separate act.
  • Private repo, least privilege: the hosting integration sees exactly one repository, and that repository contains no secrets.

Your AI assistant can set this up for you

You do not have to perform the steps above yourself — this is exactly the kind of multi-step setup an AI assistant like Muse is good at. Your part is genuinely small: connect the accounts once. Log in to your hosting panel when the assistant asks, sign in to GitHub, and approve a verification code if GitHub sends one. That is the entire human workload.

Everything else is the assistant's job: creating the private repository, writing the applier script and the manifest, connecting the repo in the hosting panel, creating the cron job, running the probe test, and verifying the first real deploy checksum-by-checksum against the live site. From that point on, deployments become simple pushes: the assistant changes the code, pushes, waits a few minutes, and proves the live site matches — a smooth workflow that never touches the blocked ports again.

One practical note: the saved logins the assistant uses have to be current. A stale hosting password is the one thing that can pause the setup, because only you can replace it — through the secure login prompt, never by pasting a password into a chat.

When this route is not the answer

  • Database changes: schema migrations should never ride an unattended file-deploy pipeline. Run them deliberately, with a backup, through whatever channel you trust.
  • Huge binary uploads: Git is the wrong truck for gigabytes of media. Use your host's file manager or the application's own uploaders.
  • Hosts without Git or cron: the pattern needs both features. Most mainstream shared and cloud hosts offer them; the cheapest legacy plans sometimes do not.

Frequently asked questions

Is the AI assistant itself blocking the SSH connection?

No. The assistant is willing to connect — the sandbox or network it runs inside only allows web-style (HTTPS) traffic out. SSH and FTP packets are dropped by that network layer before they ever reach your server, which is why the failure looks like total silence instead of an error message.

Will switching to PuTTY or another SSH client fix it?

No. The client is not the bottleneck; the port is. Any SSH client used from inside the same restricted environment hits the same silent drop. PuTTY from your own computer works because your network allows it — but then you are deploying manually.

Is SFTP a workaround?

No — SFTP rides on SSH, so it uses the same blocked channel. FTPS has the same problem on the FTP side. If the port is dropped, every protocol built on it is dropped.

Does this GitHub route work on shared hosting?

Yes — it is designed for exactly that environment. Mainstream shared hosts (Hostinger is one example) include both Git deployment in the control panel and cron jobs, which are the only two host features the pattern needs.

Is my code safe in the deploy repository?

The repository is private, the hosting integration is granted access to that one repository only, and secrets — environment files, keys, passwords — are excluded by design. The route carries code changes, never credentials.

How fast is a deploy through this route?

With the cron set to every 5 minutes, a pushed change is typically live within about 5–6 minutes: one Git pull plus one applier run. Slower than a direct SSH upload when SSH works — and infinitely faster than retrying a blocked connection forever.

The bottom line

When your AI assistant lives in an HTTPS-only world, do not fight the network — route around it. Git over HTTPS is a first-class deployment channel: versioned, auditable, and safe when you add a checksum-guarded installer and a staging step. The problem was never your server, your password, or your tools; it was a silent port block. This route turns deployment back into what it should be: a routine, verifiable push.

Want this deploy route set up on your site? Asad Webs builds fast, search-ready websites and web apps — and we can wire up Git-based deployment so your AI assistant ships safely: asadwebs.com/#contact.

Related reading: Gemini API CLI: the complete guide · How to speed up a WordPress website

Category: Web Development

Tags: Muse · GitHub · deployment · Hostinger · SSH

About Asad Webs

KEEP READING

Next guide

¿Cuánto cuesta una página web para una clínica estética en España en 2026? Reservas, tratamientos y RGPD →

Related articles

Join the conversation

No account needed. Comments appear only after approval. Your email address will not be published.

Be the first to share a useful question or thought.

You won’t be subscribed to any mailing list.
WELCOME BACK

Sign in

Access your orders, saved products and account.