Blog · WebJi® India

How to Deploy a Website with Git

Quick answer: To deploy a website with Git, push the commit that should be live. Static HTML can publish from a GitHub Pages branch. A site that needs PHP, a database, or your server uses a bare repository and a post-receive hook, or a GitHub Actions job that copies the build into public_html.
✓ In business since 2005✓ INR + GST billing✓ 24/7 Email Support — avg reply < 60 min
Young Indian gamer with a headset at an RGB-lit gaming PC in a dark room — how to deploy website with git

Git deploy versus FTP for a website

Git publishes one named commit. FTP uploads whichever files you drag across, and it keeps no record of what the server held before that upload.

An FTP site can mix yesterday's stylesheet with today's HTML, and you cannot name that mix. Git can check the previous commit out again, so the live files return to a state you already ran.

MethodUse it whenYou know it worked when
GitHub PagesStatic HTML, CSS and images in a repositoryThe Pages URL serves the index file from that branch
Post-receive hookPHP or other files served from your own server over SSHThe hook checks the commit out and the live URL matches it
GitHub ActionsA project that must be built before anything is uploadedThe workflow is green and public_html holds only the build output

Pick the row from what the site needs to run. Plain HTML can use the first row. PHP, a database, or a repository that must stay private belongs on a server you control.

How to deploy a static website with GitHub Pages

GitHub Pages serves the files in a repository as a static website. It does not run PHP, Python or Ruby. On the free GitHub plan this works for a public repository. A private repository needs a paid GitHub plan before Pages will publish it.

  1. Create the repository. A user site must be named username.github.io, in lowercase. A project site can use any name.
  2. Add an entry file at the top of the folder you will publish: index.html, index.md or README.md. Without one, Pages has nothing to serve.
  3. Open the repository Settings, then Pages, and choose the branch and folder that hold that file.
  4. Push the commit. Open the site URL. Allow up to 10 minutes the first time.

A user site is served at https://username.github.io/. A project site is served at https://username.github.io/repository-name/. Later changes go live the same way: commit, push, then refresh.

If the URL is still a 404 after those 10 minutes, the entry file is not at the top of the branch and folder you selected. Pages will not run a server-side app to fill that gap.

How a post-receive hook deploys a website with Git

A post-receive hook is a script on the server that Git runs after it accepts a push. The script checks the new commit out into the folder the web server reads.

You need SSH as a user who can write that folder. On a WebJi® account that is VPS hosting, not a feature to assume on every shared plan. If the account has no SSH, use the contact form and name the plan before you write a hook.

  1. On the server, outside the web root, run git init --bare /home/USER/repo.git.
  2. Create hooks/post-receive, run chmod +x on it, and have it execute git --work-tree=/home/USER/public_html --git-dir=/home/USER/repo.git checkout -f.
  3. On your computer, run git remote add deploy user@server:/home/USER/repo.git, then git push deploy main.
Young Indian gamer with a headset at an RGB-lit gaming PC in a dark room — how to deploy website with git

You know it worked when the push prints the checkout and a file that exists only in that commit is what the live URL serves. If the push succeeds and the site stays old, the hook is not executable or the work-tree path is wrong.

How GitHub Actions deploys a built website

Use GitHub Actions when the browser should not receive your source. A Vite or similar project has to be built first. The job can build it and copy only the output.

  1. Store the server host, the SSH user and a private key that user accepts as repository secrets.
  2. On a push to main, install dependencies and run the build so a folder such as dist or build exists.
  3. Copy only that folder to the server, for example rsync -az --delete dist/ user@server:/home/USER/public_html/.
  4. Stop when the job is green and the live URL shows a string that exists only in that build.

Do not copy the whole repository. node_modules and the source tree are not the website. A red job has published nothing. Read the log before you push again.

Where the built website files go in public_html

public_html is the document root on a cPanel account, at /home/USER/public_html. On a server without cPanel the same role is often /var/www/html. The home URL maps to the index file in that folder.

A static site with no build can be checked out straight into that folder. A built site must land there only after the build: the index.html inside dist, not the project root.

