3

I am trying to setup a windows nanoserver container as a sidecar container holding the certs that I use for SSL. Because the SSL cert that I need changes in each environment, I need to be able to change the sidecar container (i.e. dev-cert container, prod-cert container, etc) at startup time. I have worked out the configuration problems, but am having trouble using the same pattern that I use for Linux containers.

On linux containers, I simply copy my files into a container and use the VOLUMES step to export my volume. Then, on my main application container, I can use volumes_from to import the volume from the sidecar.

I have tried to follow that same pattern with nanoserver and cannot get working. Here is my dockerfile:

# Building stage
FROM microsoft/nanoserver

RUN mkdir c:\\certs
COPY . .

VOLUME c:/certs

The container builds just fine, but I get the following error when I try and run it. The dockerfile documentation says the following:

Volumes on Windows-based containers: When using Windows-based containers, the destination of a volume inside the container must be one of:

a non-existing or empty directory
a drive other than C:

so I thought, easy, I will just switch to the D drive (because I don't want to export an empty directory like #1 requires). I made the following changes:

# Building stage
FROM microsoft/windowservercore as build
VOLUME ["d:"]

WORKDIR c:/certs
COPY . .

RUN copy c:\certs d:

and this container actually started properly. However, I missed in the docs where is says:

Changing the volume from within the Dockerfile: If any build steps change the data within the volume after it has been declared, those changes will be discarded.

so, when I checked, I didn't have any files in the d:\certs directory.

So how can you mount a drive for external use in a windows container if, #1 the directory must be empty to make a VOLUME on the c drive in the container, and use must use VOLUME to create a d drive, which is pointless because anything put in there will not be in the final container?

Mike
  • 1,718
  • 3
  • 30
  • 58

1 Answers1

2

Unfortunately you cannot use Windows containers volumes in this way. Also this limitation is the reason why using database containers (like microsoft/mssql-server-windows-developer) is a real pain. You cannot create volume on non-empty database folder and as a result you cannot restore databases after container re-creation.

As for your use case, I would suggest you to utilize a reverse proxy (like Nginx for example). You create another container with Nginx server and certificates inside. Then you let it handle all incoming HTTPS requests, terminate SSL/TLS and then pass request to inner application container using plain HTTP protocol. With such deployment you don't have to copy and install HTTPS certificates to all application containers. There is only one place where you store certificates and you can change dev/test/etc certificates just by using different Nginx image versions (or by binding certificate folder using volume).

UPDATE:

Also if you still want to use sidecar container you can try one small hack. So basically you will move this operation

COPY . .

from build time to runtime (after container starts). Something like this:

FROM microsoft/nanoserver

RUN mkdir c:\\certs_in
RUN mkdir c:\\certs_out

VOLUME c:/certs_out
CMD copy "C:\certs_in" *.*  "D:\certs_out"
Ghost Master
  • 442
  • 4
  • 12