How to configure ssh client on a container with docker file and compose

Hi,

I run an environment with dockerfile and a docker-compose and i want to permit ssh connection thru my container. I have tried many conf but it did’nt work
My dockerfile :

# Install SSH
RUN apk add --no-cache openssh-client
RUN mkdir -p /root/.ssh
COPY docker-web/SSH/config /var/www/html/.ssh/config
COPY docker-web/SSH/id_rsa /var/www/html/.ssh/id_rsa
COPY docker-web/SSH/id_rsa.pub /var/www/html/.ssh/id_rsa.pub
RUN chmod 600 /var/www/html/.ssh/id_rsa

My docker-compose-yaml :

        volumes:
            - './docker-web/SSH/:/var/www/html/.ssh:ro'

When i open a terminal, my .ssh conf and my keys aren’t loaded. The directory created owned by the internal user of docker, i suppose :

/var/www/html $ ls -al
total 20
drwxrwxrwt    1 www-data www-data      4096 Dec  3 10:20 .
drwxr-xr-x    1 root     root          4096 Oct  9 00:42 ..
drwx------    2 2029    3100035        4096 Nov 25 13:48 .ssh

Have you an idea ? Thanks for your help

To me the setup doesn’t make sense. Either you use COPY to place the cert files inside the image, or you use volumes to mount the files into the container during runtime.

Also I would NEVER place key files inside /var/www/html/, you never know if that gets accidentally exposed and the Internet bots are just waiting to find and abuse such files.

Ok. with a docker-compose conf only :

        volumes:
            - './docker-web/SSH/:/home/www-data/.ssh:ro'
/var/www/html $ ls -la /home/www-data
total 20
drwxr-sr-x    1 www-data www-data      4096 Dec  3 11:23 .
drwxr-xr-x    1 root     root          4096 Oct  9 00:42 ..
-rw-------    1 www-data www-data        22 Dec  3 11:23 .ash_history
drwx------    2 2029     3100035       4096 Nov 25 13:48 .ssh

still no success

Maybe try without trailing forward slash:

        volumes:
            - './docker-web/SSH:/home/www-data/.ssh:ro'

I assume ./docker-web/SSH exists and is a directory.

It doesn’t look like internal user. Then you would see a username not an ID. The output looks like you managed to mount the files, but I don’t see in your first message what the first problem was. for example how you tested it. Usually private keys have to be owned by the user who uses them and readable only by that user. You didn’t share your base image, but based on the folders, the actual user running the processes in the container could be “www-data” with UID 33 if I remember correctly. Since you placed the ssh folder into the html folder, I assume you did it because that is the “home” of the user, which also points to www-data. If you share your base image, we can help better.

Your goal is still not clear to me. how are you trying to use the SSH keys? Your .ssh fodler still seems like mounted from the host, so I don’t see any problem with the mount.

What we should know before we can help

  • What is your base image?
  • In case you can’t or don’t want to share it, what is the user that needs the SSH keys? Run “id” in the container to show the ID and user name.
  • You could also share the home of that user whicih could be in the output of echo $HOME
  • What command you use to test the ssh settings?

Since you installed the openssh-client package, I assume you just want to use the ssh command, but you didn’t show any failing ssh command so far.

If you want to make sure the ssh command tries the right keys, you can just pass the private key like

ssh -i /home/www-data/.ssh/ssh_priv_key_path ...

Ot you can try verbose mode to see what the ssh client is trying to use and why it fails

ssh -vvv ...

UPDATE:

If you just need to make your user in the container to be the same as on the host, you can set the user in compose:

services:
  servicename:
    user: "2029:3100035"

Or use environment variables and get the uid and group id from those. The variables are either set as $UID and $GID already, or you can get the user on Linux or Mac with the id command:

UID=$(id)
GID=$(id -g)

thank you very much for you help and reply.
I have two images built :
nginx
php-8.1-fpm based on Alpine distro.
My goal is to be able to launch a ssh connection (sftp) from my container to a another server.
I try to use a ssh config mounted on my pc ./docker-web/SSH. The container’s user is www-data but i have not succeeded in applying the configuration on this user. Tomorrow, i will test your proposal and show you my dockerfile and docker-compose.yml
Thank you for your time and help

Here is my dockerfile :

FROM php:8.1-fpm-alpine
...
# Install SSH
RUN apk add --no-cache openssh-client  ca-certificates

My docker-compose :

services:
    web-nginx:
        image: nginx:stable-alpine
        container_name: web-nginx
        volumes:
	...
        ports:
            - '127.0.0.1:8086:80'

    web-php:
        image: php81wpe:latest
        build:
            context: .
            dockerfile: Dockerfile_php81
        container_name: web-php
        hostname: station-pagod
        user: www-data:1000
        extra_hosts:
            - 'host.docker.internal:host-gateway'
        environment:
            LANG: fr_FR
        volumes:
            - './docker-web/SSH:/home/www-data/.ssh:ro'

