---
name: configure-git-webserver
description: Guidance for setting up Git repositories with automatic web deployment via post-receive hooks. This skill applies when configuring bare Git repositories, setting up web servers to serve pushed content, creating Git hooks for deployment automation, or implementing push-to-deploy workflows.
---

# 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:

1. **Bare Git repository** - The central repository that receives pushes
2. **Web content directory** - Where deployed files are served from
3. **Post-receive hook** - Automates deployment on push
4. **Web server** - Serves the deployed content
5. **User access** - Permissions for users to push to the repository

### Implementation Sequence

Execute tasks in dependency order:

1. Create the bare Git repository first (other components depend on its location)
2. Create the web content directory
3. Create and configure the post-receive hook (depends on both repository and web directory)
4. Start the web server (depends on web directory existing)
5. 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:
```bash
#!/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:

1. **Repository verification**: Check that the bare repository exists and has correct structure
   ```bash
   ls -la /path/to/repo  # Should show HEAD, objects/, refs/, etc.
   ```

2. **Hook verification**: Confirm hook exists and is executable
   ```bash
   ls -la /path/to/repo/hooks/post-receive
   ```

3. **Web server verification**: Confirm server is running and listening
   ```bash
   ss -tlnp | grep :PORT  # or netstat -tlnp, or ps aux | grep server
   ```

### End-to-End Testing

Test the complete workflow:

1. Clone the repository (use local path for initial testing)
2. Create a test file and commit
3. Push to the repository
4. Verify the file appears in the web directory
5. Verify the file is accessible via HTTP

### Pre-Check Available Commands

Before using system commands, verify availability to reduce trial-and-error:

```bash
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:
```bash
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.
