본문 바로가기
AWS Cloud School 8기/도커(docker)

docker compose/ 자동 재시작 스크립트/ 2번 기본 vim 편집기

by YUNZEE 2025. 3. 30.
728x90

실습

* docker0 인터페이스 자동 재시작 스크립트

더보기

 

sudo tee /root/check_ip_and_restart_docker.sh<<EOF
#!/bin/bash
 
if ! ip add | grep -q 172.17; then
	systemctl restart docker
fi
EOF

root@host:~# chmod 777 /root/check_ip_and_restart_docker.sh 
root@host:~# crontab -e

- select-editor 2번 기본 vim 편집기

 

* * * * * /root/check_ip_and_restart_docker.sh

vi ~/.vimrc

- yaml 두 칸 들여 쓰기, 엔터 치면 바로 아래서 입력되도록

" Enable file type detection
filetype on

" Enable syntax highlighting
syntax on

" Enable auto-indentation for YAML files
autocmd FileType yaml setlocal autoindent smartindent expandtab shiftwidth=2 tabstop=2
autocmd FileType yml setlocal autoindent smartindent expandtab shiftwidth=2 tabstop=2

📌Docker Compose

docker - 단일 호스트에서 단일컨테이너를 생성(docker run)

docker compose - 단일 호스트에서 여러 개의 컨테이너를 동시 생성(docker compose up)

📌 웹 서버, 데이터베이스, 캐시 서버 등등,,, 이걸 도커로 실행하려면 명령어가 너무 많아짐, 그걸 보완하기 위해 나온 것이 docker compose임

 

📌Docker Compose 사용 시 장점

1. 다수의 컨테이너를 한 번에 실행 가능

2. 다양한 환경을 제공

3. 서비스 간 의존성 관리

4. 컨테이너 링크와 네트워크 자동 설정

 

yaml을 통해 내가 띄울 여러 개의 컨테이너를 정의.

더보기

root@host:~# mkdir /compose

root@host:~# cd /compose/

root@host:/compose# vi web.yml

services:
#내가 띄울 다양한 종류의 컨테이너들
  webserver:
#서비스의 이름
    image: nginx
    ports:
    - '8787:80'
# -p옵션과 비슷
    networks:
    - webnet
# 밑에서 생성한 네트워크 선택
networks:
  webnet
# 네트워크 생성

root@host:/compose# mv web.yml docker-compose.yml

root@host:/compose# docker compose up 

- compose파일이 있는 경로 확인

- 우리가 컴포즈파일에서 정의한 webnet이라는 네트워크가 생성된 걸 알 수 있음.

 host -1

host -1-1

services:
# 내가 띄울 다양한 종류의 컨테이너들
  webserver:
# 서비스의 이름
    image: nginx
    ports:
    - '8787:80'
# -p 옵션과 비슷
    networks:
    - webnet
# 밑에서 생성한 네트워크 선택
    volumes:
    - ./vtest:/usr/share/nginx/html
# 호스트의 ./vtest를 컨테이너의 /usr/share/nginx/html에 마운트
networks:
  webnet:
#네트워크 생성

-d: 백그라운드로 실행시킨다는 의미

network: 

# 네트워크 정의 및 선택

ports:

# -p, publish 옵션

command:

#CMD

environment:

#-e, 환경변수

depends_on:

#A라는 서비스에 B에 대한 depends_on을 걸어주면, B 먼저 생성 후 A가 생성.

 

ex) node.js 앱(todo, weather, chat)의 경우 몽고디비가 연동이 안되면 앱 자체가 죽어버림

node.js 서비스를 생성하면서 몽고디비를 depends_on으로 걸어야 함.

 

root@host:/compose# mkdir ubuntu

실습-1) 위 명령어를 활용하여, ubuntu:latest를 동작시키는 compose 파일을 만들어보세요. - 네트워크 : ubun_net

더보기
services:
  ubun:
    image: ubuntu:latest
    networks:
    - ubun_net
    command: "sleep 200"
    
networks:
  ubun_net:

root@host:/compose/ubuntu# docker compose up -d

- 여기서 sleep 모드?를 수정해 주자

services:
  ubun:
    image: ubuntu:latest
    networks:
    - ubun_net
    command: "sleep infinity"

networks:
  ubun_net:

docker compose ps

services:
  ubun:
    image: ubuntu:latest
    networks:
    - ubun_net
    environment:
      ENV_TEST: 'test'
    command: "sleep infinity"

networks:
  ubun_net:

root@host:/compose/ubuntu# docker compose up -d

 

root@host:/compose/ubuntu# docker exec -it ubuntu-ubun-1 bash
root@714c89abe587:/# echo $ENV_TEST

docker의 --link 옵션

- 도커 컴포즈에서는 --link를 굳이 명시하지 않아도 서비스의 이름으로 찾아갈 수 있음

 

실습-2) wordpress, mysql:8 , wordpress:latest를 베이스이미지로 하여 Dockerfile은 쓰지 않고 docker-compose.yml 파일을 구성해 보세요. publish 포트는 wordpress 1234로 하시고, mysql은 없다. 

