CygnusX1985
CygnusX1985

Reputation: 115

What does the -P option for "docker run" actually do?

I setup a pypiserver with docker for our team and ran into a problem, where publishing of packages didn't work. After reading the tutorial more carefully I saw, that -P .htpasswd packages was missing at the end of my docker run ... command.

Compare with the pypiserver documentation (last command in the docker section): https://pypi.org/project/pypiserver/#using-the-docker-image

docker run -p 80:8080 -v ~/.htpasswd:/data/.htpasswd pypiserver/pypiserver:latest -P .htpasswd packages

According to man docker run, the -P option should only receive the values false or true (not a list of files or even a single file) and it maps ports of the container to random ports of the host, that is clearly not happening in my use case, since docker port containername only outputs a single port map which I configured with the lowercase -p option.

So what is actually happening here? I first thought, that maybe the file list has nothing to do with the -P option (maybe it is just a toggle, that is automatically set to true if it appears in the command), but when I remove the file list I get the error:

> docker run -p 80:8080 -v ~/.htpasswd:/data/.htpasswd pypiserver/pypiserver:latest -P
usage error: option -P requires argument

Either I seriously misunderstand CLI interfaces or -P does something different as described in dockers manpage.

-P, --publish-all=true|false
          Publish all exposed ports to random ports on the host interfaces. The default is false.

       When set to true publish all exposed ports to the host interfaces. The default is false. If the operator uses -P (or -p) then Docker will make the exposed port accessible on the host and the ports will be available to any client that can reach the host.
       When using -P, Docker will bind any exposed port to a random port on the host within an ephemeral port range defined by /proc/sys/net/ipv4/ip_local_port_range. To find the mapping between the host ports and the exposed ports, use docker port(1).


Upvotes: 2

Views: 2003

Answers (1)

BMitch
BMitch

Reputation: 264306

You're looking in the wrong place. Yes, to docker run the -P option will publish all exposed ports to random high numbered ports on the host. However, before you get to that, the docker run command itself is order sensitive, and flags to docker run need to be passed in the right part of the command line:

docker run ${args_to_run} ${image_name} ${cmd_override}

In other words, as soon as docker sees something that is not an arg to run, it parses the next thing as an image name, and then the rest of the args become the new value of CMD inside the container.

Next, when you have an entrypoint defined in your container, that entrypoint is concatenated with the CMD value to form one command running inside the container. E.g. if entrypoint is /entrypoint.sh and you override CMD with -P filename then docker will run /entrypoint.sh -P filename to start your container.

Therefore you need to look at the pypiserver image docs to see what syntax their entrypoint expects:

 -P, --passwords PASSWORD_FILE

 Use apache htpasswd file PASSWORD_FILE to set usernames & passwords when
 authenticating certain actions (see -a option).
 To allow unauthorized access, use:
   -P . -a .

You can also dig into their repo to see they've set the entrypoint to:

ENTRYPOINT ["pypi-server", "-p", "8080"]

So with -P .htpasswd packages the command inside the container becomes:

pypi-server -p 8080 -P .htpasswd packages

Upvotes: 3

Related Questions