1. 개요

컨테이너는 장점이 많기 때문에 IT 업계에서 가장 뜨거운 논의 주제입니다. 조직은 놀라운 속도로 비즈니스를 위해 컨테이너 기반 솔루션을 채택하고 있습니다. 451 Research에 따르면 애플리케이션 컨테이너 시장은 향후 몇 년 동안 4배 더 커질 것이라고 합니다.

오늘날 우리는 MySQL, MongoDB , PostgreSQL 등과 같은 데이터베이스를 컨테이너화된 형태로 보유하고 있습니다. 그러나 이 기사에서는 MySQL 컨테이너를 설정하고 실행하기 위한 옵션을 살펴봅니다. 시작하려면 기존 MySQL 데이터베이스를 백업합니다. 다음으로, YAML 형식으로 컨테이너 구성을 빌드하고 애플리케이션 컨테이너 스택을 함께 가져오기 위한 오픈 소스 툴킷인 docker-compose를 사용하여 실행합니다.

더 이상 고민하지 않고 핵심 세부 사항으로 들어가 보겠습니다.

2. MySQL 컨테이너 구성 구축

이 섹션에서는 docker-compose 도구를 사용하여 MySQL 컨테이너를 빌드합니다 . 그러나 YAML은 현재 경로의 기본 구성으로 Dockerfile의 이미Map 사용합니다.

2.1. 도커 작성

먼저 버전서비스 태그를 사용하여 YAML 파일을 생성해 보겠습니다 . YAML 파일의 버전 태그 아래에 파일 형식 버전을 정의합니다 . MySQL 서비스는 컨텍스트에서 정의하는 Dockerfile의 이미지 정보를 사용합니다.

또한 .env 파일 에서 환경 변수로 정의된 기본 인수를 사용하도록 도구에 지시합니다 . 마지막으로 포트 태그는 컨테이너와 호스트 머신 포트 3306을 바인딩합니다 . MySQL 서비스를 불러오는 데 사용하는 docker-compose YAML 파일 의 내용을 살펴보겠습니다 .

# cat docker-compose.yml
version: '3.3'
services:
### MySQL Container
  mysql:
    build:
      context: /home/tools/bael/dung/B015
      args:
        - MYSQL_DATABASE=${MYSQL_DATABASE}
        - MYSQL_USER=${MYSQL_USER}
        - MYSQL_PASSWORD=${MYSQL_PASSWORD}
        - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    ports:
      - "${MYSQL_PORT}:3306"

2.2. 도커파일 생성

내부적으로 docker-compose는 지정된 경로의 Dockerfile을 사용하여 이미지를 빌드하고 MySQL 환경을 설정합니다. Dockerfile은 DockerHub에서 이미지를 다운로드하고 정의된 변수로 컨테이너를 가동합니다.

# cat Dockerfile
FROM mysql:latest

MAINTAINER baeldung.com

RUN chown -R mysql:root /var/lib/mysql/

ARG MYSQL_DATABASE
ARG MYSQL_USER
ARG MYSQL_PASSWORD
ARG MYSQL_ROOT_PASSWORD

ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD

ADD data.sql /etc/mysql/data.sql

RUN sed -i 's/MYSQL_DATABASE/'$MYSQL_DATABASE'/g' /etc/mysql/data.sql
RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d

EXPOSE 3306

이제 아래 Dockerfile 스니펫에 제공된 모든 지침을 살펴보겠습니다.

  • FROM – 유효한 Dockerfile은 이미지 이름과 버전 태그를 설명하는 FROM 문으로 시작합니다 . 우리의 경우 최신 태그가 있는 mysql 이미지를 사용합니다 .
  • MAINTAINER – 작성자 정보를 docker inspect 를 통해 볼 수 있는 컨테이너의 메타데이터로 설정합니다 .
  • RUN – mysql 이미지 위에서 명령을 실행하면 이후에 새 레이어가 형성됩니다. 결과 이미지는 커밋되어 Dockerfile에 정의된 다음 단계에 사용됩니다.
  • ARG – 빌드 시간 동안 변수를 전달합니다. 여기에서는 4개의 사용자 변수를 빌드 인수로 전달합니다.
  • ENV – $ 기호를 사용하여 Dockerfile의 환경 변수를 나타냅니다. 위 스니펫에서는 4개의 변수를 사용합니다.
  • 추가 – 빌드 시간 동안 나중에 사용할 수 있도록 파일을 컨테이너에 추가합니다.
  • EXPOSE – Docker 컨테이너 외부에서 서비스를 사용할 수 있도록 합니다.

