Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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

A bare Git repository and a post-receive hook can turn git push into a production deployment for a Hugo site. The hook checks out the pushed revision into a private workspace, runs Hugo with the production environment and destination cleanup enabled, and publishes the generated files in a directory served by Nginx. Keeping the repository, build workspace, and web root separate gives you a small, auditable deployment pipeline without a managed CI service.

What the deployment pipeline does

Hugo does not serve your source repository in production. It converts Markdown, templates, assets, data, and configuration into a static tree, normally named public. Nginx serves that generated tree. Git supplies the versioned source and provides the trigger.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Component Example location Purpose
Deployment account deploy Owns the repository, hook, checkout, and build process; it is not a general-purpose login.
Bare repository /srv/git/site.git Receives pushes and has no working tree.
Build workspace /srv/build/site Contains the checked-out Hugo source used by the hook.
Generated document root /var/www/site/public Contains only Hugo’s output and is the Nginx root.
Nginx Server block for your hostname Serves HTML, assets, feeds, and the sitemap from the generated directory.

The developer adds the bare repository as a Git remote and pushes the production branch. Git invokes hooks/post-receive, which receives one line per updated ref on standard input. The hook should act only when that ref is your production branch, such as refs/heads/main.

Prerequisites and decisions

VPS and operating-system access

You need an Ubuntu or another Linux VPS with administrative access, a DNS name pointed at it, and Nginx installed or ready to install. The commands below use sudo and conventional Linux paths; adjust them for your distribution.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application:Upgraded attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Warranty & Support: Our Electric air duster comes with 5 years warranty and 24/7 customer service. During this period, if you have any questions,pls kindly feel free to contact us.

Choose the correct Hugo edition

Hugo publishes standard, deploy, extended, and extended/deploy Linux editions. Use the smallest edition that supports your site:

Site requirement Edition capability
Markdown, templates, and ordinary assets Standard edition is sufficient unless a module or asset requires more.
Sass or SCSS processing Extended capability is required.
Hugo’s direct object-storage deployment command Deploy capability is required.
Sass plus direct object-storage deployment Extended/deploy edition covers both capabilities.

A Git-hook deployment to a VPS does not, by itself, require the deploy edition. Install an extended build only when the site’s modules or Sass pipeline need it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decide how the production branch is controlled

The examples use main. If your release branch has another name, change it consistently in the remote, hook, and any branch-protection process. A hook that silently builds every pushed branch can publish unfinished work, so it should fail closed by ignoring non-production refs.

Create the deployment account and directories

Use a dedicated account rather than running the hook as root or as the Nginx worker. The account needs to read the bare repository, write the build workspace, execute Hugo, and publish output, but it should not be an unrestricted administrator.

  1. Create the account and its SSH directory:

    sudo adduser --disabled-password --gecos "" deploy
    sudo install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
  2. Create separate repository, workspace, and web directories:

    sudo install -d -o deploy -g deploy /srv/git
    sudo install -d -o deploy -g deploy /srv/build/site
    sudo install -d -o deploy -g www-data /var/www/site/public
  3. Install Git and Hugo using your distribution’s package process or Hugo’s Linux release. Verify the binary that the hook will call:

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
    command -v git
    /usr/local/bin/hugo version

Hooks run with a restricted environment and may have a different PATH from your interactive shell. Use an absolute Hugo path such as /usr/local/bin/hugo in the hook, and make sure the deploy account can execute it.

Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Initialize the bare Git repository

Run the repository setup as the deployment account. A bare repository has Git objects and refs but no checked-out files, which is why it is appropriate as an SSH push target.

sudo -u deploy git init --bare /srv/git/site.git

The hook belongs in /srv/git/site.git/hooks/post-receive. Do not put the repository itself below /var/www; exposing Git objects or hook files through a web server is an avoidable security mistake.

From your development checkout, add the remote and push the production branch:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
git remote add production deploy@your-vps.example:/srv/git/site.git
git push production main

The first push creates the remote branch. Until the hook exists, it only stores Git objects; it does not build or publish the site.

Build and publish with a post-receive hook

Baseline hook

Create the hook as the deploy user and mark it executable. This version checks the ref, forcibly checks out the received branch into the private workspace, runs Hugo, removes stale destination files, and records ownership for Nginx:

sudo -u deploy sh -c 'cat > /srv/git/site.git/hooks/post-receive' <<'HOOK'
#!/bin/sh
set -eu

REPO=/srv/git/site.git
WORK=/srv/build/site
DEST=/var/www/site/public
BRANCH=refs/heads/main
HUGO=/usr/local/bin/hugo

