Skip to main content

Поясніть різницю між docker exec і docker attach.

docker exec і docker attach обидва способи взаємодії з running-container, але підключають до різних речей. Нерозуміння, що є що, веде до класу багів, де ти випадково вбиваєш прод, натиснувши Ctrl+C у неправильному вікні.

Теорія

TL;DR

  • docker exec = новий процес всередині container. Існуючий PID 1 container продовжує крутитися незалежно.
  • docker attach = підключення до stdio PID 1. Бачиш, що PID 1 бачить (його stdin/stdout/stderr).
  • Вбивство твого exec-shell: лише твій shell виходить. Container лишається running.
  • Вбивство/Ctrl+C твоєї attach-сесії: PID 1 отримує SIGINT. Container, скоріш за все, зупиниться.
  • Detach з attach без вбивства: Ctrl+P, потім Ctrl+Q (має бути -it-режим).
  • 99% часу хочеш exec. attach рідко.

Що робить docker exec

bash
$ docker run -d --name web nginx $ docker exec -it web sh / # ps aux USER PID COMMAND root 1 nginx: master process nginx 29 nginx: worker process root 45 sh # ← мій shell, окремий процес root 51 ps aux / # exit # Container ще running.

Shell це процес 45 всередині container. Крутиться поряд з nginx (PID 1 і 29). Вийди з shell → процес 45 завершується, nginx не зачеплено, container ще running.

Що робить docker attach

bash
$ docker run -d --name web nginx $ docker attach web # (тиша, stdio nginx, без поточного output) # Натисни Ctrl+C # nginx отримує SIGINT → виходить → container зупиняється

Ти підключений до stdio nginx. Усе, що nginx друкує, ти бачиш. Усе, що набираєш, nginx отримує на stdin. Ctrl+C шле SIGINT на nginx. nginx виходить. Container завершується.

Для debug це майже ніколи не те, що хочеш.

Side-by-side

docker execdocker attach
Створює процестак (новий)ні (підключення до PID 1)
Вбиває container на Ctrl+Cнітак (шле SIGINT на PID 1)
Ctrl+P, Ctrl+Q для безпечного detachn/aтак
Бери дляdebug, inspect, ad-hoc командREPL як PID 1, console-app
Поширена помилкамайже жодноївипадкове вбивство проду

Detach з attach

Escape-послідовність, щоб вийти з attach без вбивства PID 1:

Ctrl+P, Ctrl+Q

Має бути у -it-режимі (interactive + TTY). Без -t немає terminal-послідовності для інтерпретації; без -i stdin закритий. Без escape-послідовності твої лише опції це Ctrl+C (вбиває container) або kill docker-процесу ззовні.

У shell, що override Ctrl+P (деякі tmux-конфіги), можливо, треба перемапити перед attach.

Коли attach реально корисний

REPL як PID 1

bash
docker run -d --name nodejs node:22 node # nodejs running як PID 1, REPL чекає input docker attach nodejs > 1+1 2 > .exit # Ctrl+P, Ctrl+Q для detach натомість

Python або Node REPL, запущений як PID 1, приймає input лише через attach. exec породив би новий shell, що не те, що хочеш.

Console-based застосунки

Застосунки, що взаємодіють через stdio як свій primary-інтерфейс (chess-сервери, console-ігри, певні admin-tools), потребують attach.

Watching live PID 1 output

bash
docker attach web # nginx access-лог стрімить у реальному часі

Хоча docker logs -f web зазвичай кращий вибір, той самий ефект, без ризику вбивства.

Типові помилки

Бери attach, коли хотів exec

bash
# НЕПРАВИЛЬНО docker attach web # підключається до stdio nginx # Натисни Ctrl+C → вбиває nginx → container зупиняється → outage # ПРАВИЛЬНО docker exec -it web sh # новий shell # Натисни Ctrl+D (або exit) → shell завершується → container не зачеплено

Найпоширеніша attach-помилка це сприймати його як exec. Та сама інтуїція («підключитися до running-container»), дуже різні наслідки.

Забути -it з attach

bash
docker attach --no-stdin web # вимикає stdin # більше не можна Ctrl+P, Ctrl+Q для detach (без TTY) # тільки Ctrl+C, що вбиває