각 서비스명

wordpress => wp

mysql => dbdb

더보기

root@host:/compose# cd ..

root@host:/compose# mkdir wordpress

root@host:/compose# cd wordpress/

root@host:/compose/wordpress# vi docker-compose.yml

services:
  wp:
    image: wordpress:latest
    ports: 
    - '1234:80'
    environment:
    - WORDPRESS_DB_HOST=dbdb
    - WORDPRESS_DB_NAME=wpdb
    - WORDPRESS_DB_USER=wpuser
    - WORDPRESS_DB_PASSWORD=1234
    networks:
    - wpnet
# 네트워크를 명시하지 않으면 스스로 만든다.
    depends_on:
    - dbdb
  dbdb:
    image: mysql:8
    environment:
    - MYSQL_ROOT_PASSWORD=1234
    - MYSQL_USER=wpuser
    - MYSQL_PASSWORD=1234
    - MYSQL_DATABASE=wpdb
    networks:
    - wpnet

networks:
  wpnet:

- docker-compose가 서비스의 이름으로 찾아갈 수 있도록 알아서 관리

root@host:/compose/ubuntu/wordpress# docker compose down

이미 존재하는 네트워크를 선택하고 싶을 때.

더보기

- publish 및 컨테이너가 외부로 통신하는 근거

 

이번에는 컴포즈파일에서 이 네트워크(wpnet)를 선택해서 리소스를 띄워보자.

 

 - 이미 만들어 둔 네트워크를 가져올 때는 external을 사용해 주자

서비스에서 이미지를 빌드하는 방법

더보기

- 시작하기 전에 앞에서 실습했던 yml 다운해주기

 

root@host:/compose# mkdir build

root@host:/compose# cd build/

root@host:/compose/build# vi docker-compose.yml

services:
  dbdbdb:
    build: 
# 이미지빌드를 하겠다. 현재디렉토리에 Dockerfile이 있으면 그냥 build:만 해도됨.
      context: .
# 디렉토리 지정. 현재(.) 디렉토리
      dockerfile: Dockerfile
# 도커 파일의 이름 지정.
    image: mydb:1
# 빌드해서 나온 이미지의 이름.
    ports:
      - '33306:3306'

 

root@host:/compose/build# vi Dockerfile

FROM mysql:8
ENV MYSQL_DATABASE=wpdb
ENV MYSQL_USER=wpuser
ENV MYSQL_PASSWORD=12345
ENV MYSQL_ROOT_PASSWORD=1234

 

오류 /해결 방안 -1

- 이게 아니라 build -> created -> started 되기를 바랐지만 build 부분이 안되고 created부분으로 넘어감.

 

아주 간단한 휴먼오류

 - 파일명을 docker_compose라고 했음, 원래는  docker-compose라고 해야 됨

- 정상적으로 up 되는 걸 확인할 수 있음

오류 /해결 방안 -2

- 암호 업데이트가 안됨 = 이미지 빌드가 안됨 = 이미지가 이미 존재하면 빌드를 안 함.

오류 /해결 방안 -3

root@host:/compose/build# mysql -u wpuser -p12345 -h 211.183.3.100 -p 33306
mysql: [Warning] Using a password on the command line interface can be insecure.
Enter password: 
ERROR 2003 (HY000): Can't connect to MySQL server on '211.183.3.100:3306' (111)

- 대소문자 오류쓰~~~미치게쓰~~

docker compose scaling

더보기

root@host:/compose/build# docker compose up --scale dbdbdb=3 -d

# --scale <서비스이름>=<컨테이너갯수>

# 호스트의 publish 된 포트는 1개밖에 없기 때문에 compose에서 호스트포트의 범위를 늘려줘야 한다.

# 호스트의 포트를 넉넉하게

https://docs.docker.com/compose/gettingstarted/3

실습-4) 위 예제를 통해 web-redis 컨테이너를 컴포즈파일로 만들어보세요.

더보기

# 위 예제를 통해 web-redis 컨테이너를 컴포즈파일로 만들어보세요.

# 파일구성 후 docker compose up

# 스케일링을 위해 compose 파일 수정 docker-compose.yml

 

root@host:/compose/flask# mkdir flask

root@host:/compose/flask# cd  flask

 

vi app.py

import time

import redis
from flask import Flask

app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return f'Hello World! I have been seen {count} times.\n'

 

vi requirements.txt

flask
redis

 vi Dockerfile

# syntax=docker/dockerfile:1
FROM python:3.10-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run", "--debug"]

 

- 여기서 compose부분을 수정해자

- 수정해 주는 이유는 스케일링이 되는 걸 확실하게 보기 위해서 수정을 해보는 것

root@host:/compose/flask# vi compose.yaml 

services:
  web:
    build: .
    ports:
      - "8000-8003:5000"
      #수정한 부분
  redis:
    image: "redis:alpine"

 3개의 포트번호를 스케일링해보자

- 다른 포트로 들어가니까 증가된 걸 확인할 수 있음. 스케일링 맛보기 느낌임.