while read -r oldrev newrev refname; do
  [ "$refname" = "$BRANCH" ] || continue

  git --work-tree="$WORK" --git-dir="$REPO" checkout -f main
  "$HUGO" 
    --source "$WORK" 
    --destination "$DEST" 
    --cleanDestinationDir 
    --environment production

  chown -R www-data:www-data "$DEST"
done
HOOK
sudo chmod 750 /srv/git/site.git/hooks/post-receive
sudo chown deploy:deploy /srv/git/site.git/hooks/post-receive'

The received revision variables are available for logging or more advanced release handling. The baseline uses main deliberately after confirming the ref, so a push to another branch cannot replace the production workspace.

Why destination cleanup is mandatory

Hugo can leave files from an earlier build when a page is renamed, deleted, changed to a draft, expired, or assigned a future publication date. --cleanDestinationDir removes files that are no longer produced. You can set the equivalent cleanDestinationDir configuration value, but an explicit production flag makes the behavior visible in the hook.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.

Keep failed builds from replacing good output

Hugo should complete successfully before you alter the live directory. The baseline command writes directly to DEST; a more defensive arrangement builds in a temporary directory and copies only after a successful exit:

TMP=$(mktemp -d /srv/build/.hugo-build.XXXXXX)
trap 'rm -rf "$TMP"' EXIT
"$HUGO" --source "$WORK" --destination "$TMP" 
  --cleanDestinationDir --environment production
rsync -a --delete "$TMP"/ "$DEST"/

Place these lines in the hook in place of the direct Hugo invocation. A failed Hugo command exits before the synchronization step, leaving the previous generated tree in place. For stronger atomicity, build each revision in its own release directory and point Nginx at a current symlink; switch that symlink only after the build succeeds. Retain at least one previous release so a bad deployment can be restored immediately.

Capture logs

SSH clients may show hook output during a push, but that is not a durable deployment log. Redirect standard output and error to a root-owned or deploy-owned log location, rotate it, and include the commit ID and timestamp. Never write secrets, private keys, or environment values containing credentials to the log.

Restrict SSH to Git pushes

The deployment key should be used only for this repository. In /home/deploy/.ssh/authorized_keys, disable interactive features and invoke a wrapper that checks the requested Git service:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
command="/usr/local/bin/restricted-git",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-ed25519 AAAA... deployment-key

Create /usr/local/bin/restricted-git as root with mode 755:

#!/bin/sh
set -eu
case "${SSH_ORIGINAL_COMMAND:-}" in
  "git-receive-pack '/srv/git/site.git'")
    exec /usr/bin/git-receive-pack /srv/git/site.git
    ;;
  *)
    echo 'This key is limited to the production repository.' >&2
    exit 1
    ;;
esac

Use a separate key for automation and keep the private half off the VPS. If several people push, grant access through your normal code-review or key-management process rather than sharing one private key.

Configure Nginx to serve Hugo output

Point the server block’s root at the generated directory, not at the repository or workspace. A minimal static configuration is:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.
server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/site/public;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Add your TLS configuration for the hostname using the certificate method you operate. Validate before reloading:

sudo nginx -t
sudo systemctl reload nginx

Give Nginx read and directory-traversal permission without making the source tree public. If you use a release symlink, ensure Nginx can traverse the release parent and that the symlink target is readable by the Nginx worker.

Run an acceptance deployment

Do not treat a successful SSH push as proof that the site is correct. Make a harmless change, push it, and check each boundary in order.

  1. Confirm the push targets the intended branch:

    git push production main
  2. Check the hook log and verify that it ran as deploy, checked out the expected commit, and returned a zero Hugo exit status.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  3. Inspect the generated tree for index.html, static assets, feeds, and the sitemap. Check that URLs use the production base URL and environment-specific settings.

  4. Request the site through its public hostname and confirm Nginx serves the new revision, including a cache-busted asset or visible test change.

  5. Delete or rename a test page, push again, and verify that the old URL disappears. Repeat with a draft, expired page, or future-dated page if those features are part of your site.

    Best Value
    Sale
    Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
    • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
    • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
    • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
    • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
    • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.
  6. Introduce a known template or content error on a temporary branch, push only if your process permits it, and verify that Hugo fails and the last good output remains available. Revert the test immediately.

    Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  7. Test the SSH restriction by attempting an interactive login or a different Git command with the deployment key; both should be rejected.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Rollback and recovery

Prefer a normal Git revert

