Configure Git Webserver
Overview
This skill provides guidance for setting up a Git-based web deployment system where pushing to a Git repository automatically deploys content to a web server. The typical workflow involves creating a bare Git repository, configuring a post-receive hook to deploy content, and running a web server to serve the deployed files.
Approach
Component Identification
Before implementation, identify all required components:
-
Bare Git repository - The central repository that receives pushes
-
Web content directory - Where deployed files are served from
-
Post-receive hook - Automates deployment on push
-
Web server - Serves the deployed content
-
User access - Permissions for users to push to the repository
Implementation Sequence
Execute tasks in dependency order:
-
Create the bare Git repository first (other components depend on its location)
-
Create the web content directory
-
Create and configure the post-receive hook (depends on both repository and web directory)
-
Start the web server (depends on web directory existing)
-
Configure user access as needed
Post-Receive Hook Design
The post-receive hook should:
-
Handle multiple branch names (both master and main for compatibility)
-
Use git --work-tree to checkout to the web directory
-
Be marked executable (chmod +x )
-
Include the proper shebang (#!/bin/bash )
Example hook structure:
#!/bin/bash while read oldrev newrev ref do branch=$(echo $ref | cut -d/ -f3) if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then git --work-tree=/path/to/web/dir --git-dir=/path/to/repo checkout -f $branch fi done
Web Server Options
Consider available options based on environment:
-
python3 -m http.server
-
Simple, usually available, single-threaded
-
nginx
-
Production-ready, requires installation
-
node http-server
-
Requires Node.js
-
busybox httpd
-
Lightweight, often available in minimal environments
Verification Strategies
Component-Level Verification
Verify each component independently before testing the full workflow:
Repository verification: Check that the bare repository exists and has correct structure
ls -la /path/to/repo # Should show HEAD, objects/, refs/, etc.
Hook verification: Confirm hook exists and is executable
ls -la /path/to/repo/hooks/post-receive
Web server verification: Confirm server is running and listening
ss -tlnp | grep :PORT # or netstat -tlnp, or ps aux | grep server
End-to-End Testing
Test the complete workflow:
-
Clone the repository (use local path for initial testing)
-
Create a test file and commit
-
Push to the repository
-
Verify the file appears in the web directory
-
Verify the file is accessible via HTTP
Pre-Check Available Commands
Before using system commands, verify availability to reduce trial-and-error:
command -v netstat || command -v ss # Network status command -v systemctl || command -v service # Service management
Common Pitfalls
Persistence Issues
Problem: Background processes (like python3 -m http.server & ) do not survive system restarts.
Mitigation: For production use, create a systemd service or use a process manager. For testing purposes, background processes are acceptable but document the limitation.
Permission Issues
Problem: Users cannot push to the repository or the hook cannot write to the web directory.
Mitigation:
-
Verify repository ownership and permissions
-
Ensure the user running the hook has write access to the web directory
-
Check that the hook itself is executable
Branch Name Handling
Problem: Hook only handles master but user pushes to main (or vice versa).
Mitigation: Handle both common default branch names in the hook logic.
Testing Methodology
Problem: Testing with local paths (/git/server ) may pass but SSH-based access (user@server:/git/server ) may fail.
Mitigation: If SSH access is required, verify SSH configuration and user access separately from the Git/web functionality.
Error Handling in Hooks
Problem: Hook failures are silent, making debugging difficult.
Mitigation: Add error output and logging to hooks:
exec 2>&1 # Redirect stderr to stdout set -e # Exit on error
Single-Threaded Web Servers
Problem: Simple web servers like python3 -m http.server are single-threaded and unsuitable for concurrent access.
Mitigation: Document this limitation. For production, use a proper web server like nginx.
Task Breakdown Guidance
Avoid excessive granularity in task tracking. Group related operations:
-
Good: "Set up bare Git repository with post-receive hook"
-
Avoid: Separate tasks for "create directory", "run git init", "create hook file", "make hook executable"
Focus task tracking on logical milestones rather than individual commands.