Guide
How to deploy a website to shared hosting with SSH and Git
To deploy a website to shared hosting, add an SSH public key to your hosting account, build the site on your own computer, then copy the built folder to your site's web folder with rsync over SSH, a Git pull on the server, or a GitHub Actions workflow. Static sites, including Astro, work well because the host only has to serve ready-made files. Rsync is the simplest method and the one to start with.
The route
From your code to a live site in five steps
- BuildMake the finished files, for Astro the dist folder
- KeyCreate an SSH key and add the public half to your account
- TestLog in once to prove the key works
- UploadCopy files with rsync, Git or an automated workflow
- CheckOpen the live site and keep a way back
What you will use
The tools in this guide
Astro
Builds your project into a dist folder of static files, which is what you upload.
npm
Installs the project and runs the build command on your computer.
Git
Tracks your changes so every deploy matches a known version and can be rolled back.
GitHub
Stores the repository and holds your deploy secrets for automated workflows.
GitHub Actions
Builds and deploys for you each time you push to your main branch.
Claude Code
Can write the deploy script and workflow for you. You read it before it runs.
Choosing a method
Three ways to deploy: rsync, Git and GitHub Actions
| Method | How it works | Best for | Watch out for |
|---|---|---|---|
| Rsync over SSH | You build locally, then one command copies only the changed files to the server | Solo owners and small sites, the best place to start | You must remember to build first and run the command yourself |
| Git pull on the server | The server holds a copy of your repository and you pull new commits into it | Sites with no build step, such as plain HTML, or when you want the server to hold history | Build tools may not be on the server, so built files often need to be committed |
| GitHub Actions | A push to GitHub starts a workflow that builds the site and uploads it for you | Teams, frequent updates and anyone who wants deploys to happen automatically | You must store the private key as a secret and keep the workflow tidy |
All three use SSH underneath. Pick one, get it working, and only then consider adding another.
Step 1
Create an SSH key pair
An SSH key is a pair of files. The private key stays on your computer and is never shared. The public key is a harmless line of text that you give to the server. When you connect, the server checks that you hold the matching private key, so no password is sent. This is safer than a password because there is nothing to guess and nothing to leak from the server.
Open a terminal on your computer and run this command. Ed25519 is a modern, small and fast key type.
ssh-keygen -t ed25519 -C "deploy-mysite" -f ~/.ssh/id_ed25519_mysiteAdd a passphrase if the key will live on your own laptop. A key used only by an automated workflow has no passphrase, which is one reason that key must be used for that job only.
You now have two files. The one ending in .pub is the public key. Print it and copy the single line it shows.
cat ~/.ssh/id_ed25519_mysite.pubtype $env:USERPROFILE\.ssh\id_ed25519_mysite.pubNever share the file without the .pub ending. That is the private key.
Steps 2 to 4
Add the key, test the login and find your web folder
Add the public key to your hosting account
Sign in to the control panel for your hosting account and look for SSH key management. Paste the public key line and save it. If you cannot see where, ask our live chat or search the knowledge base, because the exact screen can change.
Collect your connection details
You need the server name, your account username and the SSH port. They are shown in your client area and welcome email. Do not guess the port. Use the one shown for your account.
Test the login
Use the command in the box just below this list, with your own details in place of the capitals. The first time you are asked to trust the server's fingerprint. Accept it, and you should reach a command prompt with no password request.
Find the web folder for your domain
Run ls and look for the folder that holds your site, often public_html or a similar name. Addon domains and subdomains each have their own folder, so check the document root shown for that domain in the control panel and use exactly that.
Log out and note the full path
Type exit. Keep the full path to the web folder somewhere safe. You will paste it into the deploy command next.
Steps 3 and 4
The login and folder commands
ssh -i ~/.ssh/id_ed25519_mysite -p PORT USERNAME@SERVERls
exitLook for the folder that holds your site, often public_html or a similar name, and note its full path.
Step 5
Deploy an Astro site with rsync
Build the site first. In an Astro project this writes the finished site into a folder called dist. Open that folder and check it holds an index.html and your assets before you copy anything.
npm run buildThen copy it. Replace the capitals with your own details, and run it with --dry-run first, which shows what would change without changing anything.
rsync -avz --delete --dry-run \
-e "ssh -i ~/.ssh/id_ed25519_mysite -p PORT" \
dist/ USERNAME@SERVER:/full/path/to/public_html/Read the list it prints. If it wants to delete something you did not expect, such as an uploads folder or a file you added through the control panel, stop and work out why. When the list looks right, run the same command again without --dry-run.
rsync -avz --delete \
-e "ssh -i ~/.ssh/id_ed25519_mysite -p PORT" \
dist/ USERNAME@SERVER:/full/path/to/public_html/What each part of the command does:
-a- Keeps file details such as dates and permissions
-v- Lists each file as it is sent
-z- Compresses the transfer
--delete- Removes files on the server that are no longer in your build, so the live site matches your project. Tidy, but the option that can hurt, which is why the dry run comes first
-e "ssh ..."- Tells rsync which key and port to use
dist/- The trailing slash means "the contents of dist". Without it the folder itself is copied into the target
Rsync only sends what changed, so later deploys of a small site take seconds. Afterwards, open your domain in a private browser window and check the page you changed.
Before the first deploy
A short pre-flight list
- The build finished with no errors
- dist contains index.html
- You ran the command with --dry-run first
- The target path is the right domain folder
- A backup of the current site exists
- The dist/ trailing slash is present
- Your .htaccess file is in the project, if the site needs one
- You know how to roll back
Make it repeatable
Put the deploy in a script
Typing a long command is how mistakes happen. Save it as a small script in your project that stops if anything fails, builds the site, then runs rsync. The line set -e makes it stop at the first error, so a failed build can never be uploaded.
#!/usr/bin/env bash
set -e
SERVER="SERVER"
USER="USERNAME"
PORT="PORT"
TARGET="/full/path/to/public_html/"
KEY="$HOME/.ssh/id_ed25519_mysite"
npm run build
rsync -avz --delete -e "ssh -i $KEY -p $PORT" dist/ "$USER@$SERVER:$TARGET"Keeping the details in variables at the top means changing hosting later is a four-line edit. Never put a password or a private key in the script. It should only name the key file on your own computer.
Because a script is plain text, it suits an AI assistant well. Ask Claude Code to write it, then read every line yourself, as described in the section on using Claude Code below.
Method 2
Deploy with Git on the server
With this method the server keeps a copy of your repository. You push changes to a Git host such as GitHub, log in over SSH and run git pull in the site folder, and the live files update. It is a good fit for sites with no build step, such as hand-written HTML, because the files in the repository are the files that get served.
The catch is the build. Many modern projects, including Astro, need a build step that produces the final files. Build tools are not guaranteed to be installed on shared hosting, and building on the server uses its resources. The usual answer is to build on your own computer and either commit the built files to a separate branch or use rsync instead. If you want to build on the server, ask our live chat what is available for your plan first.
Whichever way you set it up, make sure the repository's own hidden folder, .git, cannot be downloaded by visitors. If the site folder is a Git checkout, ask live chat how to block that folder, or keep the checkout outside the public folder and copy only the built files into it.
Method 3
Deploy automatically with GitHub Actions
Create a key just for the workflow
Make a new ed25519 key with no passphrase, used for deploying only. Add its public half to your hosting account as described above. Do not reuse your personal key.
Store the private key as a secret
In your GitHub repository, open Settings, then Secrets and variables, and add the private key as a secret named something like DEPLOY_KEY. Add the server, user, port and path as further secrets or variables. They are never written in the workflow file.
Write the workflow
Create a file in .github/workflows that runs when you push to your main branch. It checks out the code, sets up Node.js, runs npm ci and npm run build, writes the key to a temporary file with strict permissions, then runs the same rsync command you tested by hand.
Pin down the server fingerprint
Add the server's host key to the workflow's known hosts so the connection is checked, instead of switching host checking off. Switching it off is a common shortcut and it removes a protection.
Watch the first run
Push a small change and watch the workflow in the Actions tab. Read the logs, then confirm the live site changed. Fix problems here before you rely on it.
Using an AI assistant
Using Claude Code to write your deploy setup
Claude Code is well suited to this job, because a deploy script and a workflow file are short, structured and easy to check. Give it the facts it cannot know: the build command, the output folder, the server name, your username, the port and the target folder. Ask for a script with a dry-run option and a clear message at each stage.
Then review what it writes. Check that the destination path is exactly your domain folder, that the source ends in a slash, and that --delete points at the folder you meant and nothing higher up. Check that no password or key appears in any file that will be committed. If you do not understand a line, ask it to explain, and test with --dry-run before the first real run.
Most important of all, never paste your private key into a chat with any AI tool, and never commit it to a repository. The assistant needs only the public key and the connection details. If a private key is ever pasted or committed by mistake, treat it as exposed: remove it from your hosting account and create a new pair.
Read more in how to build a website with Claude and which stack to ask Claude for.
Roll back
Keep a way back before you deploy
Before you deploy
- Download or copy the current live files
- Take a backup in the control panel
- Keep the previous build folder on your computer
- Commit your work to Git so each deploy matches a version
- Run a dry run and read it
If it goes wrong
- Rebuild or check out the previous version
- Run the same deploy command again
- Restore from your own copy first, since it is the freshest
- Use our weekly remote backups, kept for about a month, as a second line
- Ask live chat if you are unsure which files to restore
Fixing problems
Common deploy errors and what they mean
Permission denied (publickey)
The server did not accept your key. Check you added the public key, the right username, the right port, and that the command names the correct private key file.
The site shows the old version
You may have uploaded to the wrong folder, or a cache is serving the old page. Check the target path, then do a hard refresh.
A page or the whole site returns an error
A needed .htaccess file may be missing after --delete removed it. Keep it inside your project so it ships every time.
Files end up in a nested folder
Almost always a missing trailing slash on dist/. Without it, rsync copies the folder itself into the target.
Bad file permissions
Files uploaded with unusual permissions may not be readable. Do not open them to everyone. Ask live chat for the right setting.
Still stuck
Send live chat the exact error text, the command you ran with secrets removed, and your domain.
Security
Keeping SSH deploys safe
- Use keys, not passwords, for deploys
- Use one key per job or per person
- Never paste a private key into any chat or email
- Never commit a private key to Git
- Use a deploy-only key for automated workflows
- Remove keys you no longer use from the account
- Keep known hosts checking switched on
- Keep a backup before every important deploy
Good to know
What deploys do not cover
A deploy replaces your site's files. It does not move a database, set up email, or change DNS. If your project uses a database, move and import that separately, and keep the connection details out of Git. If you are switching from another host, our guide to moving a website covers the order of work, and free migration is included on the Small plan and above on yearly billing.
If you prefer clicking to commands, the same files can be uploaded with a desktop program. See what is SFTP. SFTP is a good fallback when you want to check one file by hand, but it does not give you a repeatable deploy.
FAQ
Common questions
Can I deploy an Astro site to shared hosting?
Yes. Astro builds a folder of static files, and shared hosting is well suited to serving static files. Build locally, then copy the dist folder to your site folder with rsync, SFTP or a GitHub Actions workflow.
Is SSH available on shared hosting?
On our shared plans SSH and Git are supported. Add your public key in the control panel, and ask live chat if you cannot find where.
Should I use rsync, Git or GitHub Actions?
Start with rsync, because it is the simplest and easiest to check. Move to GitHub Actions when you update often or work in a team. Use Git on the server mainly for sites with no build step.
Is it safe to let an AI assistant write my deploy script?
It is safe if you read the script, test it with a dry run and never share your private key. Give the assistant only the public key and connection details, and check the destination path carefully.
How do I undo a bad deploy?
Rebuild the previous version and run the same deploy command again. Keep a copy of the working site before each deploy. Our weekly remote backups are a second line of defence, not the first.
Keep reading
Related pages
Host your Astro or static site in the UK
SSH and Git supported, free SSL, UK servers and live chat open 24/7, from 84p a month (£10.03 billed yearly).