2.3. 환경 설정

또한 현재 경로에 환경 변수 파일을 .env 로 생성할 수 있습니다. 이 파일에는 작성 파일과 관련된 모든 변수가 포함되어 있습니다.

# cat .env
MYSQL_DATABASE=my_db_name
MYSQL_USER=baeldung
MYSQL_PASSWORD=pass
MYSQL_ROOT_PASSWORD=pass
MYSQL_PORT=3306

2.4. MySQL 백업 파일

데모를 위해 기존 데이터베이스 테이블에서 백업을 가져오겠습니다. 여기서는 동일한 Customers 테이블을 data.sql 파일을 통해 자동으로 MySQL 컨테이너로 가져옵니다 .

아래에는 요청된 테이블에서 데이터를 가져오는 SELECT 쿼리 를 사용하여 테이블 데이터를 보여줍니다 .

mysql> select * from Customers;
+--------------+-----------------+---------------+-----------+------------+---------+
| CustomerName | ContactName     | Address       | City      | PostalCode | Country |
+--------------+-----------------+---------------+-----------+------------+---------+
| Cardinal     | Tom B. Erichsen | Skagen 21     | Stavanger | 4006       | Norway  |
| Wilman Kala  | Matti Karttunen | Keskuskatu 45 | Helsinki  | 21240      | Finland |
+--------------+-----------------+---------------+-----------+------------+---------+
2 rows in set (0.00 sec)

MySQL RDBMS 패키지의 일부인 mysqldump 유틸리티는 데이터베이스의 모든 데이터를 텍스트 파일로 백업하는 데 사용됩니다. 인라인 인수와 함께 간단한 명령을 사용하여 MySQL 테이블을 빠르게 백업할 수 있습니다.

  • -u: MySQL 사용자 이름
  • -p: MySQL 비밀번호
# mysqldump -u [user name] –p [password] [database_name] > [dumpfilename.sql]

# mysqldump -u root -p my_db_name > data.sql
Enter password:

높은 수준에서 백업 파일은 선택한 데이터베이스에서 Customers 라는 테이블을 삭제 하고 여기에 모든 백업 데이터를 삽입합니다.