An extract of the different command that i’ve tried on my terminal :

/var/www/html $ id
uid=82(www-data) gid=1000 groups=1000
/var/www/html $ ls -al
total 12
drwxrwxrwt    1 www-data www-data      4096 Oct 14 15:34 .
drwxr-xr-x    1 root     root          4096 Oct  9 00:42 ..
/var/www/html $ ls -al /home/www-data/
total 20
drwxr-sr-x    1 www-data www-data      4096 Dec  4 08:59 .
drwxr-xr-x    1 root     root          4096 Oct  9 00:42 ..
-rw-------    1 www-data www-data        37 Dec  4 09:00 .ash_history
drwx------    2 2029     3100035       4096 Nov 25 13:48 .ssh
/var/www/html $ ssh nedtd301
hostkeys_find_by_key_hostfile: hostkeys_foreach failed for /home/www-data/.ssh/known_hosts: Permission denied
The authenticity of host 'nedtd301 (172.31.0.154)' can't be established.
ED25519 key fingerprint is SHA256:0ht7Z4MTrkxjz2TF9FTmVNpfDhPMloEW/DrsLJY2l9M.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Failed to add the host to the list of known hosts (/home/www-data/.ssh/known_hosts).
www-data@nedtd301's password:

In the SSH directory, i have a config file with user defined to connect to the remote server above and it is not my default docker user (www-data) but as you can see, this didn’t work. And i don’t know the user with the UID 2029.
www-data is the user coming with the php-conf i think.

It must be the user who created and owned the file on the host (outside the container). When you use a bind mount under the “volumes” section, the file or folder is just mounted from the original location to the container. You will access the exact same file from the container, so the owner and permissions remain the same. It doesn’t matter what “the user in the container”. There is no user in the container. There are user IDs and and processes can run on behalf of users with that user id. The actual username can be different inside and outside the container. It is just a name assigned to the ID in /etc/passwd, which is different in the container.

This is at least the usual behavior with the official Docker CE on Linux. You can run the “id” command on the host to see your user id and you can also run the following command in the SSH folder on the host:

ls -ln

This will show the user id and group id of the file instead of user name and group name.

If it is not the same as you can see in the container, thenthe next step will be figuring out what kind of Docker you have, but I haven’t seen any special behavior yet.

If the problem is the owner of the files, you have two options:

  • You change the owner on the host to match the ID of the www-data user that runs the ssh command
  • or you do what I recommended originally and set the user in the compose file, but that might not work if there is any process in the container that needs to run as www-data, which is likely when you are using PHP.

The most secure solution is changing the owner of the files on the host. Then you wil not be able to use it from the host, but it is better if the container has its own keys.

To change the owner, you would need a root user on the host. There are other cases as well, but I don’t want to overcomplicate this answer even more, so let’s see what you can find out about the files on the host and we continue from there.

Thank you very much for your help and your time.
I have root access on the host. I will test monday and send you my result.

Hi,
I realized that it is my UID and GID !!
I will try other test and i’ll keep you posted.

Hi,

So ! i have modified my setup.
I created a user on my host who match with the user in my container :

xxxxxxxxxxxxx:/appli/docker/docker-WPE/docker-web$ ls -ltr SSH
total 12
-rwxrwxrwx 1 edt_data edt_grp  399 nov.  25 11:53 id_rsa.pub
-r-------- 1 edt_data edt_grp 1678 nov.  25 11:53 id_rsa
-rw------- 1 edt_data edt_grp  111 déc.   3 08:52 config

In my dockerfile :

RUN addgroup -g 10001 edt_grp && \
    adduser -u 10000 -h /home/edt_data -G edt_grp -D edt_data

In my docker-compose :

services:
    web-nginx:
....

    web-php:
....
        user: edt_data
        volumes:
            - './docker-web/SSH:/home/edt_data/.ssh'

And it rocks !

User oracle/var/www/html 
$ ssh wp......01
The authenticity of host 'wp.....01 (XX.XX.XX.XX)' can't be established.
ED25519 key fingerprint is SHA256:o......4....LYo.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? ^C
/var/www/html $ ssh wp.....01
The authenticity of host 'wp......01 (XX.XX.XX.XX)' can't be established.
ED25519 key fingerprint is SHA256:o......4....LYo.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'wp.......01' (ED25519) to the list of known hosts.
Last login: Wed Dec 10 12:00:08 2025
[]oracle@wp......01:oracle 10.12.2025-14:57:11

1 Like