As a memorandum
I wanted to organize how to write docker-compose.yml and its outline once, so I will write it.
-Host OS: Windows 10 Home ・ Guest OS: wsl2 Ubuntu20.04 ・ Docker ver19.03 ・ Docker Compose ver1.25.0
In this article, the following directory structure is taken as an example. (I referred to this article.)
. | ├── infra │ ├── mysql │ │ ├── Dockerfile │ │ └── my.cnf │ ├── nginx │ │ └── default.conf │ └── php │ ├── Dockerfile │ └── php.ini ├── docker-compose.yml └── backend └── Directory to install Laravel
・ Application server ・ Web server -Db server
It is a configuration to build a LEMP architecture consisting of three layers. In the original article, laravel is adopted as the PHP framework, but this time it is not dealt with because the purpose is to organize the knowledge of docker-compose.yml.
The contents of docker-compose.yml are as follows.
version: "3" services: app: build: ./infra/php volumes: - ./backend:/work depends_on: - web web: image: nginx:1.18-alpine ports: - "10080:80" volumes: - ./backend:/work - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - db working_dir: /work db: build: ./infra/mysql volumes: - db-store:/var/lib/mysql volumes: db-store:
docker-compose.yml is written in a file format called yml (yaml). For yml, you should first keep the following in mind.
-Express the hierarchical structure with indentation. In order to ensure readability, one layer is often represented by two indents. -The --at the beginning of the line represents an array. --In the same hierarchy are elements of the same array. -Descriptions such as key: value represent hashes. It is necessary to put a half-width space after the :.
build: Defined when generating an image from a Dockerfile. .. Describe the file path of Dockerfile in value. (It doesn't matter whether it's a relative path or an absolute path. Also, docker compose looks for a file named Dockerfile in the described file path, so you can omit Dockerfile.)
app: build: ./infra/php
In this case, the image that will be the basis of the app container will be created from the Dockerfile in ./infra/php.
image: Specifies the base image on which the container is based. For example, if you want to use the official image as it is, define this instead of build.
web: image: nginx:1.18-alpine
Here, the web container is generated from the official image of nginx.
ports: Specifies the port that the container exposes. The format is "Host side port number: Container side port number".
web: image: nginx:1.18-alpine ports: - "10080:80"
In this example, port 10080 on the host side and port 80 on the container side are associated. (Port 80 is the default port number for nginx)
Although it is not defined this time, if you do not expose the port of the container to the host side and open it only to another container that cooperates, use expose instead of ports.
Defines container dependencies.
web: image: nginx:1.18-alpine ports: - "10080:80" volumes: - ./backend:/work - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf depends_on: - db
The above example defines that the web container depends on the db container. Specifically, the order is defined that the db container is activated and then the web container is activated.
However, it only controls the order of container start, and the web server does not wait until the db server on the container is ready.
If you want to make such specifications, you need to take measures on the application side.
Mount the volume in the container. I think it's a term that many people don't understand, so the following is a brief explanation.
-Volume: A data storage area for retaining data even after the container is destroyed. Simply put, the directory that stores the data in the container -Mount: To load an external file into linux.
Roughly speaking, it's about Shioume, "Containers are not suitable for long-term storage, so let's store them in an external OS." (I think it's inconvenient to go into a container and edit php with vim ...)
volumes are defined in the format of "mountable host side directory: container side directory".
app: build: ./infra/php volumes: - ./backend:/work
Here, the work directory (and the files and directories under it) in the app container is mounted on the ./backend directory on the host side.
There are many other keys that can be defined, but for now, I've summarized the basic ones. First of all, I want to understand build and volumes.