blog-2025-09-06-forgejo-ssh

Saturday, September 6, 2025, 9:01:36 AM Coordinated Universal Time by stefs

forgejo installation on dokploy

keywords: forgejo docker dokploy ssh

i'm running my own forgejo instance via dokploy (i.e. in a docker container). as i'm currently the only user and scale/performance isn't a problem, i opted for sqlite, so i didn't even have to set up a postgresql instance (which would have been trivial in dokploy anyway).

there was just one hickup: private repositories were not accessible via ssh. this is necessary for authenticating from dokploy if the goal is to redeploy on push:

  1. git push to forgejo
  2. forgejo informs dokploy via webhook
  3. dokploy pulls from forgejo, builds (with nixpacks) the app and deploys it

after a short while i found the reason: git with ssh inside of docker needs either its own ssh server with a custom port or ssh-passthrough configured see the docs.

the custom port solution was recommended, but i opted for the "clean" ssh-passthrough route and subsequently lost several hours of my spare time (special thanks to gemini and claude, without i'd never had made it even that far).

the steps outlined in the gitea documentation (forgejo is a fork of gitea) are a bit simplistic; in my case several more steps were necessary.

  1. do not map the ssh port for forgejo in the docker file
  2. create a user git
  3. create a script ssh-shell bash script in gits home directory. the contents is, roughly
  #!/bin/bash
  exec /usr/bin/docker exec -i -u git \
    --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" \
    forgejo /usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-7
  1. set the shell of the git user to the ssh-shell script
  2. add your ssh key to the hosts and the forgejo-containers' authorized_keys (this is the icky part)

testing all this required a lot of use of ssh -vT git@<your_forgejo_domain> until all parts aligned. the welcome message should then display Hi yourusername! You've successfully authenticated, but Forgejo does not provide shell access..

now it worked, but only for my ssh key. if i added a second user to my forgejo instance i would have had to add their key to the authorized_keys file manually.

the problem here is the ssh authentication via authorized_keys - the entry with the public key must be present in the host and the forgejo containers authorized_keys file. this has to be solved through forgejo's key management. if the user adds an ssh key through the web interface, the application should write this into the containers authorized_keys file and the hosts git user should use the containers authorized_keys file instead of its own.

this is where i ran into the final problem that made me undo all progress and switch to the ports solution. the proper configuration would, in theory, be:

Host SSH config (/etc/ssh/sshd_config):

Match User git
    AuthorizedKeysCommand /usr/local/bin/forgejo-keys %u %k
    AuthorizedKeysCommandUser git

Key lookup script (/usr/local/bin/forgejo-keys):

#!/bin/bash
# This script fetches keys directly from Forgejo
docker exec -u git forgejo /usr/local/bin/gitea --config=/data/gitea/conf/app.ini admin user list-keys "$1" 2>/dev/null || true

the problem here is that the gitea executable doesn't have a admin user list-leys command. going through the documentation now it seems the command was changed to

AuthorizedKeysCommand /path/to/gitea keys -e git -u %u -t %t -k %k

for now i'm keeping the custom ssh server, though.

source


Saturday, September 6, 2025, 9:01:12 AM Coordinated Universal Time by stefs

forgejo installation on dokploy

keywords: forgejo docker dokploy ssh

i'm running my own forgejo instance via dokploy (i.e. in a docker container). as i'm currently the only user and scale/performance isn't a problem, i opted for sqlite, so i didn't even have to set up a postgresql instance (which would have been trivial in dokploy anyway).

there was just one hickup: private repositories were not accessible via ssh. this is necessary for authenticating from dokploy if the goal is to redeploy on push:

  1. git push to forgejo
  2. forgejo informs dokploy via webhook
  3. dokploy pulls from forgejo, builds (with nixpacks) the app and deploys it

after a short while i found the reason: git with ssh inside of docker needs either its own ssh server with a custom port or ssh-passthrough configured see the docs.

the custom port solution was recommended, but i opted for the "clean" ssh-passthrough route and subsequently lost several hours of my spare time (special thanks to gemini and claude, without i'd never had made it even that far).

the steps outlined in the gitea documentation (forgejo is a fork of gitea) are a bit simplistic; in my case several more steps were necessary.

  1. do not map the ssh port for forgejo in the docker file
  2. create a user git
  3. create a script ssh-shell bash script in gits home directory. the contents is, roughly
  #!/bin/bash
  exec /usr/bin/docker exec -i -u git \
    --env SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" \
    forgejo /usr/local/bin/gitea --config=/data/gitea/conf/app.ini serv key-7
  1. set the shell of the git user to the ssh-shell script
  2. add your ssh key to the hosts and the forgejo-containers' authorized_keys (this is the icky part)

testing all this required a lot of use of ssh -vT git@<your_forgejo_domain> until all parts aligned. the welcome message should then display Hi yourusername! You've successfully authenticated, but Forgejo does not provide shell access..

now it worked, but only for my ssh key. if i added a second user to my forgejo instance i would have had to add their key to the authorized_keys file manually.

the problem here is the ssh authentication via authorized_keys - the entry with the public key must be present in the host and the forgejo containers authorized_keys file. this has to be solved through forgejo's key management. if the user adds an ssh key through the web interface, the application should write this into the containers authorized_keys file and the hosts git user should use the containers authorized_keys file instead of its own.

this is where i ran into the final problem that made me undo all progress and switch to the ports solution. the proper configuration would, in theory, be:

Host SSH config (/etc/ssh/sshd_config):

Match User git
    AuthorizedKeysCommand /usr/local/bin/forgejo-keys %u %k
    AuthorizedKeysCommandUser git

Key lookup script (/usr/local/bin/forgejo-keys):

#!/bin/bash
# This script fetches keys directly from Forgejo
docker exec -u git forgejo /usr/local/bin/gitea --config=/data/gitea/conf/app.ini admin user list-keys "$1" 2>/dev/null || true

the problem here is that the gitea executable doesn't have a admin user list-leys command. going through the documentation now it seems the command was changed to

AuthorizedKeysCommand /path/to/gitea keys -e git -u %u -t %t -k %k

(see [https://docs.gitea.com/administration/command-line#keys])

for now i'm keeping the custom ssh server, though.

source


view