GPG version: 2.2.23
Docker version 20.10.5

I am playing around with GPG on my laptop and trying to reuse it inside docker container.

The docker container is simply a PHP-FPM alpine image. I have simple PHP CLI tool which encrypt/decrypts data with GPG. I exported the GPG from host and imported it inside container. The problem though, I always need to provide passphrase for PHP to decrypt the data. I would like to avoid passphrase in container for sake of security.

Further I discovered the gpg-agent with gpg-preset-passphrase and preconfigured it inside the container, but later on found that this isn't optimal, because once I restart the container or destroy it, I will need to start gpg-agent and set passphrase again.

So, I was wondering, is there a way to pass gpg-agent with cached passphrase inside docker and so docker would reuse it to encrypt/decrypt the data?

I know there is possibility to reuse ssh-agent inside docker, but couldn't really find a way to do the same for GPG.

Or maybe there is a better/secure way of doing it?

1 Answer 1


I would say the resolution was very simple.


First of all, you need to start gpg-agent:

gpg-agent --verbose --daemon --log-file /tmp/gpg-agent.log --allow-preset-passphrase --default-cache-ttl=31536000

This will start gpg-agent in background. You can verify that it is running:

ps aux | grep gpg

Now you need to use gpg-preset-passphrase to preset passphrase for the private key. gpg-preset-passphrase is not located in the /usr/local/bin, so you need to find it:

sudo find / -name gpg-preset-passphrase

In my case it was /usr/local/Cellar/gnupg/2.3.1_1/libexec/gpg-preset-passphrase, so now run the following command to find out private KEYID:

gpg-connect-agent 'keyinfo --list' /bye

Sample output:

S KEYINFO 4B86D9FBE0D9617C6EB4B42015C9B2AC8XXXXXXX D - - - P - - -
S KEYINFO 8960D3408E09A1A111AA862DBFB1B16CFXXXXXXX D - - - P - - -

In my case it is two keys, choose one of the KEY IDs.

echo "your-secret-passphrase" | /your/path/to/gpg-preset-passphrase --verbose --preset 4B86D9FBE0D9617C6EB4B42015C9B2AC8XXXXXXX

Replace your-secret-passphrase with your password, /your/path/to/ with your path and 4B86D9FBE0D9617C6EB4B42015C9B2AC8XXXXXXX with your own KEYID.

Now run the following command again to verify that passphrase was set successfully:

gpg-connect-agent 'keyinfo --list' /bye

If you see "1" near the KEYID you've chosen, it means passphrase set successfully.

Let's verify by doing encrypt and decrypt:

echo "hello" | gpg --armor --encrypt --recipient [email protected] | gpg --decrypt

Replace [email protected] with your email.

GPG Agent Forwarding via SSH

Add the following to your ~/.ssh/config

Host gpgtunnel
    User user
    HostName server-ip
    Port 22
    RemoteForward /root/.gnupg/S.gpg-agent /home/user/.gnupg/S.gpg-agent
    IdentityFile ~/.ssh/id_rsa

RemoteForward has the following signature: <remote path> <local path>. You can find location of local path by running:

gpgconf --list-dir agent-extra-socket

ssh to you server and find remote path by running:

gpgconf --list-dir agent-socket

Some note about S.gpg-agent vs S.gpg-agent.extra. S.gpg-agent allows to do export of the private key and other manipulation with keys, where is S.gpg-agent.extra is a very limit version which allows only encrypt/decrypt operation.

Now you need to export public key to remote sever, you can use the following command:

gpg --export [email protected] | ssh -p 22 user@remote-server gpg --import

Replace [email protected] with your GPG email.

Ensure you have imported public key successfully:

ssh -p 22 user@remote-server gpg -k


Now try to run ssh gpgtunnel and do encrypt/decrypt on the server. Now server should be able to reuse your local gpg-agent socket.

echo "hello" | gpg --armor --encrypt --recipient [email protected] | gpg --decrypt

If for some reason this doesn't work, you may run the following SSH command from your local computer:

ssh -fNT gpgtunnel

This will put SSH to background (-f flag). Now ssh gpgtunnel normally and retry encrypt/decrypt command from above again.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .