Last checked by Netlify Support Team: October 2024
Some workflows require use of an SSH private key during build - for instance, logging in to a server to restart your backend, or using git clone on a private repo during build. There are better ways to accomplish this goal for most use cases, but in case you choose to do that, below is an approach that can work.
First, create an ssh key and add the public key (shorter one) to your service (e.g. on your GitHub repo settings, or in ~/.ssh/authorized_keys
on your server)
Then, take the private key (longer one) and transform it into something suitable for the build environment. This means that it wouldn’t have carriage returns in it, so I’ve edited the key I use with this pattern, in my Netlify Build Environment Variables on the Build & Deploy settings page, as shown in this screenshot:
There, I configure my SSH_KEY
variable, setting it to a value like this:
-----BEGIN RSA PRIVATE KEY-----_MIIEpAIBAAKCAQEAoCGgoxalJiAF5WKQ...
You can see your own key will look more like:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAoCGgoxalJiAF5WKQ...
So you can see, I’ve just replaced carriage returns with underscores. Then I use this sequence as part of my build command:
mkdir -p ~/.ssh && echo -e "${SSH_KEY//_/\\n}" > ~/.ssh/id_rsa && chmod og-rwx ~/.ssh/id_rsa
Now you’ll have a mostly-usable SSH key in your build environment. I say “mostly” since there are still some things to consider:
- You’ll need to set these settings for git (which you would & can use manually if you ran ssh interactively):
-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no
. This stack overflow article shows how to apply them to the git config: https://stackoverflow.com/questions/7772190/passing-ssh-options-to-git-clone - You’ll need to do this BEFORE YOUR BUILD STARTS and BEFORE YOU NEED THE KEY. So - this may be a challenge considering you might have a
package.json
that we try to use withnpm install
before the build runs. You’ll have to do something to prevent us from runningnpm install
, such as not having a package.json file in the root of your repo, or make that package optional - and then install it later, AFTER you’ve run those build commands.
I don’t have a great demonstration of that use pattern to share - if you require the package before your build starts, the submodule route mentioned in this article (about Hugo, but generally applicable) outlines how this process can happen at clone time rather than post-dependency-installation time. Even without a specific example, hopefully this provides some ideas on how you can approach this process.