Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Поясніть різницю між docker exec і docker attach.». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**`docker exec`** запускає НОВИЙ процес всередині running-container. **`docker attach`** підключає до stdio PID 1. Вбивство exec-процесу лишає container running; вбивство attached PID 1 зупиняє container. ```bash docker exec -it web sh # новий shell, окремий процес, виходити безпечно docker attach web # підключити до stdio nginx, Ctrl+C зупиняє nginx ``` **Головне:** `exec` це те, що майже завжди хочеш для debug або inspect. `attach` для кейсів, коли треба взаємодіяти з самим PID 1 — REPL як PID 1, console-based застосунки. Detach з attach через Ctrl+P, Ctrl+Q (НЕ вбиває container).Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**`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 exec` | `docker attach` | |---|---|---| | Створює процес | так (новий) | ні (підключення до PID 1) | | Вбиває container на Ctrl+C | ні | **так** (шле SIGINT на PID 1) | | Ctrl+P, Ctrl+Q для безпечного detach | n/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 це єдиний шлях. Але цей дизайн нечастий.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.