실습-5) 지난 시간에 했던 vuejs-fastapi 앱을 docker compose로 구성해 보세요.

https://github.com/oolralra/vue-fastapi.git

더보기

root@host:/compose/fast/vue-fastapi# cd ..

root@host:/compose/fast/vue-fastapi# git clone https://github.com/oolralra/vue-fastapi.git

 

root@host:~/multi/vue-fastapi/frontend# vi Dockerfile

- 위에 파일에 내용을 수정해 주고

vi docker-compose.yml

- 소스코드에서 backed:8000으로 찾아가라고 되어있기 때문에

- 서비스의 이름을 이걸로 해야 함

services:
  backend:
    build:
      context: ./backend  # backend 디렉토리에서 Dockerfile을 찾아 빌드
    image: back:1  # 이미지 이름 설정
    ports:
      - "8000:8000"  # 호스트의 8000 포트를 컨테이너의 8000 포트에 매핑
    networks:
      - vue_fastapi_net  # 두 서비스 간의 네트워크 연결

  frontend:
    build:
      context: ./frontend  # frontend 디렉토리에서 Dockerfile을 찾아 빌드
    image: front:1  # 이미지 이름 설정
    ports:
      - "80:80"  # 호스트의 80 포트를 컨테이너의 80 포트에 매핑
    networks:
      - vue_fastapi_net  # 두 서비스 간의 네트워크 연결
    depends_on:
      - backend  # frontend가 backend 서비스가 준비될 때까지 기다리게 설정

networks:
  vue_fastapi_net:  # 두 서비스가 연결될 네트워크 정의
    driver: bridge  # 기본 네트워크 드라이버인 bridge 사용

root@host:/compose/fast/vue-fastapi# docker compose up -d

- 해주면 전에 직접 빌드해주던 것들을 한 번에 할 수 있음

실습-6) 아래와 같이 디렉터리 구성 후 web은 nginx, was는 tomcat, db는 mysql:8로 3 tier를 구성하는 도커컴포즈 파일을 작성하세요! curl 211.183.3.100:4989 로 접속했을 때 DB연동을 확인해 보세요.

더보기

root@host:~# cd /compose/
root@host:/compose# mkdir 3tier
root@host:/compose# cd 3tier/
root@host:/compose/3tier# mkdir web was db
root@host:/compose/3tier# ls
db  was  web

풀이) 

1. db 구성

 

root@host:/compose/3tier# cat db/Dockerfile

FROM mysql:8

ENV MYSQL_ROOT_PASSWORD=1234

ENV MYSQL_PASSWORD=1234

ENV MYSQL_USER=tomuser

ENV MYSQL_DATABASE=tomdb

 

# db는 Dockerfile만 있으면 끝.

 

2. tomcat 구성

root@host:/compose/3tier# cat was/Dockerfile

FROM tomcat:latest

WORKDIR /usr/local/tomcat

RUN mkdir /usr/local/tomcat/webapps/ROOT

COPY dbtest.jsp ./webapps/ROOT/dbtest.jsp

COPY index.jsp ./webapps/ROOT/index.jsp

COPY mysql* /usr/local/tomcat/lib

# CMD는 이미 베이스이미지에 구성되어 있으므로 안 함.

 

root@host:/compose/3tier# cat was/dbtest.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ page import="java.sql.*"%>

<h1>DB</h2>

<%

        Connection conn=null;

        try{

                String Url="jdbc:mysql://db/tomdb";

                String Id="tomuser";

                String Pass="1234";

 

                Class.forName("com.mysql.jdbc.Driver");

                conn=DriverManager.getConnection(Url,Id,Pass);

                out.println("was-db Connection Success!");

        }catch(Exception e) {

                e.printStackTrace(); 

}

%>

 

root@host:/compose/3tier# cat was/index.jsp 

# 인덱스 파일 구성

<%@ page contentType="text/html; charset=UTF-8"%>

<html>

     <head><title>hello world</title></head>

     <body>

     <h2>

             TOMCAT TEST<br><br>

             time : <%= new java.util.Date()%>

             <%@ page import="java.net.InetAddress" %><br>

             <%InetAddress inet= InetAddress.getLocalHost();%>

             WAS ip : <%=inet.getHostAddress()%>

     </h2>

 

 

     </body>

</html>

 

3. web 구성

root@host:/compose/3tier# cat web/default.conf

# 리버스프록시 파일 구성

server {

location /jsp {

proxy_pass http://was:8080/;

}

}

root@host:/compose/3tier# cat web/Dockerfile 

FROM nginx:alpine

WORKDIR /etc/nginx/conf.d/

COPY default.conf default.conf

 

4. 컴포즈파일 구성

root@host:/compose/3tier# cat docker-compose.yml 

services:
  web:
    build:
      context: ./web
    image: tom-web:1
    ports:
    - '88:80'
    depends_on:
    - was
  was:
    build:
      context: ./was
    depends_on:
    - db
    image: tom-was:1
  db:
    build:
      context: ./db
    image: tom-db:1

root@host:/compose/3tier# docker compose up -d --build --scale was=3

 

 

728x90