For a bad content or template change, create a revert commit and push main. The hook then builds a new, traceable revision. This preserves the audit trail and avoids rewriting the production branch.

Restore a known commit

If an urgent rollback must recreate an earlier revision, push that commit to the production branch according to your branch policy:

git push production <known-good-commit>:main

If force-pushes are prohibited, create a branch from the known-good commit, merge or revert it through the normal review process, and push the resulting commit. A release-directory setup can switch Nginx back to the previous release without rebuilding, but the source branch should still be corrected so the next deployment does not reintroduce the defect.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When a hook appears not to run

  • Check that the file is exactly named post-receive, has a valid shebang, and is executable.
  • Verify ownership and permissions on the hook, repository, workspace, and destination.
  • Confirm that the push ref is refs/heads/main; tags and other branches are intentionally ignored by the sample.
  • Run the Hugo command manually as deploy with the same absolute path and flags.
  • Inspect the hook log and system journal for permission, missing-binary, or template errors.

When the site shows old files

Confirm that --cleanDestinationDir is present, the hook is building the expected workspace, and Nginx’s root points to that same destination. Browser or proxy caching can also mask a successful deployment, so inspect the response headers and request a changed asset directly.

When assets or Sass fail

Check the Hugo edition first. Sass processing needs extended capability. Also verify that modules, Node-based asset steps, and any environment variables used locally are installed or defined for the non-interactive deploy account.

Operational hardening

  • Keep /srv/git and /srv/build outside every Nginx document root.
  • Do not let the deployment account use sudo without a narrowly defined command policy.
  • Pin the Hugo version used by production and upgrade it deliberately; a different binary can change rendering or asset behavior.
  • Set the production environment explicitly and keep secrets out of committed configuration and hook output.
  • Use a lock such as flock if concurrent pushes are possible, so two builds cannot overwrite the workspace or destination at once.
  • Check available disk space: the bare repository, checkout, temporary build, and retained releases all consume storage.
  • Back up the Git repository and deployment configuration. The generated tree is reproducible, but the repository and keys are not disposable.
  • Monitor HTTP errors and hook failures. A static site can continue serving the previous release while a later build is broken, which makes logging essential.

Git hooks versus other Hugo deployment methods

Hugo documents two broad approaches: push source to a Git repository and let a hosting platform build and deploy it, or build locally and transfer the generated files to the host. A VPS hook is a self-managed version of the first approach.

Approach Build owner Strengths Trade-offs
VPS bare repository and hook Your VPS Direct push-to-publish flow, full control of paths and runtime, no external runner required. You maintain the OS, Hugo version, SSH restrictions, logs, concurrency, backups, and TLS.
Managed Git CI/CD Managed runner Isolated builds, built-in logs, easier previews and secrets management, less server maintenance. Runner configuration, provider limits, credentials, and the handoff to the VPS or hosting target become dependencies.
Local build plus rsync, FTP, or scp Developer workstation Simple server, explicit approval before transfer, useful for occasional sites. Build reproducibility depends on each workstation and the deployment can be easy to forget or perform inconsistently.
Hugo deploy to object storage Local machine or CI runner Targets services such as Amazon S3, Azure Blob Storage, and Google Cloud Storage; supports dry runs, confirmation, deletion limits, worker controls, and CDN invalidation options. Requires object-storage credentials, a deploy-capable Hugo edition, and a different serving and rollback model.

Choose the VPS hook when you value a small, self-hosted path and are willing to operate it. Choose managed CI when previews, isolated build environments, team audit controls, or reduced server maintenance matter more. Choose local transfer for a low-frequency site where the operator deliberately reviews every upload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A production checklist

  • Dedicated deployment account created; no routine root execution.
  • Bare repository, private checkout, and Nginx document root are separate.
  • Production branch is checked explicitly in post-receive.
  • Hugo edition supports the site’s Sass, modules, and deployment needs.
  • Absolute Hugo path and production environment are set in the hook.
  • Destination cleanup is enabled on every production build.
  • SSH key is restricted to the exact repository and has forwarding and TTY disabled.
  • Nginx root points only to generated output; nginx -t passes before reload.
  • Logs, disk space, backups, and concurrent-push behavior are monitored.
  • A harmless push, deletion test, failed-build test, and rollback procedure have been verified.

Final deployment sequence

Once configured, the normal release path is short: commit and review the Hugo source, push main to the restricted VPS remote, let post-receive check out the revision and build it with destination cleanup, then verify the hook log and the public hostname. The repository remains the audit record, the build workspace stays private, and Nginx exposes only the generated static files.

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.