Infra

[Docker] 리눅스 환경에서 컨테이너 관리하고 실행하기

yerinpark 2024. 2. 16. 12:40

도커를 사용하여 여러 개의 컨테이너를 관리하고 실행해보았다.

이 실습은 세 개의 컨테이너를 사용한다.

 

  1. MySQL 컨테이너 (mysqldb): MySQL 데이터베이스를 실행하고 관리한다. fisa라는 데이터베이스에 activist, recipient, probono, probono_project라는 네 가지 테이블을 생성하고 데이터를 삽입한다.
  2. Oracle 컨테이너 (oracledb): Oracle 데이터베이스를 실행하고 관리한다. 이 컨테이너는 user01이라는 사용자와 관련된 설정을 사용하여 실행된다.
  3. Spring Boot 어플리케이션 컨테이너 (springbootapp): 스프링 부트 어플리케이션을 실행한다. 이 어플리케이션은 MySQL 데이터베이스와 연동하여 데이터를 조회하고 웹 페이지를 제공한다. 또한, 해당 어플리케이션은 도커 이미지로 빌드되며, 이 이미지는 springbootapp2로 태그되어 Docker Hub에 푸시된다.

 

프로젝트의 yml 설정

server:
  port: 8086 # server.port=80
  servlet:
    context-path: /------
    
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    password: ------
    # mysql container와 소통 가능한 설정, build 시 접속 문제 발생
    # build 시에 test로 인해 DB와 실제 접속도 확인하게 되는 상황을 skip해야 함.
    url: jdbc:mysql://mysqldb:3306/------?useSSL=false&allowPublicKeyRetrieval=true
    username: user01
  jpa:
    database: mysql
    database-platform: org.hibernate.dialect.MySQL8Dialect
    generate-ddl: true
    hibernate:
      ddl-auto: none
    show-sql: true
  mvc:        # jsp 사용을 위한 필수 설정, WEB-INF 폴더 직접 만들고, pom.xml에 설정, ProbonoController의 메소드 setViewName()확인하기
    view:
      prefix: /WEB-INF/
      suffix: .jsp

Port Forwarding

파일 구조

probono.sql 예시

username@servername:~/oracletest$ vi probono.sql

다음과 같은 방식으로 데이터를 넣어주었다.

-- Mysql 컨테이너에 dept table 생성 및 데이터 저장
USE fisa;

-- 재능기부 프로젝트
DROP TABLE IF EXISTS probono_project;

CREATE TABLE activist (
       activist_id              VARCHAR(20)  PRIMARY KEY,
       name                     VARCHAR(20) NOT NULL,
       password                 VARCHAR(20) NOT NULL,
       major                    VARCHAR(50) NOT NULL
);


ALTER TABLE probono_project AUTO_INCREMENT = 10000;

insert into activist values('giver1', '나의사', 'gp1', 'dermatology');

commit;

docker-compose.yml

docker-compose.yml 파일은 세 개의 서비스를 정의하고 각각에 대한 설정을 제공한다. 또한, Dockerfile은 스프링 부트 어플리케이션을 빌드하는 데 사용되며, 해당 어플리케이션은 MySQL 데이터베이스와 통합하여 실행된다.

version: '3'
services:
  oracle:
    container_name: oracledb
    image: oracleinanutshell/oracle-xe-11g:latest
    ports:
      - 1521:1521
      - 5500:5500
    environment:
      ORACLE_SID: ------
      ORACLE_PWD: ------
      ORACLE_CHARACTERSET: AL32UTF8
  db:
    container_name: mysqldb
    image: mysql:latest
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: ----
      MYSQL_DATABASE: ----
      MYSQL_USER: -----
      MYSQL_PASSWORD: -----

    networks:
      - spring-mysql-net
    healthcheck:
      test: ['CMD-SHELL', 'mysqladmin ping -h 127.0.0.1 -u ---- --password=$$MYSQL_ROOT_PASSWORD']
      interval: 10s
      timeout: 2s
      retries: 100

  app:
    container_name: springbootapp
    build:
      context: .
      dockerfile: ./Dockerfile

Dockerfile

FROM openjdk:17
COPY step03_probono-0.0.1-SNAPSHOT.jar app.jar
COPY probono.sql /docker-entrypoint-initdb.d/
HEALTHCHECK --interval=30s --timeout=30s --start-period=5s CMD curl -f http://localhost:8086/probono/index.html || exit 1
ENTRYPOINT [ "java", "-jar", "app.jar" ]

