Issue 53 - Run Your Own Git Remote and Rethink Audience Segments for Docs
Segment your users by knowledge of your product and set up your own Git remote on a Linux server.
Instead of thinking just about user personas for your documentation, think about where people are in their awareness of your product and its features. In this issue, you'll explore the intersection of documentation and marketing to drive product growth in your docs. Then you'll set up your own private Git remote on a Linux server so you can still collaborate with your peers when you experience an outage at a hosted provider.
Four Audiences for Product Growth and Enablement
You can't write a single piece of content that works for everyone. People try, but it never goes well. You make assumptions about their experience, you leave readers behind, or the content has no real depth. What you end up with is a junk drawer of stuff that never feels right. It creates information architecture problems, and it feels messy.
So you have to define your audience, and you have to write different content for each one.
When people sort their audience for product work, they reach for use cases, "jobs to be done," or "personas." Those tell you who your reader is and what they want to get done. But they skip the one thing that decides what content to write: how much your reader already knows.
Sort your readers by what they know instead. This will tell you exactly what each person needs from you. You can break your audience into four groups:
- People who know the feature they need but can't remember how to use it.
- People who have a problem but don't know how to use your product to solve it.
- People who have a problem but don't know you have a solution for it.
- People who don't know they have the problem you solve.
Marketers have a framework that sounds like this. Eugene Schwartz laid out the stages of awareness in his 1966 book Breakthrough Advertising, and copywriters have leaned on it for almost sixty years. The framework sorts prospects by how aware they are, then moves them toward a sale. But that framework is built to turn strangers into customers. It stops at the sign-up. Your job doesn't.
A lot of your readers already signed up. They're inside the product right now, trying to get work done. Your docs have to serve two kinds of people at once: the ones you want to win over, and the ones who already chose you. That second group is where marketing awareness content runs out of things to say.
Each group needs different kinds of content, and that's where the Diátaxis framework can help. Diátaxis sorts content into reference, how-to guides, tutorials, and conceptual content. If you're not familiar with Diátaxis, that's your homework for this month.
Let's look at each awareness group and how to reach them with the right content.
People who know the feature they need but can't remember how to use it.
This group is your core users. They're active, they're engaged, and they have a lot to do. Your product is one of many they touch every day. They already know you have the feature they need, so they go straight to your reference docs and code samples.
Say your product is a tool that runs background jobs and retries them when they fail using a feature called a Retry Policy. This reader types "retry policy syntax" into your documentation's search box. They don't want theory, and they're not looking to discover a new feature right now. They want the exact option name and a working example, fast.
Give them content that solves their immediate problem, quickly. Your reference documentation and how-to guides are key assets here. Keep them accurate and keep them current, because this is where quality content stops paying customers from churning. Link out to your explainers in case they need more information, but lead with the answer to their problem so they can get back to work.
People who have a problem but don't know how to use your product to solve it.
This group consists of two subgroups. The first subgroup is made up of people new to your product. They heard it can do a few things that they need, and they want to know how that works. The other subgroup is made up of your core users who hit a new use case and heard your product can do that too. This second subgroup is where your real product growth comes from, because they're already giving you money. You're going to help them give you more.
Back to the background job tool example. Someone searches "how to retry failed jobs in [your product]." They know your name, and they've heard you're the solution. They just don't know the steps yet, or they might not be sure it works the way they need it to work. This is the content with the best return on investment if you do it well.
Use how-to guides here, but build out tutorials too. A tutorial teaches instead of just showing someone how to do a task. Build tutorials around specific jobs within use cases, and put them where new users will find them, like your onboarding or in customer newsletters. This is also where good conceptual content shines, because you're making the case for adoption. People want proof you solve their problem in a way that fits how they work, so show them how things work under the hood.
People who have a problem but don't know you have a solution for it.
People in this group are often prospective customers, but a lot of your current customers fall into this group too. As your product grows, people stop keeping up with new features and new product lines. Think about current customers as prospects for new product features and treat them with the same approach, because it's a discoverability issue.
When people are searching Google or using LLMs and asking "how do I retry failed API calls without losing data," they don't use your product name at all. They're focused on the outcome, not on you. If your product solves that problem, you want to be the solution that pops up.
That changes the role of your documentation. Good docs are a huge top-of-funnel marketing asset. You'll find that documentation drives a lot of traffic to your product's domain, and you can build how-to and tutorial content that helps discovery when you use the words your readers actually search for. Use their keywords and their framing, not your product names and jargon. Write tutorials that target the outcome first, then tie your product in. Be sure to do this in an authentic and helpful way.
This is another place where you should steer into your use cases. Identify the most impactful ones and create tutorials focused on those areas. Promote them to get them in front of your prospects, make sure your sales teams can find them and share them with prospects, and find ways to get the content into the product so existing customers find it.
If you do this well, you may be able to syndicate this use-case content on other platforms and pull people back to you.
People who don't know they have the problem you solve.
This is the hardest group to reach, and it can pay off the most.
This reader isn't searching at all. They wrote their own retry code. A loop, a counter, and a sleep call. It works most of the time, so they think it's fine. They don't know they have a problem, so they'll never type a question about it. But you know your product does it better than anything they could write on their own.
You can't catch them with reference docs or a how-to, because they aren't looking at your documentation. You reach them by naming the problem they've learned to live with. This is where your conceptual content and thought leadership content comes in. Show them why their hand-rolled retry loop drops jobs when the server restarts. Reframe the way they work today as the problem, and your product becomes the answer they didn't know to ask for.
Create conceptual technical content and work with your partners in Marketing to make sure the right people see it. This content is slow to pay off and hard to measure. But when it lands, you've created demand that wasn't there before.
Tie it together
Link your content across the groups. Your reference docs should point to your explainers. Your outcome tutorials should point to your reference docs. A reader can enter at any group, and good links move them along to whatever they need next. Then make sure you're partnering with everyone else in your organization to get that content in front of as many customers and prospects as possible. Use it to start conversations, close deals, and create new opportunities.
Sort your readers by what they already know, match the content to that, and connect the pieces. That beats writing for "everyone" every time.
Things To Explore
- phpvm is a PHP version manager. You can manage multiple PHP versions and tie a version to a project.
- Agent Sandbox "enables easy management of isolated, stateful, singleton workloads, ideal for use cases like AI agent runtimes."
Run Your Own Git Remote with SSH
You don't need a hosting service to share code with your team or back up your work. A plain Linux server and SSH can do the job. Your server, your repositories, no third party in the middle. And when the big hosting providers have a rough day, which they sometimes do, your remote keeps working.
Before you start, set your expectations. This gives you a place to push and pull code. That's it. You won't get a website, pull requests, issues, or automated builds. If you need those, a hosted service is still the right tool. But if you just want a shared remote you control, you can set one up in a matter of minutes.
To do this, you need a Linux server you can already reach over SSH, and your public SSH key on the machine you'll push from. If you don't have a key yet, GitHub's guide to generating one works fine no matter where you plan to use it.
Create a git user and repositories on the remote machine
You're going to create a dedicated git user and an empty repository on the remote machine. A remote repository should be "bare," which means it has no working copy of the files. It only stores the history that people push and pull. Trying to push to a normal repository with a working copy causes problems, so bare is what you want on a server.
Log in to your Linux server over SSH with your regular user.
Make a dedicated account that owns the repositories. A separate user keeps your repos tidy and limits the damage if a key ever leaks. Later, you'll ensure that nobody can log in as the git user to poke around the system. You'll make sure they can only push and pull.
Create the account with no password, which blocks password logins right away:
$ sudo adduser --disabled-password --gecos "" git
This creates a normal user named git with a home directory at /home/git. You'll use that home directory in the next steps.
Create a folder to hold your repositories, owned by the git user:
$ sudo -u git mkdir -p /home/git/repos
Now create your first repository.
$ sudo -u git git init --bare /home/git/repos/project.git
The .git suffix on the folder name is a common convention for bare repositories. It's not required, but it makes them easy to spot.
Add SSH keys so people can authenticate.
People will connect using their SSH keys, so the server needs to know which keys to trust. Those go in a file called authorized_keys inside the git user's .ssh folder.
Set up the folder and file with the right permissions. Run the following commands:
$ sudo -u git mkdir -p /home/git/.ssh
$ sudo -u git chmod 700 /home/git/.ssh
$ sudo -u git touch /home/git/.ssh/authorized_keys
$ sudo -u git chmod 600 /home/git/.ssh/authorized_keys
SSH is picky about these permissions. If they're too open, it will refuse to use the file, so don't skip the chmod steps.
Now add a public key to the file. Grab the contents of your .pub key file and append it to authorized_keys. For example, if your public key is id_rsa.pub, run the following command:
$ cat ~/.ssh/id_rsa.pub | sudo -u git tee -a /home/git/.ssh/authorized_keys
Each line in the authorized_keys file is one public key. If you want more people to connect, you'll have to get their keys and add them.
Typing keys by hand gets old once you have a few people to add. GitHub can help here. Every GitHub user's public keys are available at a URL based on their username. Visit https://github.com/{username}.keys in your browser, swap in a real username, and you'll see that user's public keys.
You can use that to script the whole thing. Start with a text file of GitHub usernames, one per line. Call it github-users.txt:
alice
bob
carol
Then run a script that reads the file, fetches each person's keys, and writes them all to authorized_keys:
#!/usr/bin/env bash
set -euo pipefail
USER_FILE="${1:-github-users.txt}"
GIT_HOME="/home/git"
AUTH_KEYS="$GIT_HOME/.ssh/authorized_keys"
TMP="$(mktemp)"
while read -r username || [ -n "$username" ]; do
[ -z "$username" ] && continue
case "$username" in \#*) continue ;; esac
curl -fsSL "https://github.com/${username}.keys" \
| sed "s/$/ github:${username}/" >> "$TMP"
done < "$USER_FILE"
sudo install -d -m 700 -o git -g git "$GIT_HOME/.ssh"
sudo install -m 600 -o git -g git "$TMP" "$AUTH_KEYS"
rm -f "$TMP"
The script tags each key with the GitHub username it came from, so you can tell whose key is whose later. It also sets the correct permissions and ownership for you.
This script replaces authorized_keys every time it runs. The username file is now the single source of truth. Don't hand-edit authorized_keys after this, or your changes will disappear the next time you run the script. To add or remove someone, edit github-users.txt and run it again.
Lock the git account down with git-shell
Right now the git user can log in and get a full shell. That means anyone whose key is in authorized_keys can run any command on your server, not just git commands. That's more access than you want to hand out.
Git ships with a tool called git-shell that fixes this. It lets people run git commands over SSH but blocks everything else. No real shell, no poking around.
Find where git-shell lives, add it to the list of valid login shells, and set it as the git user's shell:
$ which git-shell | sudo tee -a /etc/shells
$ sudo chsh git -s "$(which git-shell)"
Now the git account can only move git data in and out.
From the machine you'll push from, try connecting over SSH with the git user:
$ ssh git@server
Instead of a prompt, you'll receive a message like the following:
fatal: Interactive git shell is not enabled.
Connection to server closed.
That message verifies you can't log in with this user.
Push your first repository
To push code to your remote server, add it as a remote on your project.
Navigate to your project and set up git if you haven't already:
$ cd /path/to/project
$ git init
$ git add .
$ git commit -m "initial commit"
Now point your project at the server and push. The path is relative to the git user's home directory, so repos/project.git finds the bare repository you created:
$ git remote add origin git@server:repos/project.git
$ git push -u origin main
Your history is now on your own server. The -u flag sets it as the default remote, so from now on you can just run git push and git pull.
Clone your repository on another machine
The whole point of a remote is that more than one person, or more than one machine, can use it. Anyone with a trusted key clones the repo the same way:
$ git clone git@server:repos/project.git
That pulls down a working copy they can commit to and push back.
When you have another project you want to push to your remote server, create another bare repository on the remote and push your code to it. Log in to the server with your regular account that has sudo access, and run the git init command again with a new name:
$ sudo -u git git init --bare /home/git/repos/another-project.git
Then push to it the same way you pushed the first one, using another-project.git as the path.
Consider backing up the repositories on your remote server. Clones on people's machines hold the history too, but don't count on that as a real backup plan. Set up something that copies /home/git/repos somewhere safe on a schedule.
Using an SSH-based Git remote has some tradeoffs. There's no web interface, no pull requests, no issue tracking, no automated builds, and no granular user access. For a personal project or a small team that just needs a shared place to push code, this is a quick low-tech solution that works well, especially if a hosted provider is offline.
Parting Thoughts
- What kinds of audience segments have you created content for already? How can you target people who don't know about the problem you solve? Identify some opportunities to educate people about your problem space rather than your solution. This can build trust.
- Set up a remote
gitserver, but useremoteinstead oforiginand try pushing some of your existing repositories to your private server as a second source. This will get you used to juggling multiple remotes.
Thanks for reading.
You just read issue #53 of Code, Content, and Career with Brian Hogan. You can also browse the full archives of this newsletter.