docker 컨테이너 접속 — exec와 attach 차이, 안 될 때 원인
docker 컨테이너 접속은 docker exec -it <컨테이너> bash가 정답입니다. docker attach는 새 셸을 여는 게 아니라 이미 돌고 있는 메인 프로세스(PID 1)의 화면에 붙는 것이라, 잘못 빠져나오면 컨테이너가 멈춥니다. 접속이 안 된다면 원인은 대개 셋입니다 — 컨테이너가 멈춰 있거나(is not running), 일시정지 상태거나, 이미지에 bash가 없는 경우(alpine 계열)입니다. 아래 명령과 에러는 Docker 29.5.2에서 직접 실행해 확인한 것입니다.
1. 기본 — docker exec -it
먼저 대상 컨테이너의 이름이나 ID를 확인합니다.
$ docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Status}}'
CONTAINER ID NAMES STATUS
91afab4956a9 demo3 Up 2 seconds
4522e6256f68 demo1 Up 2 seconds
이름(또는 ID 앞자리)으로 셸을 띄웁니다.
docker exec -it demo1 bash
# bash가 없는 이미지(alpine 등)면
docker exec -it demo1 sh
| 옵션 | 뜻 |
|---|---|
-i |
표준 입력을 열어 둔다(명령을 타이핑할 수 있게) |
-t |
가상 터미널(TTY)을 붙인다(프롬프트가 제대로 보이게) |
-u root |
루트로 들어간다(패키지 설치 등 권한 필요할 때) |
-w /경로 |
시작 디렉터리 지정 |
-e KEY=VAL |
그 명령에만 적용할 환경변수 |
$ docker exec -u root demo1 whoami
root
$ docker exec -w /etc demo1 pwd
/etc
$ docker exec -e FOO=bar demo1 sh -c 'echo $FOO'
bar
2. exec와 attach 차이 — 이게 핵심
이름이 비슷해 헷갈리지만 하는 일이 다릅니다.
docker exec |
docker attach |
|
|---|---|---|
| 하는 일 | 컨테이너 안에서 새 프로세스를 실행 | 이미 돌고 있는 PID 1의 입출력에 연결 |
| 빠져나올 때 | exit 해도 컨테이너는 계속 실행 |
Ctrl-C는 PID 1에 SIGINT 전달 → 멈출 수 있음 |
| 쓰는 상황 | 셸로 들어가 파일·설정 확인 (대부분 이것) | 앱 로그를 실시간으로 그 자리에서 볼 때 |
실제로 exec로 띄운 셸을 종료해도 컨테이너는 살아 있습니다.
$ docker exec demo1 sh -c 'exit 0'
$ docker inspect -f '{{.State.Running}}' demo1
true
공식 문서도 exec로 실행한 명령은 "컨테이너의 주 프로세스(PID 1)가 돌아가는 동안에만 실행되며, 컨테이너가 재시작돼도 다시 실행되지 않는다"고 설명합니다. 반면 attach 문서는 "--sig-proxy가 기본값 true이면 CTRL-c가 컨테이너에 SIGINT를 보낸다"고 적고 있습니다.
attach로 들어갔다면 Ctrl-C 대신 Ctrl-p → Ctrl-q로 빠져나오세요. 공식 문서 기준, 컨테이너를 -i -t로 실행했다면 이 조합으로 컨테이너를 계속 돌린 채 분리됩니다.
3. 접속이 안 될 때 — 에러별 원인
① container ... is not running
$ docker exec demo1 bash -c 'echo hi'
Error response from daemon: container 4522e6256f... is not running
컨테이너가 멈춰 있습니다. docker ps -a로 상태를 보고 시작한 뒤 접속합니다.
docker start demo1
docker exec -it demo1 bash
시작하자마자 다시 죽는다면 메인 프로세스가 바로 종료되는 이미지입니다. 그럴 땐 컨테이너를 새로 띄우면서 셸을 메인 프로세스로 지정합니다.
docker run -it --rm amazonlinux:2023 bash
② Container ... is paused
$ docker exec p1 sh -c 'echo x'
Error response from daemon: Container p1 is paused, unpause the container before exec
docker unpause p1 후 접속합니다.
③ "bash": executable file not found in $PATH
$ docker exec -it demo2 bash
OCI runtime exec failed: exec failed: unable to start container process:
exec: "bash": executable file not found in $PATH
$ docker exec -it demo2 sh
/ # ← sh는 있다
alpine 같은 경량 이미지에는 bash가 없습니다. sh로 접속하거나, 꼭 필요하면 컨테이너 안에서 설치합니다(apk add bash). 이미지 크기를 위해 일부러 뺀 것이니 sh로 충분한 작업이면 그냥 쓰는 편이 낫습니다.
④ cannot attach stdin to a TTY-enabled container
스크립트·CI처럼 터미널이 없는 환경에서 -it를 쓸 때 나옵니다. 그럴 땐 -t를 빼고 docker exec 컨테이너 명령 형태로 실행하면 됩니다.
4. docker compose를 쓴다면
compose로 띄운 서비스는 컨테이너 이름 대신 서비스 이름으로 들어갑니다.
docker compose exec app bash
# 컨테이너가 안 떠 있어도 새로 띄워 한 번 실행하고 싶을 때
docker compose run --rm app bash
자주 묻는 질문 (FAQ)
Q. 접속해서 설치한 패키지가 재시작하면 사라집니다.
docker exec로 만든 변경은 컨테이너 계층에만 남고, 컨테이너를 새로 만들면 사라집니다. 영구적으로 필요하면 Dockerfile에 넣어 이미지를 다시 빌드해야 합니다.
Q. 컨테이너 이름이 기억나지 않아요.
docker ps(실행 중)와 docker ps -a(전체)로 확인합니다. ID는 앞 3~4자리만 써도 구분되면 인식됩니다.
Q. 파일 하나만 꺼내거나 넣고 싶은데요.
접속할 필요 없이 docker cp 컨테이너:/경로 ./로컬경로(또는 반대 방향)를 쓰면 됩니다.
Q. root로 들어갔는데 명령이 없다고 나옵니다.
경량 이미지에는 ps·vi·curl 같은 기본 도구도 빠져 있는 경우가 많습니다. 필요한 것만 설치하거나, 디버깅 도구가 든 이미지로 확인하세요.
마무리
정리하면 접속은 docker exec -it <이름> bash(없으면 sh), attach는 PID 1에 붙는 것이라 Ctrl-p Ctrl-q로 빠져나오기, 그리고 접속이 안 되면 멈춤·일시정지·bash 없음 순으로 확인하면 됩니다. 에러 메시지가 원인을 그대로 말해 주니 첫 줄부터 읽는 습관이 제일 빠릅니다.
📚 참고 출처 (2026년 7월 21일 확인 · 명령과 에러는 Docker 29.5.2에서 직접 실행)
· docker exec 공식 문서
· docker attach 공식 문서

COMMENTS