파일 세팅

username@servername:~$ docker compose --version
Docker version 24.0.5, build 24.0.5-0ubuntu1~22.04.1
username@servername:~$ cd oracletest/
username@servername:~/oracletest$ vi docker-compose.yml
username@servername:~/oracletest$ vi Dockerfile
username@servername:~/oracletest$ tree
.
├── docker-compose.yml
├── Dockerfile
└── step03_probono-0.0.1-SNAPSHOT.jar

0 directories, 3 files

확인

코드 실행 후, MySQL 데이터베이스와의 상호작용을 확인하기 위해 데이터베이스에 접속하여 activist 테이블의 데이터를 조회하는 등의 작업을 수행했다.

username@servername:~/oracletest$ docker ps -a
CONTAINER ID   IMAGE                                    COMMAND                  CREATED          STATUS                            PORTS                                                                                                    NAMES
------------   oracletest-app                           "java -jar app.jar"      35 seconds ago   Up 3 seconds (health: starting)   0.0.0.0:8080->8086/tcp, :::8080->8086/tcp                                                                springbootapp
------------   oracleinanutshell/oracle-xe-11g:latest   "/bin/sh -c '/usr/sb…"   36 seconds ago   Up 34 seconds                     0.0.0.0:1521->1521/tcp, :::1521->1521/tcp, 22/tcp, 8080/tcp, 0.0.0.0:5500->5500/tcp, :::5500->5500/tcp   oracledb
------------   mysql:latest                             "docker-entrypoint.s…"   36 seconds ago   Up 35 seconds (healthy)           0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                     mysqldb
username@servername:~/oracletest$ docker-compose ps -a
NAME            IMAGE                                    COMMAND                  SERVICE   CREATED          STATUS                             PORTS
mysqldb         mysql:latest                             "docker-entrypoint.s…"   db        43 seconds ago   Up 41 seconds (healthy)            0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp
oracledb        oracleinanutshell/oracle-xe-11g:latest   "/bin/sh -c '/usr/sb…"   oracle    43 seconds ago   Up 41 seconds                      0.0.0.0:1521->1521/tcp, :::1521->1521/tcp, 22/tcp, 8080/tcp, 0.0.0.0:5500->5500/tcp, :::5500->5500/tcp
springbootapp   oracletest-app                           "java -jar app.jar"      app       42 seconds ago   Up 10 seconds (health: starting)   0.0.0.0:8080->8086/tcp, :::8080->8086/tcp
username@servername:~/oracletest$ curl http://localhost:8080/------------/index.html
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1></body></html>username@servername:~/oracletest$ curl http://localhost:8080/probono/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>재능 기부</title>
</head>

<style>
        .waviy {
                position: relative;
                -webkit-box-reflect: below -20px linear-gradient(transparent, rgba(0,0,0,.2));
                font-size: 30px;
                width: 300px;
                height: 18px;
                padding: 20px 20px;
...

username@servername:~/oracletest$ docker ps -a
CONTAINER ID   IMAGE                                    COMMAND                  CREATED         STATUS                   PORTS                                                                                                    NAMES
------------   oracletest-app                           "java -jar app.jar"      6 minutes ago   Up 5 minutes (healthy)   0.0.0.0:8080->8086/tcp, :::8080->8086/tcp                                                                springbootapp
------------   oracleinanutshell/oracle-xe-11g:latest   "/bin/sh -c '/usr/sb…"   6 minutes ago   Up 6 minutes             0.0.0.0:1521->1521/tcp, :::1521->1521/tcp, 22/tcp, 8080/tcp, 0.0.0.0:5500->5500/tcp, :::5500->5500/tcp   oracledb
------------   mysql:latest                             "docker-entrypoint.s…"   6 minutes ago   Up 6 minutes (healthy)   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                     mysqldb
username@servername:~/oracletest$ docker-compose up
[+] Running 3/0
 ✔ Container mysqldb        Running                                                                         0.0s
 ✔ Container springbootapp  Running                                                                         0.0s
 ✔ Container oracledb       Running                                                                         0.0s
Attaching to mysqldb, oracledb, springbootapp
springbootapp  | 2024-02-16T02:41:39.147Z  INFO 1 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
springbootapp  | 2024-02-16T02:41:39.163Z  INFO 1 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
springbootapp  | 2024-02-16T02:41:39.199Z  INFO 1 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
springbootapp exited with code 0
springbootapp exited with code 143
mysqldb        | 2024-02-16T02:41:39.651515Z 0 [System] [MY-013172] [Server] Received SHUTDOWN from user <via user signal>. Shutting down mysqld (Version: 8.3.0).
mysqldb        | 2024-02-16T02:41:40.381190Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.3.0)  MySQL Community Server - GPL.
mysqldb        | 2024-02-16T02:41:40.387587Z 0 [System] [MY-015016] [Server] MySQL Server - end.
mysqldb exited with code 0
mysqldb exited with code 0
oracledb exited with code 0
username@servername:~/oracletest$ docker exec -it mysqldb mysql -u ------------ -p ------------ fisa
mysql: [Warning] Using a password on the command line interface can be insecure.
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.3.0 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| fisa               |
| information_schema |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)

