Launching My New Site: A Git Push-to-Deploy Adventure
Today, I successfully launched my new website, built with the static site generator MkDocs, on my DreamHost server. Instead of manually uploading files with FTP, I wanted a more modern and efficient workflow. The goal was to create a "push-to-deploy" pipeline: when I push new changes to a Git repository on my server, the server should automatically build and publish the website.
This is the story of that journey, including the initial plan and the many troubleshooting steps it took to get everything working perfectly.
The Initial Plan: A 'Happy Path' to Deployment
The high-level plan was straightforward:
- Set up a Git Remote: Add a remote to my local Git repository that points to my DreamHost server via SSH.
- Create a Bare Repository on the Server: This special type of repository on the server would receive my pushes. It doesn't have a working copy of the files, just the Git history.
- Implement a
post-receiveHook: This is a script that lives in the server's repository and runs automatically every time it receives a push. - Write the Deployment Script Logic: The script would:
- Check out the latest source code into a temporary directory.
- Run
mkdocs buildto generate the static HTML files. - Copy the generated files from the
site/directory to my public web folder (dandevins.com).
- Push and Go Live: A simple
git pushfrom my local machine would trigger the whole process.
The Troubleshooting Journey: Debugging the Pipeline
As is often the case in development, the "happy path" had a few detours. Here is a breakdown of the issues we encountered and how we solved them.
Problem 1: git: command not found
The very first step failed. My local machine couldn't find the git command. This was a simple environment issue; Git wasn't installed or its location wasn't in my system's PATH variable. Once I installed it correctly, I was able to proceed.
Problem 2: fatal: You are on a branch yet to be born
After setting up the script and pushing for the first time, the deployment failed. The error message indicated that when the script tried to check out the files on the server, Git didn't know which branch to use. The initial git checkout -f command was too generic.
- Solution: We made the command more specific, telling it to check out the
mainbranch explicitly:git checkout -f main.
Problem 3: rsync: ... No such file or directory
The next push failed with an rsync error. The script was trying to copy the built files from the site/ directory, but that directory didn't exist. This meant the preceding mkdocs build command was failing silently.
- Solution: We ran the
mkdocs buildcommand manually on the server to see the real error.
Problem 4: mkdocs: command not found
The manual build revealed the root cause of the previous error: mkdocs wasn't installed on the server. On a shared host like DreamHost, you can't use system package managers like apt.
- Solution: The correct method is to install Python packages in a user-owned virtual environment.
Problem 5: The Virtual Environment Saga
Creating a virtual environment hit its own snags (ensurepip is not available). This required consulting DreamHost's specific documentation to use their provided Python setup correctly. After that, we had to ensure the virtual environment was kept outside the public web directory for security.
- Solution: We created a new, correctly located virtual environment (
~/venv_dandevins) and installedmkdocsand its theme into it. We then updated thepost-receivescript to activate this environment before running the build.
Problem 6: The Final Boss - docs vs. Docs
The build was still failing, even with mkdocs installed. The error was now ERROR - Config value 'docs_dir': The path ... /docs' isn't an existing directory.
This was the most subtle problem, caused by a difference between my local Windows machine (case-insensitive) and the Linux server (case-sensitive).
- My local project folder was named
Docs. mkdocsby default looks for a folder nameddocs(lowercase).-
My Windows machine and Git were getting confused. Even though I thought the folder was correct locally, Git's internal index still recorded it as
Docs. -
Troubleshooting: We confirmed what Git was tracking using
git ls-files, which showedDocs/index.md(uppercase). - Solution: We had to force Git to recognize the case change with a two-step rename on my local machine:
git mv Docs temp_folder, followed bygit mv temp_folder docs.
Success!
After committing and pushing this final case-change fix, the deployment script ran flawlessly from top to bottom.
- The
post-receivehook was triggered. - The correct
mainbranch was checked out. - The Python virtual environment was activated.
mkdocs buildfound the lowercasedocsdirectory and successfully built the site.rsynccopied the new files into/home/usr/dandevins.com.- The website was live.
This journey was a fantastic learning experience. It highlighted the importance of robust scripting, understanding environment differences, and using targeted debugging to solve problems one by one. The final result is a clean, automated deployment pipeline that will make updating my site a breeze.