Search code examples
docker

Does "ports" on docker-compose.yml have the same effect as EXPOSE on Dockerfile?


Does declaring on a docker-compose.yml:

ports:
 - "3306:3306"

and on Dockerfile:

EXPOSE 3306

have the same effect?


Solution

  • The ports directive in docker-compose.yml and the EXPOSE instruction in a Dockerfile serve different purposes and do not have the same effect.

    Dockerfile: EXPOSE 3306

    Container
    +-----------------+
    |                 |
    |   Application   |
    |      Port       | --> 3306 (EXPOSED, not accessible from host by default)
    |                 |
    +-----------------+
    

    That instruction is a way of documenting which ports the container listens on at runtime. It does not actually publish the port.
    It serves as a form of documentation and is used by the docker run -P command to allocate a random high-numbered port on the host and map it to the exposed port.

    docker-compose.yml: ports: - "3306:3306"

    Host System
    +-----------------+      +-----------------+
    |                 |      |                 |
    |   Host Port     | <--> |   Container     |
    |      3306       | <--> |      Port       | --> 3306 (Accessible from host)
    |                 |      |                 |
    +-----------------+      +-----------------+
    

    That directive actually maps the port on the host to the port in the container.
    "3306:3306" means map port 3306 on the host to port 3306 in the container.

    In this setup, the EXPOSE directive in the Dockerfile is optional since docker-compose.yml is already mapping the ports. The main effect of EXPOSE is for documentation and compatibility with certain commands and orchestrators that might use this information.