Introduction
I want the ability to do a git pull
in any of my projects on a server, without attaching my git account or anyone else’s git account. Deployment keys makes this possible. You create a key pair, which is a public file and a private key.
Metaphor
Imagine that you have paranoid friends who don’t trust a face or voice, only a cryptographic “handshake” is sufficient. You create a key pair and share your public key with these friends. They will use this public key and generate a token each time they speak with you. You receive the token, decrypt it with your private key and send the decrypted token back. They’ll know it’s you since the matching private key is the only key that can decipher the token generated by the matching public file.
Practical
The private key sits on your server and is used each time we do a git pull
. The public key is uploaded to the git server.
Optional step 0: Create a deployment user on the server
It’s recommended that you create a separate deployment-user on your server. Create this user before you proceed.
Step 1: Generate key pairs
ssh-keygen -t rsa -C "Deployment key for XYZ"
ssh-keygen
generates the RSA key with descriptive Comment. Store it in ~/.ssh/XYZ_deployment_rsa
. Repeat this for the next repo, ABC
.
ls ~/.ssh/
should have these four files, and a few other:
XYZ_deployment_rsa
XYZ_deployment_rsa.pub
ABC_deployment_rsa
ABC_deployment_rsa.pub
Submit these files to your git host. I’m using github.com, so I’ll visit my repo page > Settings > Deploy keys and past the content of the .pub
file there.
Step 2: Edit ~/.ssh/config
~/.ssh/config
is a handy file. If you use a custom SSH port (not 22) and an authentication key to your server, you’d use something like: ssh carl@hambro.me -p 39281 -i ~/.ssh/hambrome_rsa
. These options are tedious and can be saved in the ~/.ssh/config
file instead.
Host hambro
HostName hambro.me
Port 39281
IdentityFile /Users/carl/.ssh/hambrome_rsa
Now, you’d use ssh hambro
instead. Neat! Host hambro
creates an alias of hambro
which points to that block of options. We want to use such alias next time we do a git pull
.
It is tempting to put something like this into the file:
Host github.com
HostName github.com
IdentityFile /root/.ssh/XYZ_deployment_rsa
IdentitiesOnly yes
But now we won’t be able to place our second repo, ABC, in another block, since the alias github.com
is already taken! This is solved by not using github.com
as the alias. You could use anything unique, but I’ll stick to XYZ-github.com
and ABC-github.com
. These “domains” won’t be resolved; they are only used as a lookup in our config
-file. (They are resolved to github.com
through the HostName
option)
Host ZYZ-github.com
HostName github.com
IdentityFile /root/.ssh/XYZ_deployment_rsa
IdentitiesOnly yes
Host ABC-github.com
HostName github.com
IdentityFile /root/.ssh/ABC_deployment_rsa
IdentitiesOnly yes
Step 3: Set git upstream to use SSH
The final step is to clone your repo over SSH. However, we will replace github.com
with XYZ-github.com
and ABC-github.com
.
E.g.: git clone git@XYZ-github.com:hambro/my_xyz.git
.
You can change existing repo upstream if they’re cloned already:
git remote set-url origin git@XYZ-github.com:hambro/my_xyz.git
. You are now done!
If you did the optional step, all you have to do to pull is su deploymentuser -c "git pull"
.