# cat data.sql
-- MySQL dump 10.13  Distrib 8.0.26, for Linux (x86_64)
...
... output truncated ...
...
DROP TABLE IF EXISTS `Customers`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `Customers` (
  `CustomerName` varchar(255) DEFAULT NULL,
...
... output truncated ...
...
INSERT INTO `Customers` VALUES ('Cardinal','Tom B. Erichsen','Skagen 21','Stavanger','4006','Norway'),('Wilman Kala','Matti Karttunen','Keskuskatu 45','Helsinki','21240','Finland');
/*!40000 ALTER TABLE `Customers` ENABLE KEYS */;
UNLOCK TABLES;
...
... output truncated ...
...
-- Dump completed on 2022-07-28  1:56:09

단, 데이터베이스 생성 및 제거는 생성된 덤프 파일에서 관리되지 않습니다. 존재하지 않는 경우 데이터베이스를 생성하는 data.sql 파일 에 아래 스니펫을 추가합니다 . 데이터베이스와 테이블을 모두 관리하여 원을 완성합니다. 마지막으로 USE 명령 으로 생성된 데이터베이스도 사용합니다 .

--
-- Create a database using `MYSQL_DATABASE` placeholder
--
CREATE DATABASE IF NOT EXISTS `MYSQL_DATABASE`;
USE `MYSQL_DATABASE`;

현재 디렉토리 구조는 다음과 같습니다.

# tree -a
.
├── data.sql
├── docker-compose.yml
├── Dockerfile
└── .env

3. MySQL 서버 컨테이너 가동

이제 docker-compose를 통해 컨테이너를 가동할 준비가 모두 끝났습니다 . MySQL 컨테이너를 불러오려면 docker-compose up 을 실행해야 합니다 .

출력 라인을 훑어보면 MySQL 이미지 위에 각 단계에서 새 레이어를 형성하는 것을 볼 수 있습니다 .

그런 다음 데이터베이스를 생성하고 data.sql 파일에 지정된 데이터를 로드합니다.

# docker-compose up
Building mysql
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM mysql:latest
 ---> c60d96bd2b77
Step 2/15 : MAINTAINER baeldung.com
 ---> Running in a647bd02b91f
Removing intermediate container a647bd02b91f
 ---> fafa500c0fac
Step 3/15 : RUN chown -R mysql:root /var/lib/mysql/
 ---> Running in b37e1d5ba079

...
... output truncated ...
...

Step 14/15 : RUN cp /etc/mysql/data.sql /docker-entrypoint-initdb.d
 ---> Running in 34f1d9807bad
Removing intermediate container 34f1d9807bad
 ---> 927b68a43976
Step 15/15 : EXPOSE 3306
 ---> Running in defb868f4207
Removing intermediate container defb868f4207
 ---> 6c6f435f52a9
Successfully built 6c6f435f52a9
Successfully tagged b015_mysql:latest
Creating b015_mysql_1 ... done
Attaching to b015_mysql_1
mysql_1  | 2022-07-28 00:49:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.26-1debian10 started.

...
... output truncated ...
...

mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Creating database my_db_name
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Creating user baeldung
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: Giving user baeldung access to schema my_db_name
mysql_1  |
mysql_1  | 2022-07-28 00:49:16+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/data.sql
...
... output truncated ...
...

-d 옵션을 사용하여 분리 모드에서 컨테이너를 실행할 수 있습니다 .

# docker-compose up -d
Building mysql
Sending build context to Docker daemon  7.168kB
Step 1/15 : FROM mysql:latest
 ---> c60d96bd2b77
...
... output truncated ...
...
Step 15/15 : EXPOSE 3306
 ---> Running in 958e1d4af340
Removing intermediate container 958e1d4af340
 ---> c3516657c4c8
Successfully built c3516657c4c8
Successfully tagged b015_mysql:latest
Creating b015_mysql_1 ... done
#

4. MySQL 클라이언트 준비

MySQL 서버에 쉽게 액세스하려면 클라이언트를 설치해야 합니다 . 필요에 따라 호스트 머신이나 다른 머신 또는 서버 컨테이너와 IP 연결이 가능한 컨테이너에 클라이언트를 설치할 수 있습니다.

$ sudo apt install mysql-client -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
mysql-client is already the newest version (5.7.37-0ubuntu0.18.04.1).
...
... output truncated ...
...

이제 MySQL 클라이언트의 설치 경로와 버전을 추출해 보겠습니다.

$ which mysql
/usr/bin/mysql
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.37, for Linux (x86_64) using  EditLine wrapper

5. 서버 클라이언트 통신

클라이언트 애플리케이션을 사용하여 배포된 MySQL 서버에 액세스할 수 있습니다. 이 섹션에서는 클라이언트를 통해 MySQL 서버에 액세스하는 방법을 살펴보겠습니다.

docker ps 명령을 사용하여 생성된 컨테이너 ID 및 상태를 살펴보겠습니다 .

# docker ps | grep b015_mysql
9ce4da8eb682   b015_mysql                "docker-entrypoint.s…"   21 minutes ago   Up 21 minutes         0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                                    b015_mysql_1

다음으로 설치된 클라이언트 서비스를 사용하여 데이터베이스에 액세스하기 위한 컨테이너 IP 주소를 가져오겠습니다. docker inspect 명령을 실행하면 컨테이너에 대한 자세한 정보가 JSON 형식으로 표시됩니다. 결과 JSON에서 필드를 선택할 수도 있습니다. 여기에서는 range.NetworkSettings.Networks -> IPAddress 에서 IP 주소를 가져옵니다 .

# docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' 9ce4da8eb682
172.19.0.2

그런 다음 클라이언트를 사용하여 구성된 호스트 및 포트 정보를 사용하여 MySQL Server에 로그인할 수 있습니다.

# mysql -h 172.17.0.2 -P 3306 --protocol=tcp -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
...
... output truncated ...
...
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| my_db_name         |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
mysql> use my_db_name
...
... output truncated ...
...

Database changed

여기에서 데이터가 data.sql 파일에서 자동으로 복원되는 것을 볼 수 있습니다.

mysql> select * from Customers;
+--------------+-----------------+---------------+-----------+------------+---------+
| CustomerName | ContactName     | Address       | City      | PostalCode | Country |
+--------------+-----------------+---------------+-----------+------------+---------+
| Cardinal     | Tom B. Erichsen | Skagen 21     | Stavanger | 4006       | Norway  |
| Wilman Kala  | Matti Karttunen | Keskuskatu 45 | Helsinki  | 21240      | Finland |
+--------------+-----------------+---------------+-----------+------------+---------+
2 rows in set (0.00 sec)

이제 기존 데이터베이스 테이블에 행을 몇 개 더 추가해 보겠습니다. INSERT 쿼리를 사용하여 테이블에 데이터를 추가합니다.

mysql> INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) VALUES ('White Clover Markets', 'Karl Jablonski', '305 - 14th Ave. S. Suite 3B', 'Seattle', '98128', 'USA');
Query OK, 1 row affected (0.00 sec)

