본문 바로가기
IT/Docker

도커(Docker) 기본 명령어

by dev-centralpark 2025. 11. 20.

1. Docker 주요 명령어

1) 이미지 관련

docker pull <이미지명>           # 이미지 다운로드
docker images                    # 로컬 이미지 목록 보기
docker rmi <이미지ID>            # 이미지 삭제
docker history <이미지명>        # 해당 이미지의 히스토리

 

2) 컨테이너 실행(run)

docker run <이미지명>            # 컨테이너 실행
docker run -d <이미지명>         # 백그라운드 실행
docker run -it <이미지명> bash   # 컨테이너 내부 접속
docker run -p 8080:80 <이미지명> # 포트 매핑
docker run -v 호스트:컨테이너    # 볼륨 마운트

예: 
docker run -d -p 9999:80 -v /home/html:/usr/local/apache2/htdocs httpd
docker run -d -p 9999:80 --name web myweb

 

3) 컨테이너 관리

docker ps                       # 실행 중인 컨테이너
docker ps -a                    # 모든 컨테이너
docker stop <ID>                # 컨테이너 중지
docker start <ID>               # 다시 실행
docker restart <ID>             # 재시작
docker rm <ID>                  # 컨테이너 삭제
docker logs <ID>                # 로그 확인

# 컨테이너와 컨테이너 연결

# 1) MySQL 컨테이너 실행 (포트 개방 없이 내부에서만 실행)
docker run --rm -d --name mydb \
  -v /home/ubuntu/mssqldata:/var/lib/mysql \
  mysqldb

→ 설명
- --rm : 컨테이너가 종료되면 자동 삭제
- -d : 백그라운드 실행
- --name mydb : 컨테이너 이름을 mydb로 지정
- -v /home/ubuntu/mssqldata:/var/lib/mysql :
    MySQL 데이터 저장소를 호스트에 영구 저장(데이터 유실 방지)
- 포트(-p)를 안 썼기 때문에 외부에서는 접속할 수 없음
  = 오직 “다른 컨테이너들만” MySQL에 접근 가능
- mysqldb : 내가 빌드한 MySQL Docker 이미지 이름


# 2) Jupyter Notebook 컨테이너가 MySQL 컨테이너에 연결 (--link)
docker run --rm -d -p 9999:80 \
  -v /home/ubuntu/dev:/home/jovyan/work \
  --link mydb:myjupyterdb \
  jupyter/datascience-notebook

→ 설명
- --rm : 컨테이너 종료 시 자동 삭제
- -d : 백그라운드 실행
- -p 9999:80 : 호스트 9999 → 컨테이너 80포트로 접근 가능
    (브라우저에서 http://IP:9999 접속)
- -v /home/ubuntu/dev:/home/jovyan/work :
    Jupyter의 작업 폴더를 호스트 디렉토리와 공유
- --link mydb:myjupyterdb :
    Jupyter 컨테이너에서 "myjupyterdb" 라는 이름으로
    MySQL 컨테이너(mydb)에 접근할 수 있게 연결
    예) mysql -h myjupyterdb -u root -p
- jupyter/datascience-notebook : Jupyter 공식 이미지


# 요약
- MySQL 컨테이너는 외부 포트를 열지 않고 내부에서만 구동
- Jupyter Notebook 컨테이너는 --link 옵션으로 MySQL에 직접 접속 가능
- 따라서 Jupyter는 DB를 쓸 수 있지만 외부에서 MySQL로 접속할 수 없음
- Jupyter는 -p 9999:80 으로 외부 브라우저 접근 가능

 

4) 컨테이너 내부 진입

# 컨테이너 내부 진입
docker exec -it <container> /bin/bash
docker exec -it <container> /bin/sh

# 컨테이너 내부에 접근하여 현재 호스트 폴더로 000-default.conf를 복사함
docker cp web:/etc/apache2/sites-available/000-default.conf ./

# 현재 호스트 000-default.conf 파일을 컨테이너 내부에 붙여넣음
docker cp 000-default.conf web:/etc/apache2/sites-available/000-default.conf

# 컨테이너 내부의 변경사항을 이미지 파일로 생성
docker commit -m <컨테이너 ID 또는 이름> <이미지 이름>

# 기존의 이미지와 현재 컨테이너 이미지를 비교하여 다른점을 출력
docker diff <컨테이너명>
A는 추가, D는 삭제, C는 변경

 

5) 도커 시스템 정리

docker system df                # 디스크 사용량
docker system prune             # 미사용 컨테이너/이미지 제거

2. Dockerfile 작성 방법

## 기본구조

# FROM: 어떤 환경(베이스 이미지)에서 시작할지 정의 / 이미지만 적으면 자동 latest
FROM python:3.10-slim
FROM alpine 

# LABEL: key=value 형식으로 메타데이터를 넣을 수 있음
LABEL description="Python 기반 토큰 클리너 서비스"
LABEL maintainer="홍길동 <gildong@example.com>"
LABEL version="1.0.0"

