skip to Main Content

I have a docker-compose file which invokes an existing image and modifies it – the base image is from a parent project and not under my control. That base image has an EXPOSE 8080, but one of the primary ways I am modifying it is to change the port the service uses.

How can I negate/cancel that EXPOSE from the docker-compose.yaml?

(Note: Future versions of the parent project are likely to update the base image and our local project will modify those future versions, so the obvious solution of "make a fork which changes the Dockerfile" is not an option. Solutions that need some other local files to override the parent are fine, as long as it’s all local and not going to require resolving merge conflicts every time the base image updates.)

4

Answers


  1. You’re not the first one searching for this (see https://forums.docker.com/t/how-do-i-unexpose-ports/67863); the answer on Docker’s forum suggests that you can’t override the EXPOSE statement of a parent image, without as you already considered yourself forking the repo and changing it.

    It seems unlikely that this will be possible in the future either, looking at the Github issues https://github.com/moby/moby/issues/2210 and https://github.com/moby/moby/issues/3465; both from 2014 and neither with a relevant solution.

    Login or Signup to reply.
  2. As per the docs, the EXPOSE statement mostly functions as documentation and doesn’t do anything more

    The EXPOSE instruction does not actually publish the port. It
    functions as a type of documentation between the person who builds the
    image and the person who runs the container, about which ports are
    intended to be published. To actually publish the port when running
    the container, use the -p flag on docker run to publish and map one or
    more ports, or the -P flag to publish all exposed ports and map them
    to high-order ports.

    So while I agree that it’s annoying that there’s an incorrect EXPOSE statement in your image, I wouldn’t worry about it.

    Full documentation here: https://docs.docker.com/engine/reference/builder/#expose

    Login or Signup to reply.
  3. I’ve thought some more about this and I’ve come up with a way to do it. It removes the history of the base image completely, so maybe it’s a bit excessive.

    The idea is to copy everything from the original image into a scratch image. That way you’ll get rid of any EXPOSE statements in the original. You also lose all ENV, CMD, ENTRYPOINT etc., so you have to put those into the new image yourself.

    Here’s an example with Nginx. The original Nginx EXPOSEs port 80. The new one doesn’t.

    FROM nginx AS original
    FROM scratch
    COPY --from=original / /
    CMD ["nginx", "-g", "daemon off;"]
    
    Login or Signup to reply.
  4. Several options:

    1. Ignore it, since EXPOSE is documentation it doesn’t impact your running containers. Not ideal, but it’s what 99% of people do when faced with this.
    2. Build your own image. You can fork the upstream repository with the Dockerfile, add your change to delete the EXPOSE line, and maintain your own build. The downside is you’re maintaining the build, so you’ll need to periodically rebase your changes on whatever happens upstream.
    3. Modify the image config.

    I’ve been working on the latter. Here’s an example of pulling the image locally and then modifying it:

    $ regctl image copy nginx:latest localhost:5000/library/nginx:latest
    
    $ regctl image config localhost:5000/library/nginx:latest --format '{{jsonPretty .Config.ExposedPorts}}'
    {
      "80/tcp": {}
    }
    
    $ regctl image mod --expose-rm "80/tcp" localhost:5000/library/nginx:latest --create no-expose
    localhost:5000/library/nginx:no-expose
    
    $ regctl image config localhost:5000/library/nginx:no-expose --format '{{jsonPretty .Config.ExposedPorts}}'
    null
    

    Note that the above functionality is very new/experimental for regclient, to the point that I was just fixing a bug with the above example today, So the above needs an edge release or build off of main until 0.4.3 is released.

    Similar tools to regclient’s regctl include RedHat’s skopeo and Gooogle’s crane, but I don’t believe either allow this exact functionality yet.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search