mysql> show tables;
+-----------------+
| Tables_in_fisa  |
+-----------------+
| activist        |
| probono         |
| probono_project |
| recipient       |
+-----------------+
4 rows in set (0.00 sec)

mysql> select * from activist;
+-------------+-----------+----------+-------------+
| activist_id | name      | password | major       |
+-------------+-----------+----------+-------------+
| giver1      | 나의사 | gp1      | dermatology |
| giver2      | 오드리 | gp2      | culture     |
| giver3      | 키다리 | gp3      | mentor      |
+-------------+-----------+----------+-------------+
3 rows in set (0.00 sec)

mysql> username@servername:~/oracletest$

성공했을 때의 결과

docker-compose up 명령은 세 개의 컨테이너를 동시에 실행하며, 각 컨테이너는 정의된 환경 설정에 따라 초기화된다. 마지막으로, docker push 명령은 빌드된 어플리케이션 이미지를 Docker Hub에 푸시한다.

username@servername:~/oracletest$ docker-compose up
[+] Running 3/0
 ✔ Container oracledb       Created                                                                                                        0.0s
 ✔ Container mysqldb        Created                                                                                                        0.0s
 ✔ Container springbootapp  Created                                                                                                        0.0s
Attaching to mysqldb, oracledb, springbootapp

Dockerhub에 push하기

username@servername:~$ docker logs oracledb
Starting Oracle Net Listener.
Starting Oracle Database 11g Express Edition instance.
username@servername:~/oracletest$ docker buildx build -t springbootapp2:1.0 .
[+] Building 1.7s (9/9) FINISHED                                                                                     docker:default
username@servername:~/oracletest$ docker push ------------/springbootapp2:1.0
The push refers to repository [docker.io/------------/springbootapp2]
An image does not exist locally with the tag: ------------/springbootapp2
username@servername:~/oracletest$ docker run -p 8080:8086 --name springbootapp2 --network springboot-mysql-net -d springbootapp2:1.0
------------
username@servername:~/oracletest$ docker ps -a
CONTAINER ID   IMAGE                COMMAND               CREATED          STATUS                            PORTS                                       NAMES
------------   springbootapp2:1.0   "java -jar app.jar"   11 seconds ago   Up 9 seconds (health: starting)   0.0.0.0:8080->8086/tcp, :::8080->8086/tcp   springbootapp2
username@servername:~/oracletest$ docker images
REPOSITORY                        TAG       IMAGE ID       CREATED          SIZE

username@servername:~/oracletest$ docker push ------------/springbootapp2:1.0
The push refers to repository [docker.io/------------/springbootapp2]
An image does not exist locally with the tag: ------------/springbootapp2
username@servername:~/oracletest$ docker login
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
username@servername:~/oracletest$ docker push ------------/springbootapp2:1.0
The push refers to repository [docker.io/------------/springbootapp2]
An image does not exist locally with the tag: ------------/springbootapp2
username@servername:~/oracletest$ docker build -t springbootapp2:1.0 .
[+] Building 0.8s (8/8) FINISHED                                                                                     docker:default
                                                                    0.0s
username@servername:~/oracletest$ docker push ------------/springbootapp2:1.0
The push refers to repository [docker.io/------------/springbootapp2]
An image does not exist locally with the tag: ------------/------------
username@servername:~/oracletest$ docker tag springbootapp2:1.0 ------------/springbootapp2:1.0
username@servername:~/oracletest$ docker push ------------/springbootapp2:1.0
The push refers to repository [docker.io/------------/springbootapp2]