How to use ssh private key with Phoenix application

Hello,
I have a Phoenix application using the git_cli dependency to manage git repositories. The application is able to clone/push to a git server (Gitea).
On my machine the application is working as I have a configure the git server with a public key and I have my private key define in ~/.ssh/id_rsa.
However I’m not sure what is the best way to setup a pair of ssh private/public key on the Fly instance.
I’m thinking of trying to create keys manually on the server and store the private key on a volume but I will then need to update the code to let the dependency know where to find the key (if this is possible). Would this approach be the “correct” one or are there any other easier solution available, maybe using flyctl ssh tool?
Thanks

Could add your private key as a secret flyctl secrets set SSH_PRIV_KEY=abcd and then read that as an env variable inside your app?

Thanks for looking at this @savikko
I’m trying to do this at the moment. If I set the private ssh key in a secret I need to next find a way to use it with the git_cli (which is just an Elixir wrapper around the git command) without changing the code too much.
Another idea I’m testing is to still have the private key define in a secret and have a way in the Dockerfile to create the /root/.ssh/id_rsa file based on this secret. This way I won’t have to change the Elixir code and on each flyctl deploy the same key will be recreated on the server. However I don’t see a way to access the secret in the Dockerfile at the moment.

In that case, you might want to take a look at build args. The downside of that is that you’d be putting this private information on a fly.toml. Secrets are set on runtime so they’d not be available to you during the build.

Another way to approach this without secrets/envs/args would be making your Dockerfile copy directly this from a file (I assume ~/.ssh/id_rsa) and put on the proper place. The downside of this is that the machine that builds your app should have your id_rsa so you’d not be able to use our remote builders.

Those were my ideas for making this a zero-code solution. I tried to go to git_cli docs and could not see a doc for how to setup for prod so that’s unfortunate (seems like it just assumes the app runs on a place with an id_rsa which is not awesome IMO).

I think @savikko solution is quite reasonable: you could read the secret on elixir’s runtime.exs, write it on ~/.ssh/id_rsa and it should work just fine. I’d suggest doing something like this pseudo-code:

# runtime.exs
if config_env() == :prod do
  id_rsa = System.get_env("SSH_PRIV_KEY")
  # write file
end
2 Likes

Thanks @lubien and @savikko for the ideas.

I’ve managed to have a first version working.
I’m creating the ssh keys on my machine on a specific folder which I add to .gitignore to make sure to not publish the keys.
I then updated the Dockerfile to copy this folder to the Fly instance:

# Create .ssh folder in root folder on Fly
RUN mkdir /root/.ssh
# Copy the ssh key from my machine to Fly .ssh folder
COPY keys/id_ed25519 /root/.ssh
RUN ssh-keyscan -H your-host-with-public-key > /root/.ssh/known_hosts

The only issue is that I have to commented out the USER nobody created by flyctl launch as I didn’t find a way yet where to place the ssh key on Fly for the nobody user to find them.

I’ll try to create the /home/nobody/,ssh folder but I have a feeling it’s not going to work.

So the question I need to resolve is “where to create the .ssh folder containing the private key for the nobody user created in Dockerfile?”