복원된 테이블에도 새 행을 성공적으로 삽입했습니다. 축하해요! 결과를 보자:

mysql> select * from Customers;
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
| CustomerName         | ContactName     | Address                     | City      | PostalCode | Country |
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
| Cardinal             | Tom B. Erichsen | Skagen 21                   | Stavanger | 4006       | Norway  |
| Wilman Kala          | Matti Karttunen | Keskuskatu 45               | Helsinki  | 21240      | Finland |
| White Clover Markets | Karl Jablonski  | 305 - 14th Ave. S. Suite 3B | Seattle   | 98128      | USA     |
+----------------------+-----------------+-----------------------------+-----------+------------+---------+
3 rows in set (0.00 sec)

또는 MySQL 서버 컨테이너는 MySQL 클라이언트 설치와 함께 제공됩니다. 그러나 테스트 목적으로 컨테이너 내에서만 사용할 수 있습니다. 이제 Docker 컨테이너에 로그인하고 기본 MySQL 클라이언트를 사용하여 MySQL 서버에 액세스해 보겠습니다.

docker exec 명령은 컨테이너 ID를 사용하여 실행 중인 컨테이너에 로그인하는 데 도움이 됩니다. -i 옵션은 STDIN을 열어두고 -t는 pseudo-TTY를 할당하며 마지막으로 /bin/bash는 BASH 프롬프트에 표시됩니다.

# docker exec -it 9ce4da8eb682 /bin/bash
root@9ce4da8eb682:/# mysql -h localhost -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
...
... output truncated ...
...
mysql>

6. 결론

요약하면 docker-compose를 사용하여 MySQL 서버 컨테이너를 불러오는 단계에 대해 논의했습니다 . 또한 백업 파일에서 데이터베이스와 테이블을 자동으로 복원했습니다. 또한 복원된 데이터에 액세스하고 일부 CRUD 작업을 수행했습니다.

res – REST with Spring (eBook) (everywhere)