docker inspect myweb
...
"Labels":{
	"author": "ㅇㅇㅇ"
}
...

# COPY: 호스트 파일을 도커 컨테이너 내부로 복사
COPY clean_tokens.py /app/clean_tokens.py
COPY ./DEV /usr/local/apache2/htdocs

# RUN: 이미지 빌드 과정에서 필요한 명령 실행
RUN pip install schedule requests
RUN apt-get install
RUN apt-get install -y apache2 apt-utils

# CMD: 컨테이너 실행 시 실행할 기본 명령
3가지 예시
Docker 공식에서 추천하는 방식
CMD ["python", "clean_tokens.py"]

쉘기반
CMD python clean_tokens.py

ENTRYPOINT는 반드시 실행해야하는 '메인 명령', CMD는 '인자' 역할을 함
ENTRYPOINT ["python"]
CMD ["clean_tokens.py"]

docker inspect myweb
...
"Cmd":[
	"/bin/sh",
    "-c",
    "httpd-foreground"
]
...

# Dockerfile의 CMD 명령 덮어쓰기
docker run -d -p 9999:80 --name web myweb /bin/sh -c httpd-foreground

# EXPOSE: 컨테이너가 사용하는 포트를 문서화(외부 오픈 아님)
EXPOSE 8080

# ENV: 환경변수로 활용
ENV MYSQL_ROOT_PASSWORD=password
ENV MYSQL_DATABASE=dbname

# WORKDIR: 이후 명령어가 실행될 작업 디렉터리 설정
WORKDIR /app

 

1) 이미지 빌드

docker build <옵션> Dockerfile_path

<옵션 예시> 
docker build --tag myimg .
-t 또는 --tag: 이미지의 이름 설정

docker build --tag myimg2 -f Dockerfile2 .
-f: Dockerfile을 지정함

docker build --tag myimg3 -f Dockerfile2 --pull=true
--pull: 해당 옵션은 이미지 생성시마다 새로 다운로드 받으라는 옵션

3. Dockerfile 실전 예시

(1) Apache 웹서버 + HTML

# RUN 할 필요 없이 COPY만 해도 동작함
FROM httpd:latest
COPY ./html/ /usr/local/apache2/htdocs/

빌드: docker build -t my-apache .

실행: docker run -d -p 9999:80 my-apache

(2) Node.js 서버 이미지 만들기 (프론트/백엔드 둘 다 가능)

FROM node:18

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

(3) Spring Boot JAR 실행용 Dockerfile

FROM eclipse-temurin:17-jdk

WORKDIR /app

COPY build/libs/myapp.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

4. docker-compose

# 주로 services(필수), volumes(선택)만 쓰임
# 다른 옵션 networks, secrets, configs, depends_on, healthcheck, deploy 등등

services:                        # 실행할 서비스(컨테이너) 목록
  backend:                       # 내가 정한 서비스(컨테이너) 이름
    build:                       # Dockerfile을 이용해 이미지 빌드
      context: .                 # 현재 디렉토리를 빌드 컨텍스트로 사용
      dockerfile: Dockerfile     # 빌드할 도커파일 지정
    ports:
      - "8080:8080"              # 호스트 8080 → 컨테이너 8080 포트 매핑
    env_file:
      - .env                     # 환경변수 파일(.env) 사용
    depends_on:
      - db                       # db 서비스가 먼저 시작되도록 지정
    restart: always              # 컨테이너 종료 시 자동 재시작
    networks:
      - appnet                   # appnet 네트워크 연결
    volumes:
      - ./logs:/app/logs         # 로컬 logs → 컨테이너 /app/logs 마운트
      - ./config:/app/config     # 로컬 config → 컨테이너 /app/config 마운트

  db:                            # 내가 정한 서비스(컨테이너) 이름
    image: postgres:15           # PostgreSQL 15 이미지 사용
    environment:
      POSTGRES_PASSWORD: 1234    # Postgres 초기 비밀번호 설정(환경변수)
    volumes:
      - pgdata:/var/lib/postgresql/data   # 데이터 저장 볼륨 지정
    restart: always              # DB 컨테이너 자동 재시작
    networks:
      - appnet                   # 같은 네트워크 사용

volumes:                          # Docker 볼륨 정의
  pgdata:                         # 이름 있는 볼륨(데이터 영속성)

networks:                         # Docker 네트워크 정의
  appnet:                         # 서비스들이 공유할 네트워크 이름
    driver: bridge                # 로컬 개발에서 기본적으로 사용하는 bridge 네트워크

# 실행 방법
docker compose up -d
→ yml에 적힌 web + db 컨테이너가 동시에 실행됨

# 중지
docker compose down
→ yml에 적힌 컨테이너 중지

# 종료
docker compose down
→ 두 개 모두 종료 및 네트워크 제거

# logs 확인
docker compose logs -f
→ 여러 컨테이너 로그를 한 번에 확인 가능

# .dockerignore 파일을 통해 COPY할 파일을 제외할 수 있음