The deploy user has to own the directory, or the web server will not serve the new files. On cPanel the account user already owns public_html. A Linux VPS is where you create that user yourself. Directories should be 755 and files 644, all owned by the same user. A hook that runs as root leaves files the next deploy cannot replace.

Why git clone or git push says permission denied

Permission denied names one layer. It is not a sign that Git itself is broken. Read the words in brackets before you change the hook.

  • git clone or git push says permission denied (publickey). The key from that machine is not trusted by the remote. To clone a private GitHub repository onto the server, add the server user's public key as a deploy key. To push to your own server, put your laptop's public key in that user's authorized_keys, then test with ssh.
  • The hook runs and the files do not change. hooks/post-receive is missing chmod +x, or the work-tree path is relative and lands somewhere else. Use an absolute path.
  • rsync or Actions cannot write public_html. The SSH user does not own the directory. chown that path to the deploy user, or deploy as the cPanel user who already owns /home/USER/public_html.
  • The hook runs as root. Root-owned files block the web user on the next deploy. Keep one deploy user, directories 755 and files 644.

What to put in gitignore before you deploy

gitignore lists files Git must not store. A deploy that contains secrets or dependency folders will publish them, or it will bloat every push.

  • .env and password files. A database password or an API key does not belong in the repository that the server checks out.
  • node_modules and vendor. Install those on the machine that builds. Do not commit them.
  • Operating-system junk. .DS_Store and editor folders are not part of the site.
  • Do not ignore the live files. If the hook checks the repository out as the site, ignoring index.html means the site will not have it.

If Actions builds the site, ignore the dist folder and let the job upload it. If the hook checks the repository out as the live site, the HTML has to be in the commit.

How to roll a Git website deploy back

Rollback is why Git beats FTP for a site you will change again. The old files are still a commit. Tag that commit stable while it is the one you trust.

On the hook path, SSH in and check the previous hash out: git --work-tree=/home/USER/public_html --git-dir=/home/USER/repo.git checkout -f OLDHASH. From your computer you can also git revert the bad commit and push, so the hook runs the same way it does for a normal release.

On the Actions path, re-run the workflow from the older commit. If you deploy into timestamped folders and flip a symlink, point the symlink back. You know it worked when the live page matches the file from that older commit, not the one you just removed.

Frequently Asked Questions

How do I deploy a website using Git?

Push the commit that should be live. For static HTML, publish a GitHub Pages branch that contains index.html. For a site on your own server, push to a bare repository whose post-receive hook checks that commit out into public_html, or let GitHub Actions copy the built folder there.

Can I host a website on GitHub?

Yes, when the site is static. GitHub Pages serves HTML, CSS, JavaScript and images from a repository. It does not run PHP or a database. A public repository on the free plan can publish; a private repository needs a paid GitHub plan.

How do I deploy an HTML website to GitHub?

Put index.html at the top of the branch you will publish, push the repository, then in Settings open Pages and select that branch. A user site is served at https://username.github.io/ and a project site at https://username.github.io/repository-name/. Allow up to 10 minutes the first time.

What is a Git post-receive hook?

It is an executable script at hooks/post-receive inside a bare repository on your server. Git runs it after a push is accepted. A website hook uses that moment to check the new commit out into public_html, which is the folder the web server reads.

How do I auto-deploy from GitHub to my own server?

Add a GitHub Actions workflow on push to main. It builds the site if a build is required, then copies only that output over SSH into public_html. Keep the host, the SSH user and the private key in repository secrets. The live site changes when the job is green.

Why does git clone say permission denied on my server?

permission denied (publickey) means the key from that machine is not trusted by the remote. To clone a private GitHub repo onto the server, add the server user's public key as a deploy key. To push to your server, put your laptop key in that user's authorized_keys and test with ssh first.

Is deploying with Git better than FTP?

For a site you will change again, yes. Git can restore the previous commit by name. FTP cannot, because it never stored which set of files was live. A one-off upload you will not undo can still go by FTP.

Need help with this?

WebJi® support does it for you — free. Talk to our Jaipur team →