A bare Git repository stores a project's version-control history and metadata without a working directory containing editable source code. It acts as a private remote: developers push and pull changes, while deployed files live elsewhere. section 3.3 section 3.3.4
A practical self-hosted deployment flow uses the bare repository as the handoff point:
- Log in to the virtual machine with SSH and install Git. section 3.3.1
- Create a repository directory and initialize it with git init --bare. section 3.3.2
- Set HEAD to the main branch so the remote has a default branch reference. section 3.3.2
- Add the VM repository as a local Git remote and push the main branch. section 3.3.2 section 3.3.3
- Use a post-receive hook to check out the pushed code into a separate working directory, install dependencies, and restart application processes. section 3.3.4
Two application remotes
A VM can host /var/repos/roadtok8s/py.git for a Python application and /var/repos/roadtok8s/js.git for a Node.js application. Local projects push with git push vm main; hooks then populate /opt/projects/roadtok8s/py and /opt/projects/roadtok8s/js. section 3.3.2
Listing 3.9 Initializing the bare web app repos
mkdir -p /var/repos/roadtok8s/py.git cd /var/repos/roadtok8s/py.git git init --bare git symbolic-ref HEAD refs/heads/main mkdir -p /var/repos/roadtok8s/js.git cd /var/repos/roadtok8s/js.git git init --bare git symbolic-ref HEAD refs/heads/main
Inspect the commands that create both bare repositories and point HEAD at main. section 3.3.2
Listing 3.13 Creating the post-receive file
export WORK_TREE=/opt/projects/roadtok8s/py export GIT_DIR=/var/repos/roadtok8s/py.git cat <<EOF > "$GIT_DIR/hooks/post-receive" #!/bin/bash git --work-tree=$WORK_TREE --git-dir=$GIT_DIR checkout HEAD -f EOF chmod +x "$GIT_DIR/hooks/post-receive"
Inspect the post-receive hook that connects the bare repository to its deployed working tree. section 3.3.4
