8
votes

My use case is that I have multiple express micro-services that use the same middleware and I would like to create a different repo in the format of an npm module for each middleware.

Every repo is a private repo and can have a deploy key attached (can be different keys or the same)

All of this works OK locally. However when I try to use this with my docker-compose setup it fails on the npm install step, in the build stage.

Dockerfile

FROM node:alpine
RUN npm install --production
CMD npm start

docker-compose.yml

services:
   node-api:
        build:
            context: .
            dockerfile: Dockerfile

I understand this doesn't work because I don't have the deploy key I use on my local system in the Docker context.

I've looked around for a solution and none seem very easy/non hacky

  1. Copy the key in and squash (CONS: not sure how I do this in a docker-compose file)http://blog.cloud66.com/pulling-git-into-a-docker-image-without-leaving-ssh-keys-behind/

  2. Copy the key in on the build step and add to image. (CONS: Not very secure :( )

  3. Use the key as a build argument. (CONS: see 2)

  4. Dockerise something like https://www.vaultproject.io/ run that up first, add the key and use that within the node containers to get the latest key. (CONS: probably lots of work, maybe other issues?)

  5. Use Docker secrets and docker stack deploy and store the key in docker secrets (CON: docker stack deploy has no support for docker volumes yet. See here https://docs.docker.com/compose/bundles/#producing-a-bundle unsupported key 'volumes')

My question is what is the most secure possible solution that is automated (minimal manual steps for users of the file)? Time of implementation is less of a concern. I'm trying to avoid checking in any sensitive data while making it easy for other people to run this locally.

1
For 5th point, what do you mean with no support for volumes yet? because here: docs.docker.com/engine/swarm/secrets/#use-secrets-in-compose looks like they create volumesEdwin
should have been more specific, I mean in my compose file I use docker volumes docs.docker.com/engine/tutorials/dockervolumes for the containers to persist things like database files etc. I can put secrets in compose but volumes are not supported yet.Peter Grainger
I don't know if you mean this: docs.docker.com/compose/compose-file/… ? or something else?Edwin
docs.docker.com/compose/bundles/#producing-a-bundle I'm creating a bundle for the docker stack deploy (so I can use the secrets) when I create it I get the message unsupported key 'volumes', I believe you can set up volumes in a stack, just not through a compose filePeter Grainger
so you want a stack from a bundle, because a docker stack supports the volume and other things (as in github.com/docker/labs/blob/master/beginner/chapters/…)Edwin

1 Answers

12
votes

Let's experiment with this new feature: Docker multi stage build

You can selectively copy artifacts from one stage to another, leaving behind everything you don’t want in the final image.

The idea is to build a temporary base image, then start the build again only taking what you want from the previous image. It uses multiple FROM in the same Dockerfile:

FROM node as base-node-modules
COPY your_secret_key /some/path
COPY package.json /somewhere
RUN npm install <Wich use your key>

FROM node #yes again!
...
...
COPY --from=base-node-modules /somewhere/node_modules /some/place/node_modules
...
... # the rest of your Dockerfile
...

Docker will discard everything what you don't save from the first FROM.