실습
* 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
'AWS Cloud School 8기 > 도커(docker)' 카테고리의 다른 글
디스크 용량 확장/ mysql 컨테이너 생성/--link 옵션/ 사설저장소(private registry) (1) | 2025.04.02 |
---|---|
Docker Swarm (1) | 2025.04.01 |
다양한 앱 배포/ 웹 어플리케이션/ 프레임워크/ sudo lsof -i :<포트 번호>/ sudo kill -9 <PID>/ (0) | 2025.03.30 |
도커이미지(Docker Image)/ FROM/ WORKDIR/ COPY/ RUN/ CMD/ EXPOSE/ ENV/ Dockerfile (4) | 2025.03.19 |
컨테이너 가상화 (6) | 2025.03.18 |