컨테이너 시작에 실패했을 때, 가장 먼저 할 일은 컨테이너에 들어가는 것이 아니라 로그를 확인하는 것이다.
docker logs 容器名称
예시:
docker logs nginx
로그가 너무 많다면 마지막 100줄만 확인할 수 있다.
docker logs --tail 100 nginx
새 로그를 계속 확인하려면:
docker logs -f nginx
평소에 나는 다음 조합을 더 자주 사용한다:
docker logs -f --tail 200 nginx
이 명령어는 마지막 200줄의 로그를 먼저 보여준 후, 새로 생성되는 로그를 계속 출력한다.
최근 30분간의 로그를 확인하려면:
docker logs --since 30m nginx
컨테이너가 계속 재시작된다면, 두 개의 터미널을 동시에 열어두면 된다.
첫 번째 터미널에서 상태 확인:
docker ps
두 번째 터미널에서 로그를 계속 확인:
docker logs -f --tail 200 容器名称
일반적으로 환경 변수 누락, 설정 파일 오류, 디렉터리 권한 부족, 데이터베이스 연결 실패 등은 모두 로그에서 단서를 찾을 수 있다.
3. 컨테이너 시작, 중지 및 재시작
이미 존재하는 컨테이너를 시작하려면:
docker start 容器名称
컨테이너 중지:
docker stop 容器名称
컨테이너 재시작:
docker restart 容器名称
예시:
docker restart nginx
docker stop는 먼저 컨테이너 내부의 프로그램에 정상 종료 신호를 보낸다.
PostgreSQL, MySQL, Redis처럼 데이터를 쓰는 서비스는 우선 docker stop를 사용하여 프로그램이 데이터를 저장하고 파일을 닫을 시간을 확보해야 한다.
컨테이너가 완전히 응답하지 않을 때만 다음을 고려한다:
docker kill 容器名称
docker kill는 컨테이너 프로세스를 강제로 종료하는 방식으로,docker stop보다 강력하다.
컨테이너가 멈춘 문제를 해결할 수는 있지만, 일상적인 재시작 방식으로 사용해서는 안 된다.
4. 컨테이너 내부에 접근하기
컨테이너에 접근하려면 보통 다음을 사용한다:
docker exec -it 容器名称 bash
예시:
docker exec -it nginx bash
하지만 모든 이미지에 Bash가 설치되어 있는 것은 아니다.
Alpine 같은 경량 이미지는 보통 sh만 있다:
docker exec -it nginx sh
root 사용자로 접근해야 한다면:
docker exec -it -u root 容器名称 sh
대화형 터미널로 들어가지 않고도 명령어 하나를 바로 실행할 수 있다.
docker exec nginx ls -lah /etc/nginx
명령어에 cd, 파이프 또는 여러 작업이 포함되어 있다면 sh -c를 사용해야 한다.
docker exec nginx sh -c 'cd /etc/nginx && ls -lah'
다음과 같은 방식은 보통 통하지 않는다:
docker exec nginx "cd /etc/nginx && ls"
因为 cd 不是一个独立的可执行程序,它是 Shell 内部命令。
컨테이너에 접근하는 것은 문제 추적에는 유용하지만, 설정을 장기적으로 바꾸는 용도로는 적합하지 않다.
예를 들어, 컨테이너 안에서 nginx.conf를 수정하더라도, 다음에 컨테이너가 다시 생성될 때 이 변경 사항은 모두 사라질 가능성이 높다./etc/nginx/nginx.conf를 수정해도, 다음에 컨테이너가 다시 생성될 때 이 변경 사항은 모두 사라질 가능성이 높다.
진정으로 장기간 유지해야 할 설정은 Dockerfile에 작성하거나 호스트에서 마운트해야 한다.
5. 이미지 기본 작업
로컬 이미지 확인:
docker images
다음과 같이 쓸 수도 있다:
docker image ls
이미지 내려받기:
docker pull nginx
버전 지정:
docker pull nginx:1.29-alpine
프로덕션 환경에서는 다음과 같이 막연한 태그 대신 명확한 버전을 지정하는 것이 좋다:
nginx:latest
latest는 단순한 태그일 뿐이며, 항상 같은 버전을 가리킨다는 보장이 없다.
오늘 내려받은 latest와 몇 달 후에 내려받은 latest는 내용이 완전히 다를 수 있다. 이렇게 하면 업데이트는 편하지만, 문제가 생겼을 때 롤백하기 어렵다.
이미지 삭제:
docker rmi 镜像名称
예시:
docker rmi nginx:1.29-alpine
이미지가 여전히 어떤 컨테이너에서 사용 중이라면 Docker는 삭제를 거부한다.
해당 컨테이너가 이미 중지되었더라도 여전히 그 이미지를 참조할 수 있다. 먼저 다음 명령어로 확인한다:
docker ps -a
6. 새 이미지를 내려받았는데도 왜 프로그램이 여전히 구 버전일까
이것은 Docker 사용에서 자주 오해하는 부분이다.
다음을 실행하는 것은:
docker pull nginx:latest
단순히 새 이미지를 서버에 내려받을 뿐이다.
이미 실행 중인 컨테이너는 자동으로 새 이미지로 바뀌지 않는다. 컨테이너를 생성할 때 사용한 이미지는 이미 결정되었기 때문이다.
Docker Compose 프로젝트의 경우, 보통 다음을 실행해야 한다:
docker compose pull docker compose up -d
첫 번째 명령어가 이미지를 내려받고, 두 번째 명령어가 새 이미지를 기반으로 컨테이너를 다시 생성한다.
다음만 실행하는 것은:
docker compose restart
보통 소용없다.
restart는 단순히 기존 컨테이너를 재시작할 뿐이다. 이미지를 교체하지 않으며, 새로 수정한 포트, 디렉터리 마운트, 환경 변수도 반영되지 않는다.
따라서 compose.yaml를 수정한 후에는 다음을 실행해야 한다:
docker compose up -d
컨테이너가 제대로 다시 생성되지 않은 것이 의심된다면 다음을 사용할 수 있다:
docker compose up -d --force-recreate
하지만 대부분의 경우 일반적인 docker compose up -d면 충분하다.
7. Docker Compose 자주 사용하는 명령어
요즘 새 버전의 Docker는 보통 다음을 사용한다:
docker compose
구 버전 대신:
docker-compose
프로젝트 시작:
docker compose up -d
-d는 백그라운드 실행을 의미한다.
프로젝트 상태 확인:
docker compose ps
로그 확인:
docker compose logs
로그 계속 확인:
docker compose logs -f
특정 서비스만 확인:
docker compose logs -f web
프로젝트의 컨테이너를 중지하되 삭제하지 않음:
docker compose stop
다시 시작:
docker compose start
컨테이너를 중지하고 삭제:
docker compose down
이미지를 다시 빌드하고 시작:
docker compose up -d --build
원격 이미지 내려받기:
docker compose pull
Compose 파일에 형식 오류가 있는지 확인:
docker compose config
전체 설정을 출력하지 않고 검사만 하려면:
docker compose config -q
나는 보통 프로젝트를 업데이트하기 전에 먼저 한 번 실행한다:
docker compose config -q
아무 출력도 없으면 보통 설정 문법에 문제가 없다는 뜻이다.
8. 비교적 안전한 업데이트 절차
프로젝트가 다음 경로에 있다고 가정하자:
/opt/myapp
먼저 프로젝트 디렉터리로 이동한다:
cd /opt/myapp
설정 확인:
docker compose config -q
현재 실행 상태 확인:
docker compose ps
새 이미지 내려받기:
docker compose pull
컨테이너 다시 생성:
docker compose up -d --remove-orphans
업데이트 후 상태 확인:
docker compose ps
마지막으로 로그 확인:
docker compose logs --tail 200
프로그램이 정상적으로 실행되면 그때 구 이미지 정리를 고려한다.
docker image prune
정리 작업을 업데이트 절차의 맨 앞에 두지 말자.
먼저 새 버전이 정상적으로 실행되고 있는지 확인한 후에 구 이미지를 삭제한다. 그래야 문제가 생겼을 때 예전 버전을 다시 사용할 기회라도 있다.
docker ps -a docker images docker volume ls docker system df -v
不要把 docker system prune -a --volumes 当成日常清理命令。
이 명령어는 '이 모든 것을 더 이상 필요하지 않다고 확인했다'는 의미에 더 가깝다.
15. 디렉터리 권한 오류가 발생하면 어떻게 할까
컨테이너가 호스트 디렉터리를 마운트한 후, 프로그램이 다음과 같은 오류를 표시할 수 있다:
Permission denied
먼저 호스트 디렉터리의 권한을 확인한다:
ls -ld /opt/myapp/data
파일의 UID와 GID를 확인:
ls -ln /opt/myapp/data
그런 다음 컨테이너 내부에서 프로그램이 어떤 사용자로 실행되는지 확인:
docker exec 容器名称 id
컨테이너가 UID 1000, GID 1000을 사용한다면, 상황에 맞게 호스트 디렉터리의 소유자를 변경한다:
sudo chown -R 1000:1000 /opt/myapp/data
많은 사람들이 권한 문제를 만나면 바로 다음을 실행한다:
chmod -R 777 /opt/myapp/data
이렇게 하면 일시적으로 문제가 해결될 수 있지만, 보통 올바른 방법은 아니다.
777는 모든 사용자에게 읽기, 쓰기, 실행 권한을 부여하여 실제 UID, GID 및 디렉터리 소유권 문제를 가려버린다.
먼저 컨테이너가 어떤 사용자로 실행되는지 확인한 후, 그에 맞게 권한을 조정하는 것이 더 안정적이다.
16. 몇 가지 혼동하기 쉬운 부분
docker pull는 실행 중인 컨테이너를 업데이트하지 않는다
이미지를 내려받는 역할만 한다.
Compose 프로젝트를 업데이트하려면 다음도 필요하다:
docker compose up -d
docker restart는 새 설정을 적용하지 않는다
기존 컨테이너를 재시작할 뿐이다.
Compose 파일을 수정한 후에는 다음을 사용해야 한다:
docker compose up -d
컨테이너를 삭제해도 데이터 볼륨이 반드시 삭제되지는 않는다
일반적인:
docker rm 容器名称
는 보통 이름이 있는 데이터 볼륨을 삭제하지 않는다.
하지만:
docker rm -v 容器名称
는 컨테이너가 사용하는 익명 데이터 볼륨을 삭제할 수 있다.
컨테이너 내부에서 수동으로 수정한 파일은 신뢰할 수 없다
컨테이너가 다시 생성되면 수정 사항이 사라질 수 있다.
장기간 유지해야 할 설정은 Dockerfile, Compose 파일 또는 호스트 마운트 디렉터리에 작성해야 한다.
컨테이너 IP에 의존하지 말자
컨테이너 이름이나 Compose 서비스 이름으로 접근한다.
모든 포트를 공개 네트워크에 노출하지 말자
내부 서비스는 Docker 네트워크 안에만 두는 것이 좋다.
17. 내가 평소에 가장 자주 사용하는 명령어들
컨테이너 확인:
docker ps -a
로그 확인:
docker logs -f --tail 200 容器名称
컨테이너 접근:
docker exec -it 容器名称 sh
리소스 확인:
docker stats
디스크 사용량 확인:
docker system df -v
Compose 설정 확인:
docker compose config -q
Compose 프로젝트 업데이트:
docker compose pull docker compose up -d --remove-orphans
업데이트 후 상태 확인:
docker compose ps docker compose logs --tail 200
이 명령어들만으로도 대부분의 일상적인 배포, 업데이트, 문제 해결을 커버할 수 있다.
마치며
Docker에서 가장 오해하기 쉬운 점은 컨테이너를 작은 서버처럼 생각하기 쉽다는 점이다.
하지만 컨테이너는 가상 머신이 아니다.
컨테이너는 언제든지 삭제되고 다시 생성되며 교체될 수 있는 실행 환경에 더 가깝다. 정말 중요한 것은 컨테이너 내부에만 두어서는 안 된다.
프로그램은 이미지에, 설정은 Compose나 마운트 디렉터리에, 데이터는 데이터 볼륨이나 별도 저장소에 둔다. 컨테이너에 문제가 생기면 다시 생성하면 된다.
이 점을 이해하면 많은 Docker 명령어를 굳이 외우지 않아도 된다.
마지막으로 한 번 더 강조하자면, 다음 파라미터들을 볼 때는 실행하기 전에 잠시 멈추는 것이 좋다:
-v --volumes prune rm -f --privileged
이것들이 항상 위험한 것은 아니지만, 보통 데이터 삭제, 강제 작업, 또는 컨테이너 권한 확장을 의미한다.
특히 다음 명령어는:
docker compose down -v
데이터가 백업되었는지 확인하기 전에는 함부로 실행하지 말자.
Loading...
Loading...
Loading...
Loading...
Loading...
Docker 명령은 많지 않지만 헷갈리기 쉽습니다. 새 이미지를 가져와도 실행 중인 웹사이트가 이전 버전을 사용하거나, 컨테이너를 삭제 후 재생성하면 데이터베이스가 사라지거나, 서버 디스크가 Docker 로그 파일로 가득 차는 등의 문제가 자주 발생합니다. 이 글은 배포와 유지보수에 자주 사용되는 Docker 명령어를 정리한 것으로, 완전한 매뉴얼이 아닌 일상적인 작업과 데이터 손실 가능성이 있는 명령어에 초점을 맞춥니다. 컨테이너는 가상 머신이 아니라 언제든 삭제되고 교체될 수 있는 실행 환경이며, 중요한 데이터는 컨테이너 내부가 아닌 데이터 볼륨이나 호스트 디렉토리에 저장해야 합니다. 이미지, 컨테이너, 볼륨, 네트워크의 관계를 이해하는 것이 중요하며, docker pull만으로 실행 중인 컨테이너가 업데이트되지 않고, docker restart로 새 설정이 적용되지 않으며, 컨테이너 삭제가 항상 볼륨을 삭제하지는 않는다는 점을 주의해야 합니다. docker system prune --volumes와 같은 명령은 데이터를 삭제할 수 있으므로 실행 전에 반드시 확인해야 합니다.
Docker 명령어 자체는 많지 않지만, 진짜 문제는 명령어들이 헷갈리기 쉽다는 데 있다.
예를 들어, 새 이미지를 분명히 내려받았는데도 사이트는 여전히 구 버전으로 동작하는 경우, 컨테이너를 삭제했다가 다시 만들고 나서야 데이터베이스도 함께 사라진 걸 알게 되는 경우, 서버 디스크가 갑자기 가득 차서 확인해보니 Docker 로그 파일 때문인 경우도 있다.
이런 문제들은 복잡하지 않지만, 시간이 지나면 꼭 한 번씩 마주친다. 막상 문제가 생겼을 때 문서를 찾아보다 보면 파라미터를 확인하는 데 또 시간을 허비하게 된다.
그래서 평소에 서버를 배포하고 유지보수하면서 자주 사용하는 Docker 명령어를 여기에 정리했다.
이것은 완전한 Docker 매뉴얼이 아니다. 1년에도 한 번 쓸까 말까 한 파라미터는 모두 일일이 담지 않았다. 여기에는 일상에서 가장 흔히 쓰는 작업과 데이터 손실을 초래할 수 있는 몇 가지 명령어만 기록했다.
Dockerfile 用来构建镜像,镜像用来创建容器。容器负责运行程序,但容器本身不适合保存重要数据,需要长期保留的内容应该放在数据卷或宿主机目录中。多个容器之间,则通过 Docker 网络互相通信。
시작하기 전에, Docker의 몇 가지 개념을 먼저 구분하자
Docker 명령어가 헷갈리는 주된 이유는 이미지, 컨테이너, 데이터 볼륨, 네트워크가 자주 함께 등장하기 때문이다.
이들 간의 관계는 대략 다음과 같다:
1. 먼저 Docker의 현재 상태 확인하기
Docker에 문제가 생겼을 때, 나는 보통 바로 서비스를 재시작하지 않고 먼저 컨테이너 상태를 확인한다.
이 명령어는 실행 중인 컨테이너만 표시한다.
중지된 컨테이너도 보고 싶다면 -a를 추가해야 한다.
출력에서 중요한 항목들은 다음과 같다:
일부 컨테이너는 시작되자마자 곧바로 종료되기도 한다. 이런 경우 docker ps만으로는 확인할 수 없으며, 반드시 다음을 사용해야 한다:
Docker가 현재 얼마나 많은 디스크 공간을 사용 중인지 확인하려면 다음을 실행한다:
이미지, 컨테이너, 데이터 볼륨의 상세한 점유 현황을 확인하려면 다음을 실행한다:
서버 디스크가 갑자기 가득 찼을 때 이 두 명령어가 유용하다.
不要一看到 /var/lib/docker 很大,就直接进去删除文件。这个目录由 Docker 自己管理,手动删除里面的内容,很容易把整个 Docker 环境弄坏。
2. 컨테이너 로그 확인하기
컨테이너 시작에 실패했을 때, 가장 먼저 할 일은 컨테이너에 들어가는 것이 아니라 로그를 확인하는 것이다.
예시:
로그가 너무 많다면 마지막 100줄만 확인할 수 있다.
새 로그를 계속 확인하려면:
평소에 나는 다음 조합을 더 자주 사용한다:
이 명령어는 마지막 200줄의 로그를 먼저 보여준 후, 새로 생성되는 로그를 계속 출력한다.
최근 30분간의 로그를 확인하려면:
컨테이너가 계속 재시작된다면, 두 개의 터미널을 동시에 열어두면 된다.
첫 번째 터미널에서 상태 확인:
두 번째 터미널에서 로그를 계속 확인:
일반적으로 환경 변수 누락, 설정 파일 오류, 디렉터리 권한 부족, 데이터베이스 연결 실패 등은 모두 로그에서 단서를 찾을 수 있다.
3. 컨테이너 시작, 중지 및 재시작
이미 존재하는 컨테이너를 시작하려면:
컨테이너 중지:
컨테이너 재시작:
예시:
docker stop는 먼저 컨테이너 내부의 프로그램에 정상 종료 신호를 보낸다.
PostgreSQL, MySQL, Redis처럼 데이터를 쓰는 서비스는 우선 docker stop를 사용하여 프로그램이 데이터를 저장하고 파일을 닫을 시간을 확보해야 한다.
컨테이너가 완전히 응답하지 않을 때만 다음을 고려한다:
docker kill는 컨테이너 프로세스를 강제로 종료하는 방식으로,docker stop보다 강력하다.
컨테이너가 멈춘 문제를 해결할 수는 있지만, 일상적인 재시작 방식으로 사용해서는 안 된다.
4. 컨테이너 내부에 접근하기
컨테이너에 접근하려면 보통 다음을 사용한다:
예시:
하지만 모든 이미지에 Bash가 설치되어 있는 것은 아니다.
Alpine 같은 경량 이미지는 보통 sh만 있다:
root 사용자로 접근해야 한다면:
대화형 터미널로 들어가지 않고도 명령어 하나를 바로 실행할 수 있다.
명령어에 cd, 파이프 또는 여러 작업이 포함되어 있다면 sh -c를 사용해야 한다.
다음과 같은 방식은 보통 통하지 않는다:
因为 cd 不是一个独立的可执行程序,它是 Shell 内部命令。
컨테이너에 접근하는 것은 문제 추적에는 유용하지만, 설정을 장기적으로 바꾸는 용도로는 적합하지 않다.
예를 들어, 컨테이너 안에서 nginx.conf를 수정하더라도, 다음에 컨테이너가 다시 생성될 때 이 변경 사항은 모두 사라질 가능성이 높다./etc/nginx/nginx.conf를 수정해도, 다음에 컨테이너가 다시 생성될 때 이 변경 사항은 모두 사라질 가능성이 높다.
진정으로 장기간 유지해야 할 설정은 Dockerfile에 작성하거나 호스트에서 마운트해야 한다.
5. 이미지 기본 작업
로컬 이미지 확인:
다음과 같이 쓸 수도 있다:
이미지 내려받기:
버전 지정:
프로덕션 환경에서는 다음과 같이 막연한 태그 대신 명확한 버전을 지정하는 것이 좋다:
latest는 단순한 태그일 뿐이며, 항상 같은 버전을 가리킨다는 보장이 없다.
오늘 내려받은 latest와 몇 달 후에 내려받은 latest는 내용이 완전히 다를 수 있다. 이렇게 하면 업데이트는 편하지만, 문제가 생겼을 때 롤백하기 어렵다.
이미지 삭제:
예시:
이미지가 여전히 어떤 컨테이너에서 사용 중이라면 Docker는 삭제를 거부한다.
해당 컨테이너가 이미 중지되었더라도 여전히 그 이미지를 참조할 수 있다. 먼저 다음 명령어로 확인한다:
6. 새 이미지를 내려받았는데도 왜 프로그램이 여전히 구 버전일까
이것은 Docker 사용에서 자주 오해하는 부분이다.
다음을 실행하는 것은:
단순히 새 이미지를 서버에 내려받을 뿐이다.
이미 실행 중인 컨테이너는 자동으로 새 이미지로 바뀌지 않는다. 컨테이너를 생성할 때 사용한 이미지는 이미 결정되었기 때문이다.
Docker Compose 프로젝트의 경우, 보통 다음을 실행해야 한다:
첫 번째 명령어가 이미지를 내려받고, 두 번째 명령어가 새 이미지를 기반으로 컨테이너를 다시 생성한다.
다음만 실행하는 것은:
보통 소용없다.
restart는 단순히 기존 컨테이너를 재시작할 뿐이다. 이미지를 교체하지 않으며, 새로 수정한 포트, 디렉터리 마운트, 환경 변수도 반영되지 않는다.
따라서 compose.yaml를 수정한 후에는 다음을 실행해야 한다:
컨테이너가 제대로 다시 생성되지 않은 것이 의심된다면 다음을 사용할 수 있다:
하지만 대부분의 경우 일반적인 docker compose up -d면 충분하다.
7. Docker Compose 자주 사용하는 명령어
요즘 새 버전의 Docker는 보통 다음을 사용한다:
구 버전 대신:
프로젝트 시작:
-d는 백그라운드 실행을 의미한다.
프로젝트 상태 확인:
로그 확인:
로그 계속 확인:
특정 서비스만 확인:
프로젝트의 컨테이너를 중지하되 삭제하지 않음:
다시 시작:
컨테이너를 중지하고 삭제:
이미지를 다시 빌드하고 시작:
원격 이미지 내려받기:
Compose 파일에 형식 오류가 있는지 확인:
전체 설정을 출력하지 않고 검사만 하려면:
나는 보통 프로젝트를 업데이트하기 전에 먼저 한 번 실행한다:
아무 출력도 없으면 보통 설정 문법에 문제가 없다는 뜻이다.
8. 비교적 안전한 업데이트 절차
프로젝트가 다음 경로에 있다고 가정하자:
먼저 프로젝트 디렉터리로 이동한다:
설정 확인:
현재 실행 상태 확인:
새 이미지 내려받기:
컨테이너 다시 생성:
업데이트 후 상태 확인:
마지막으로 로그 확인:
프로그램이 정상적으로 실행되면 그때 구 이미지 정리를 고려한다.
정리 작업을 업데이트 절차의 맨 앞에 두지 말자.
먼저 새 버전이 정상적으로 실행되고 있는지 확인한 후에 구 이미지를 삭제한다. 그래야 문제가 생겼을 때 예전 버전을 다시 사용할 기회라도 있다.
9. 데이터는 도대체 어디에 저장되는가
Docker 컨테이너 자체는 중요한 데이터를 보관하기에 적합하지 않다.
컨테이너가 삭제되면 그 쓰기 가능 계층도 함께 삭제된다.
장기간 보관해야 하는 데이터는 보통 두 곳에 둔다:
데이터 볼륨 확인:
특정 데이터 볼륨의 정보 확인:
예시:
Compose에서 흔히 사용하는 데이터 볼륨 설정 방식:
이렇게 하면 컨테이너가 삭제되어도 postgres-data 데이터 볼륨은 보통 그대로 유지된다.
호스트 디렉터리를 사용한다면 다음과 같이 쓸 수 있다:
왼쪽은 호스트 디렉터리:
오른쪽은 컨테이너 내부 디렉터리:
여기서 가장 문제가 되기 쉬운 것은 경로를 잘못 쓰는 것이다.
컨테이너 원래 /app/config에 설정 파일이 있었는데, 빈 디렉터리를 마운트했다고 가정해보자:
그러면 컨테이너의 원래 /app/config가 호스트의 빈 디렉터리로 덮어쓰여진다.
프로그램을 시작하면 마치 설정 파일이 갑자기 사라진 것처럼 동작한다.
따라서 마운트하기 전에 호스트 디렉터리가 존재하는지, 그 안에 올바른 파일이 있는지 먼저 확인하는 것이 좋다.
10. 컨테이너 간에는 어떻게 연결해야 하는가
같은 Compose 프로젝트의 서비스는 서비스 이름으로 직접 연결할 수 있다.
예시:
애플리케이션이 데이터베이스에 연결할 때 주소는 다음과 같이 써야 한다:
컨테이너 IP를 다음과 같이 고정으로 쓰지 말자:
컨테이너가 다시 생성되면 IP 주소가 바뀔 수 있지만, 서비스 이름은 보통 변하지 않는다.
Docker 네트워크 확인:
네트워크 상세 정보 확인:
사용자 정의 네트워크 생성:
이미 존재하는 컨테이너를 네트워크에 추가:
두 컨테이너가 서로 접근할 수 없다면, 먼저 같은 Docker 네트워크에 있는지 확인한다.
11. 포트를 모두 공개 네트워크에 노출하지 말자
다음과 같은 설정:
는 일반적으로 호스트의 8080 포트를 컨테이너의 80 포트에 매핑하는 것을 의미한다.
기본적으로 모든 네트워크 인터페이스를 수신할 수 있다:
즉, 서버 방화벽이 허용하기만 하면 외부 장치가 이 포트에 직접 접근할 수 있다.
서비스를 호스트의 Nginx나 OpenResty에서만 사용한다면, 로컬 호스트에 바인딩할 수 있다:
이렇게 하면 외부 네트워크에서 직접 접근할 수 없고, 호스트를 통해서만 로컬로 연결할 수 있다.
데이터베이스와 Redis도 일반적으로 공개 네트워크에 직접 노출할 필요가 없다.
같은 Compose 네트워크의 애플리케이션은 직접 접근할 수 있다:
모든 내부 서비스에 일일이 ports를 설정할 필요가 없다.
12. 리소스 사용량 확인
모든 컨테이너의 CPU 및 메모리 사용량을 실시간으로 보기:
한 번만 출력:
특정 컨테이너 확인:
컨테이너 내부 프로세스 확인:
컨테이너가 갑자기 종료되었다면, 메모리 부족으로 시스템이 종료시킨 것은 아닌지 확인할 수 있다.
다음이 반환된다면:
이 컨테이너에 OOM Kill이 발생했음을 의미한다. 즉, 메모리 부족으로 커널이 강제 종료시킨 것이다.
종료 코드도 확인할 수 있다:
재시작 횟수 확인:
이 정보들은 컨테이너가 반복적으로 재시작되는 문제를 추적하는 데 큰 도움이 된다.
13. Docker 로그가 디스크를 가득 채우는 이유
Docker는 기본적으로 json-file를 사용하여 컨테이너 로그를 저장할 수 있다.
로그 로테이션을 설정하지 않으면 로그 파일이 계속해서 커진다.
수정:
다음을 추가:
의미는 다음과 같다:
수정 후 Docker를 재시작한다:
단, 새로운 로그 설정은 보통 이후에 생성되는 컨테이너에만 적용된다는 점에 유의하자.
이미 존재하는 컨테이너는 다시 생성해야 할 수 있다.
Compose에서도 서비스별로 개별 설정할 수 있다:
서버 디스크가 이유 없이 계속 줄어든다면, 데이터베이스나 업로드 파일뿐만 아니라 Docker 로그도 확인해야 한다.
14. Docker 공간 정리하기
중지된 컨테이너 삭제:
댕글링 이미지 삭제:
사용하지 않는 네트워크 삭제:
사용하지 않는 데이터 볼륨 삭제:
종합 정리:
이 명령어들은 모두 확인을 요구한다.
하지만 '사용하지 않음'이라는 말을 보고 그 안의 데이터에 가치가 없다고 생각해서는 안 된다.
예를 들어, 데이터베이스 컨테이너가 삭제된 후 해당 데이터 볼륨은 일시적으로 어떤 컨테이너도 사용하지 않을 수 있다. Docker는 이를 미사용 데이터 볼륨으로 판단하지만, 데이터베이스 파일은 여전히 그 안에 있다.
다음 명령어들을 실행하기 전에는 각별히 조심해야 한다:
특히:
일반적인:
는 보통 컨테이너와 네트워크만 삭제한다.
加上 -v 以后,还会删除项目使用的数据卷。如果 PostgreSQL、MySQL 或上传文件保存在这些数据卷中,数据也会一起消失。
정리하기 전에 적어도 다음을 먼저 확인하자:
不要把 docker system prune -a --volumes 当成日常清理命令。
이 명령어는 '이 모든 것을 더 이상 필요하지 않다고 확인했다'는 의미에 더 가깝다.
15. 디렉터리 권한 오류가 발생하면 어떻게 할까
컨테이너가 호스트 디렉터리를 마운트한 후, 프로그램이 다음과 같은 오류를 표시할 수 있다:
먼저 호스트 디렉터리의 권한을 확인한다:
파일의 UID와 GID를 확인:
그런 다음 컨테이너 내부에서 프로그램이 어떤 사용자로 실행되는지 확인:
컨테이너가 UID 1000, GID 1000을 사용한다면, 상황에 맞게 호스트 디렉터리의 소유자를 변경한다:
많은 사람들이 권한 문제를 만나면 바로 다음을 실행한다:
이렇게 하면 일시적으로 문제가 해결될 수 있지만, 보통 올바른 방법은 아니다.
777는 모든 사용자에게 읽기, 쓰기, 실행 권한을 부여하여 실제 UID, GID 및 디렉터리 소유권 문제를 가려버린다.
먼저 컨테이너가 어떤 사용자로 실행되는지 확인한 후, 그에 맞게 권한을 조정하는 것이 더 안정적이다.
16. 몇 가지 혼동하기 쉬운 부분
docker pull는 실행 중인 컨테이너를 업데이트하지 않는다
이미지를 내려받는 역할만 한다.
Compose 프로젝트를 업데이트하려면 다음도 필요하다:
docker restart는 새 설정을 적용하지 않는다
기존 컨테이너를 재시작할 뿐이다.
Compose 파일을 수정한 후에는 다음을 사용해야 한다:
컨테이너를 삭제해도 데이터 볼륨이 반드시 삭제되지는 않는다
일반적인:
는 보통 이름이 있는 데이터 볼륨을 삭제하지 않는다.
하지만:
는 컨테이너가 사용하는 익명 데이터 볼륨을 삭제할 수 있다.
컨테이너 내부에서 수동으로 수정한 파일은 신뢰할 수 없다
컨테이너가 다시 생성되면 수정 사항이 사라질 수 있다.
장기간 유지해야 할 설정은 Dockerfile, Compose 파일 또는 호스트 마운트 디렉터리에 작성해야 한다.
컨테이너 IP에 의존하지 말자
컨테이너 이름이나 Compose 서비스 이름으로 접근한다.
모든 포트를 공개 네트워크에 노출하지 말자
내부 서비스는 Docker 네트워크 안에만 두는 것이 좋다.
17. 내가 평소에 가장 자주 사용하는 명령어들
컨테이너 확인:
로그 확인:
컨테이너 접근:
리소스 확인:
디스크 사용량 확인:
Compose 설정 확인:
Compose 프로젝트 업데이트:
업데이트 후 상태 확인:
이 명령어들만으로도 대부분의 일상적인 배포, 업데이트, 문제 해결을 커버할 수 있다.
마치며
Docker에서 가장 오해하기 쉬운 점은 컨테이너를 작은 서버처럼 생각하기 쉽다는 점이다.
하지만 컨테이너는 가상 머신이 아니다.
컨테이너는 언제든지 삭제되고 다시 생성되며 교체될 수 있는 실행 환경에 더 가깝다. 정말 중요한 것은 컨테이너 내부에만 두어서는 안 된다.
프로그램은 이미지에, 설정은 Compose나 마운트 디렉터리에, 데이터는 데이터 볼륨이나 별도 저장소에 둔다. 컨테이너에 문제가 생기면 다시 생성하면 된다.
이 점을 이해하면 많은 Docker 명령어를 굳이 외우지 않아도 된다.
마지막으로 한 번 더 강조하자면, 다음 파라미터들을 볼 때는 실행하기 전에 잠시 멈추는 것이 좋다:
이것들이 항상 위험한 것은 아니지만, 보통 데이터 삭제, 강제 작업, 또는 컨테이너 권한 확장을 의미한다.
특히 다음 명령어는:
데이터가 백업되었는지 확인하기 전에는 함부로 실행하지 말자.