iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Antihost offers Linux VPS plans with full root access, unlimited traffic on a 1 Gbps port and a 14-day free trial.
Use a bare Git repository as the central remote on a Linux VPS, keep every working tree outside that repository, and authenticate administrators or automation with verified SSH keys. For deployments, check out each pushed commit into a separate release directory, validate it, then switch the live symlink atomically. This layout keeps Git storage, deployable files, and the public web root independent, making rollback and recovery practical.
Choose the repository architecture first
A VPS can play two different roles: it can host your central Git remote, or it can receive code from a hosted source such as GitLab and deploy that code. Both designs work, but they assign collaboration, security, and recovery responsibilities differently.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →| # | Preview | Product | Price | |
|---|---|---|---|---|
| 1 |
|
Pro Git | Buy on Amazon | |
| 2 |
|
Pro Git (Expert's Voice in Software Development) | $37.07 | Buy on Amazon |
| 3 |
|
Professional Git | $24.79 | Buy on Amazon |
| 4 |
|
Pro Git 1st (first) edition Text Only | $83.26 | Buy on Amazon |
| 5 |
|
Git: Github Programming, In 8 Hours, For Beginners, Learn Coding Fast: Git Github Language, Crash... | $2.99 | Buy on Amazon |
| Decision area | Self-hosted bare remote | Hosted source with VPS deployment |
|---|---|---|
| Repository location | The canonical repository is stored on the VPS, for example /srv/git/project.git. |
The canonical repository remains with the hosted provider; the VPS keeps deployment clones or release checkouts. |
| Collaboration and review | You must provide your own access controls and any review workflow. | The provider supplies collaboration, review, and project administration features. |
| Operational burden | You maintain SSH access, repository permissions, hooks, monitoring, and backups. | You still maintain the VPS, but provider availability and credentials become dependencies. |
| Authentication scope | Developer keys authenticate directly to the VPS service account. | A project-scoped deploy key can give the VPS read-only access, with write permission only when required. |
| Recovery responsibility | You are responsible for backing up all Git objects, refs, hooks, and configuration. | You must protect deployment configuration and local releases, while the hosted provider generally remains the source repository. |
| Deployment audit trail | Pushes and hook logs are yours to record and retain. | Repository events are recorded by the provider, while VPS-side deployment logs remain your responsibility. |
The rest of this guide shows both patterns, then applies the same safe deployment model to either one.
Why the central remote should be bare
A bare repository contains Git’s object database, refs, and configuration but has no checked-out working tree. That makes it suitable as a shared remote: pushes update refs without competing with files that someone may be editing or serving. A normal clone, by contrast, has a working tree and is intended for inspecting, changing, testing, or deploying files.
#1 Best Overall
Create the bare repository outside the public web root. The repository directory is storage for Git, not a document root and not a place from which a web server should serve application files. A separate clone or release checkout can be used to build and deploy a particular commit.
Never make the bare repository itself the live site. A web server pointed at its internal directories could expose source, configuration, or Git metadata, and a deployment that modifies a live working tree can leave a half-updated application visible to users.
Recommended Free Tools
Prepare the Linux VPS
Install and record the required packages
Install the Git and OpenSSH packages supplied by your Linux distribution. Record the installed versions and the distribution release in your operations notes. Repeating a deployment or rebuilding a replacement VPS is easier when the toolchain is known rather than assumed.
Create a dedicated service account
Create a git service account for a self-hosted remote. It should own the repository and have only the directory permissions needed for Git operations. Disable interactive login for this account unless a specific administrative procedure requires it; developers should authenticate to the account only to invoke Git’s server-side commands.
Keep repository storage, release directories, logs, and the live web root separate. For example:
/srv/git/project.git— the bare central repository./srv/releases/project-<commit>— immutable or disposable release checkouts./srv/www/project-current— a symlink to the active release./var/log/project-deploy/— deployment and hook logs, protected from public access.
Restrict the network surface
Allow SSH only as required by your firewall and network policy. If the VPS also serves HTTP or HTTPS, those web services should not grant access to /srv/git. File ownership and mode bits are a second line of defense, not a substitute for network and web-server restrictions.
Set up SSH authentication correctly
SSH uses two keys: a public key and a private key. The private key stays on the developer or automation host and must never be copied into the repository, committed to source control, or placed in shell history. Install only the corresponding public key in the authorized account on the VPS.
Create a key pair on the client or CI host
When supported by the clients you operate, prefer an ED25519 key. Protect it with a passphrase for interactive use, or store it in a restricted secret-management system for automation. An SSH agent can hold an unlocked key during a controlled session so scripts do not need to expose the passphrase.
Rank #2
Verify the VPS host key before using it
Before the first push or clone, verify the VPS host-key fingerprint through a trusted, separate channel. Add the verified key to the client’s known-hosts database. Production automation should use a pinned host-key process rather than accepting an unknown key automatically. This prevents an operator from confusing a changed or intercepted host with the intended VPS.
Limit what an authorized key can do
For a self-hosted remote, the key used by a developer should be authorized only for the intended Git account and repository permissions. For automated deployment, use a separate key from human keys and grant the smallest possible scope. Review and revoke keys when people, systems, or projects change.
Build a self-hosted bare remote
Initialize the repository on the VPS
After creating the service account and parent directory, initialize the bare repository as that account:
sudo install -d -o git -g git -m 0750 /srv/git/project.git
sudo -u git git init --bare /srv/git/project.git
The exact account name, group, path, and permissions depend on your distribution and access model. Check that the service account can read and write the repository while unrelated users cannot.
Add the remote on a development machine
From an existing local clone, add the VPS as origin and push the branch you intend to publish:
git remote add origin git@vps.example:/srv/git/project.git
git push -u origin main
Replace the hostname, path, and branch with your values. Confirm the remote before pushing:
git remote -v
git branch --show-current
git ls-remote origin
The last command should show the refs that exist on the VPS. If the project uses another default branch, configure and document that branch rather than assuming main.
Test from a clean clone
Clone the repository into a temporary directory with the same kind of SSH identity used by a developer or build host. Check out the expected branch and inspect the files. This catches incorrect ownership, an incorrect repository path, missing authorized keys, and a default-branch mismatch before deployment automation is added.
Rank #3
Use a hosted source with a VPS deploy key
If the source of truth is GitLab, the VPS normally pulls rather than receives developer pushes. Create a project deploy key on the VPS and prefer read-only access for this purpose. Deploy keys are intended for non-human interaction with a project; grant write access only if the VPS genuinely must push tags, commits, or other refs.
Keep the deployment identity separate
Generate a key dedicated to this project and deployment purpose. Do not reuse a personal key or a key shared by unrelated applications. Store the private half with restrictive permissions and make the corresponding public key visible only in the project’s deploy-key configuration.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Clone into a release location
A first checkout can use a path such as:
git clone git@gitlab.example:group/project.git /srv/releases/project-<commit>
The angle-bracket text denotes the commit-specific directory name; replace it with an actual commit identifier in your script. Pin the checkout to the exact commit or tag that passed your checks instead of silently deploying whichever branch happens to move next.
For subsequent releases, fetch the required ref into a temporary directory, check out the target commit, run validation, and only then make it live. A failed fetch or checkout must leave the current release untouched.
Design a safe push-to-deploy flow
A Git hook is a program triggered by a Git event. The hook should not turn the repository directory into the web root. Its job is to coordinate a controlled release process.
Place and enable the hook
For a self-hosted bare repository, a server-side receive hook can react after a push is accepted. GitLab’s server-hook documentation likewise requires hook files to be executable and placed in the configured hook directory; the event triggers the hook. Apply the same operational discipline to either environment: explicit ownership, executable mode, a known interpreter, and a protected directory.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchValidate the event and input
- Accept only the expected repository and branch or ref.
- Use the commit ID supplied by Git, not an untrusted filename or commit message, to identify the release.
- Quote shell variables and avoid evaluating commit messages, paths, or ref names as shell code.
- Use absolute paths for Git, service-manager, and application commands so the hook does not depend on an interactive shell’s environment.
- Record the commit ID, start time, result, and error output in a protected log.
Build each release separately
Create a new release directory for the target commit. Check out or export the commit there, install dependencies using the application’s locked files, and run syntax, migration, asset, or health checks appropriate to the application. Do not delete the current release when any preparation step fails.
Switch the live version atomically
After validation succeeds, update a symlink such as /srv/www/project-current to point to the new release. A rename of a prepared symlink is atomic on the same filesystem, so readers see either the old complete release or the new complete release rather than a directory being filled file by file. Reload or restart the service only when the application requires it, and make that action explicit in the hook.
Keep rollback available
Retain at least one previous known-good release. If health checks or monitoring detect a failure, point the live symlink back to that release and reload the service. The rollback procedure should be documented and executable independently of the failed hook.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Example deployment sequence
- Receive or select a commit. A push to the self-hosted remote, or a controlled pull from the hosted source, identifies one immutable commit.
- Create a temporary release path. Use a unique directory under the releases parent and ensure the deployment user owns it.
- Fetch and check out exactly that commit. Avoid deploying an implicitly changing branch tip.
- Install and validate. Use locked dependency versions, compile assets if needed, run tests and configuration checks, and verify required environment settings without printing secrets.
- Run an application health check. Test locally or against a private listener before exposing the release publicly.
- Switch the symlink. Replace the current-link atomically only after every check passes.
- Reload the service and verify. Check service status, logs, and an application endpoint appropriate to your system.
- Record the outcome. Log the commit, release path, operator or automation identity, checks, and exit status.
- Clean up safely. Remove old releases only after the retention rule preserves the rollback versions you require.
Permissions and least privilege
The account that accepts Git pushes does not automatically need permission to modify every application file or restart every service. Separate responsibilities where practical:
- Let the
gitaccount own the bare repository and receive Git traffic. - Let a deployment account own release directories and perform checkouts and validations.
- Grant only a narrowly defined service reload permission if a restart is required.
- Keep environment files and deployment secrets outside the repository, readable only by the service that needs them.
- Ensure the web-server account can read the active release but cannot rewrite the repository or deployment scripts.
If a hook must cross account boundaries, use a tightly constrained service-manager rule or wrapper command. Do not give the hook unrestricted administrative access merely to avoid diagnosing one permission error.
Backups and restoration
A repository backup is more than a copy of a working directory. For a self-hosted remote, preserve Git objects, refs, repository configuration, server hooks, service files, deployment scripts, and the metadata needed to recover keys and secrets. Also include the release and web-server configuration that determines how a commit becomes live.
Store backups off the VPS
Keep backup copies on storage independent of the VPS. A disk snapshot on the same machine does not protect against deletion, filesystem corruption, or loss of the host. Protect backup access as carefully as production access.
Define a recovery objective
Choose how much recent history and deployment configuration you can afford to lose and how quickly service must return. The retention schedule is an operator decision; document it rather than assuming that one recent archive is sufficient.
Perform a restore drill
Test restoration on a separate path or replacement host. Verify that the restored repository can be cloned, refs are present, hooks have the expected permissions, deployment scripts can create a release, and the service can be pointed to the restored files. A backup is not usable until this process succeeds.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting common failures
“Permission denied (publickey)”
Confirm that the client is using the intended private key, the matching public key is installed for the correct account, and the VPS account can read its authorized-keys file. Check host-key verification separately; a trusted host key does not authenticate a user. For automation, inspect the job’s SSH configuration rather than assuming it inherits your interactive agent.
Best Value
“Repository not found” or a path error
Inspect git remote -v and compare the SSH path with the actual bare repository location. On a self-hosted server, the path is interpreted by the SSH account, so ownership and parent-directory traversal permissions matter. Test a clean clone using the same account and key.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsThe hook never runs
Check that the hook is in the repository’s configured hooks directory, has executable permissions, uses a valid interpreter, and is triggered by the event you expect. Read the protected hook log and capture standard error. A hook that exits early without logging is difficult to operate.
The site shows a partial deployment
This usually means the web root points directly at a directory being modified. Move checkouts to a new release directory, validate them there, and switch a symlink only after completion. Keep the previous release until the new one has passed health checks.
A failed deployment removed the working version
Change the hook so cleanup happens only after a new release is live and verified. Restore the previous release by repointing the live symlink, then inspect the failed release and logs before retrying.
Operational checklist
- Use a bare repository for a central self-hosted remote.
- Keep bare storage, release checkouts, logs, and the public web root in separate paths.
- Create a dedicated service account and disable unnecessary interactive login.
- Prefer ED25519 SSH keys where supported; protect private keys and install only public keys remotely.
- Verify and pin the VPS host key before unattended operations.
- Use a read-only, project-scoped deploy key for pull-only hosted-source deployments.
- Validate hook refs and inputs; never execute untrusted names or messages as shell code.
- Deploy immutable commit-specific releases and switch the live symlink atomically.
- Keep at least one previous release and monitor hook exit status.
- Back up repository objects, refs, hooks, service files, and deployment metadata off-host.
- Prove the backup with a restoration drill against your stated recovery objective.
Frequently Asked Questions
Can I use a normal clone as the central repository on the VPS?
Use a bare repository for the central remote. A normal clone has a working tree and is better suited to inspection, testing, or deployment; keeping it as the shared push target can create conflicts with checked-out files.
Free tools Windows power users keep installed
One-click scans. No signup required.
Should a VPS deploy key have write access?
No, not for a pull-only deployment. Make the project-scoped deploy key read-only and grant write permission only when the VPS must intentionally push changes.
Where should the live website point?
Point it at a separate release directory, commonly through a symlink such as /srv/www/project-current. Do not point the web server at the bare repository.
How do I make a Git hook safe for production?
Make it executable and place it in the configured hook directory, validate the expected ref, use the exact commit ID, quote inputs, run with least privilege, log failures, and switch releases only after checks pass.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