Якщо мусиш attach без TTY, прийми, що Ctrl+C твій єдиний вихід. Краще: просто не роби.

Використовувати --sig-proxy=false у attach без розуміння

bash
docker attach --sig-proxy=false web # Ctrl+C тепер НЕ propagate на PID 1, container виживає

Обхід для безпечнішого attach. Але якщо тобі це треба, ти, скоріш за все, хотів exec.

Спроба attach на stopped-container

bash
$ docker attach stopped-web Error: container is not running

Attach потребує running. Бери docker start -ai stopped-web, щоб оживити exited-container з прикріпленим stdio (інше, але пов'язане).

Реальне застосування

  • exec для 99% debug: shell у running-container, one-off команда, inspect файли, check env. Безпечно і стандартно.
  • attach конкретно для: взаємодії з REPL як PID 1 (рідко), console-app, де stdio це API (рідко), watching live-output без docker logs (рідко; logs зазвичай краще).
  • Ніколи attach на прод-веб-сервер, який не хочеш вбити. Бери docker logs -f.

Питання для поглиблення

Q: Чому Ctrl+C вбиває container з attach, але не з exec?


A: З attach ти підключений до stdio PID 1. Ctrl+C шле SIGINT на PID 1 (головний процес). PID 1 виходить, container виходить. З exec твій shell це окремий процес; Ctrl+C вбиває shell, не PID 1.

Q: Чи можуть кілька user attach до того самого container?


A: Так, усі бачать output PID 1 і ділять stdin. Працює як screen-сесія. Корисно для collaborative-debug; ризиково, бо хтось може випадково Ctrl+C.

Q: Яка різниця між docker attach і docker exec -it container bash?


A: Attach підключається до stdio існуючого PID 1. Exec створює новий bash-процес всередині container. Новий bash незалежний; PID 1 shared.

Q: Що дає docker run -d потім docker attach vs docker run (без -d)?


A: Той самий результат (бачиш output PID 1). Комбо -d + attach корисне, коли хочеш стартувати detached, зробити інші речі, тоді attach пізніше. docker run без -d це attach-by-default.

Q: (Senior) Коли б ти написав custom-container, що потребує docker attach понад docker exec?


A: Коли мета container Є взаємодія через stdio як primary-інтерфейс, як кастомний REPL, інтерактивний admin-tool, що user запускає періодично, а не як daemon, або game-сервер з admin-консоллю. Навіть тоді сучасні дизайни віддають перевагу HTTP або gRPC API над stdio-attachment заради usability і multi-user-підтримки. Pure-stdio інтерфейси все рідше; якщо тягнешся за attach, спитай, чи твій дизайн часом не релікт.

Приклади

Безпечний debug з exec

bash
# Прод-веб-сервер. Інспектуй БЕЗ ризику outage. docker exec -it web sh / # cat /etc/nginx/nginx.conf / # netstat -tlnp / # ps aux / # exit # nginx ніколи не помітив; uptime збережено.

Ризикований live-tail з attach

bash
# НЕ роби це у проді docker attach prod-web # Стрімить live access-логи. # Випадковий Ctrl+C → SIGINT → nginx виходить → 502 для юзерів. # Краще: docker logs -f prod-web # той самий output, безпечно

Detach демо

bash
$ docker run -d --name pyrepl python:3.13 python # Python REPL чекає у фоні як PID 1 $ docker attach pyrepl >>> 2 + 2 4 >>> # Тепер натисни Ctrl+P, потім Ctrl+Q read escape sequence $ docker ps --filter name=pyrepl STATUS NAMES Up 2 minutes pyrepl # ще running

Detach безпечно; container тримає REPL живим; можна re-attach пізніше.

Коли attach реально потрібен

bash
# Кастомний container, спроектований як інтерактивний tool docker run -d --name console myorg/admin-console:1.0 docker attach console admin> help admin> reset --user 42 admin> exit # Кастомна 'exit' команда каже застосунку завершитися.

Якщо дизайн застосунку «говори зі мною через stdio», attach це єдиний шлях. Але цей дизайн нечастий.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Коментарі

Ще немає коментарів