Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save scollier/d68d64e2e5af616eb6f1 to your computer and use it in GitHub Desktop.
Save scollier/d68d64e2e5af616eb6f1 to your computer and use it in GitHub Desktop.

Private files in docker container

It is sometimes necessary to have files in a container that shouldn't ever end up in an image. These files are generally some form of private key or password that aren't allowed to be distributed. This document details a few usecases for such files and their requirements.

Use Cases

Private keys for packages

Not all package content is freely accessible on the network. For instance, using yum to download RHEL packages require that you provide x509 certificates and private keys to prove that you are entitled to download a particular product. In general such entitlements are tied to the computer running the program, and needs to somehow be transferred from the host to the container so that the yum instance in the container can access it.

In practice how this works is that a base image sets up a yum repository configuration file, /etc/yum.repos.d/my-corp.repo:

[my-corp-rpms]
name = Internal only RPMs for mycorp
baseurl = https://cdn.mycorp.com/content/rpms/
enabled = 1
gpgcheck = 1
gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mycom
sslverify = 1
sslcacert = /etc/secret/mycom-ca.pem
sslclientkey = /etc/secret/mycom-private-key.key
sslclientcert = /etc/secret/mycom-cert.crt

In this example we have 3 secret files: the ca root, and the private key/certificate pair. They are typically tied to the machine that will execute the container (at least that is how e.g. RHEL licenses work), and are should ideally to be supplied to all containers running on that machine automatically.

Private SSH keys

A container, like e.g. a continuos integration mechanism, might need to access e.g. a git repostory that is not publically available. To authenticate to this container it would need to supply a ssh private key.

This involves a file like $HOME/.ssh/id_rsa being available in the container. Generally this key is tied either to the user starting the container, or it is tied to the specific container instance. That means the file is read either from the users home directory, or is manually specified when starting the container instance.

API Keys

Many web services have require API keys that identify a particular user. A container that uses such api should ideally not ship the key with the container, as that makes distributing the image problematic. It is much better to ship the image without the key, and the apply the specific key (you might e.g. have a different key for testing) when starting the container.

Requirements

The private files can't be put in a base image, and in order avoid accidentally getting commited into an image they should not be stored in the normal container filesystem. They should instead work in a similar fashion to volumes.

In some cases the files come from the container host, but in other cases they come directly from the client, being uploaded via the REST api. We don't want to store these files unnecessarily long or unnecessarily make them available outside the container. Furthermore, volumes are not available during the build phase, which is required for some usecases.

This means using the existing volume feature as-is is not ideal, as they are not available during the build and require the files to be visible in the host filesystem.

Related issues and features

  • PR#3070 Add support for certificates for registry

    This is very similar to the above yum usecase, except it applies to the docker daemon itself when contacting a registry, rather than yum inside the container talking to a repo.

  • Index/registry authentication from $HOME/.dockercfg.

    This file contains login information that are automatically uploaded by the client to the docker daemon for all operations that may need to talk to the index, such as push/pull, etc. This is similar to e.g. the ssh key example above, except it applies to the daemon, and the authentication is not visible inside the container.

  • PR#5655 Always mount a /run tmpfs in the container

Proposal

First of all, each container gets a tmpfs mounted on /run that is not visible outside the container, and that dies with the container. This is similar to how /run works on a normal distribution, and forms the basis for allowing container files that are not part of any image.

Then during container initialization any registred host-specific private files are copied into a directory in /run, say /run/docker. Additionally any private data uploaded during docker run is placed in this directory, possibly overriding the host-specific files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment