Doubts about the Docker-Compose and Dockerfile configuration

Asked

Viewed 1,060 times

1

I went up a small development environment. There are 2 containers:

  • mysql (mysql:5.7)
  • web (php:7.1-apache)

My question is in a configuration parameter of Docker-Compose.yml and Dockerfile respectively:

  • ports
  • EXPOSE

What’s the difference between the two?

Docker-Compose.yml

version: "3.3"
services:
  mysql:
    container_name: mysql
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: SENHA_AQUI
      MYSQL_DATABASE: webapp
      MYSQL_USER: root
      MYSQL_PASSWORD: senha_aqui
    restart: always
    ports:
      - 3306:3306

  web:
    container_name: web
    image: web_dev
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./htdocs/:/var/www
      - ./apache/:/etc/apache2/sites-available/
    working_dir: /var/www
    depends_on:
      - mysql
    links:
      - mysql
    restart: always
    ports:
      - 80:80

I resolved by

Dockerfile:

FROM php:7.1-apache

MAINTAINER Fabio J L Ferreira <[email protected]>

RUN apt-get update && apt-get install -y curl unzip git npm && curl -sL https://deb.nodesource.com/setup_6.x | bash - && apt-get install -y nodejs

COPY php.ini /usr/local/etc/php/

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer

RUN rm -rf /var/lib/apt/lists/* /tmp/*

2 answers

1


As you mentioned the difference begins in the "scope", where each one is applied. EXPOSE is in the scope of the image, in the Dockerfile while port in the creation of container, either in the Compose file atraveś do ports, docker-compose run with the parameters -p/--publish=[]/--service-ports or without commie using docker create or docker run and the parameter -p/--publish/-P/--publish-all.

So, despite the different forms, we conceptually have the difference in the image and we containers. In creating the image EXPOSE means that the service(s) in the container "listen" on certain door(s), regardless of whether the door in question will be published or not, and serve as instruction to whom will use the image, stating which doors can be posted securely.

As an example, if I have Dockerfile to create an image EXPOSURE something like EXPOSE 80 means that, regardless of the form of container of EXPOSURE, this door may be accessible among others containers of the same network.

In summary, regarding the exhibition/publication of doors:

  • unused EXPOSE and neither -p (or other commented variations): the door(s) of the running service will not be accessible from anywhere, except within itself container;
  • using EXPOSE and -p (or other commented variations): a(s) port(s) specified in Dockerfile will be (on) accessible(is) both BETWEEN containers And through the host;
  • using only EXPOSE: a(s) port(s) specified(s) in Dockerfile will be (no) accessible(is) BETWEEN containers on the same network, but not through host

Also, if you use -p, but did not use EXPOSE, Docker will implicitly make a EXPOSE. This is because if you are opening the door publicly then it can be accessible among the containers also.

Finally, there is the expose in the scope of commie which in this case means that the door will be available to the services of commie, but are not published for the machine host.

  • I understood in my case how I am using ports in Docker-Compose.yml I fall into this scenario: Also, if you use -p but you do not use EXPOSE, Docker implicitly will do an EXPOSE. This is because if you’re opening the door publicly then it can be accessible between containers as well. Right?

  • Exactly, checking the status you observe the behavior well. As good practice I like to use the EXPOSE, especially when the image will be distributed, it is clear to the user what is exposed

  • When you say it becomes clear, are you referring that when inspecting the image, even without Dockerfile it is possible to see the exposed doors? Also, if you use EXPOSE, I don’t need the reference (port) in Docker-Compose.yml?

    1. did not understand this question; 2. this, does not need, between containers on the same network the ports are accessible - standard when commie, but not through the machine host.
  • I understood. To end this post I have one last question, when adding EXPOSE to Dockerfile I am generating a new layer?

  • 1

    Yes, any Docker instruction when building an image generates a layer. Use docker history <sua_imagem> see all the layers of your images.

Show 1 more comment

0

In Docker each container by default has a network interface, virtual and own. This means that each container gets an internal IP.

EXPOSE is metadata that explains to consumers that their application or service exposes port(s). Note, it explains, but does nothing. The only practical function is to allow in the DOCKER RUN/CREATE subcommand you can use the -P parameter to make PORT BIND dynamically, according to the free ports on your host.

Every container, by default, has all its ports released which means that in the Container IP, ports you set in EXPOSE or not, can be accessed. Containers in the same bridge network can access other containers and communicate with any port of these, regardless of the previous existence of a EXPOSE definition.

PORTS, is the Docker-Compose configuration for the PORT BIND, which causes a bridge between the host and the container to be made for specified ports.

Finally, being pragmatic: EXPOSE is not useful for anything, except to inform which ports your container will use. No process or mechanism validates or relies on this to do anything except the -P case, as stated in the previous paragraph. But it is good practice, and should not be ignored when creating images. It is important to make clear which doors will be used, this facilitates, and often helps to understand some coupling problems, for example.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.