Як запустити контейнер з Docker image?
docker run це найвживаніша команда у всьому Docker CLI. Вона тягне image, якщо треба, створює container і стартує його, усе одним махом. Знання шести флагів, що з'являються у кожній прод-команді, це і є більшість того, що значить «використовувати Docker».
Теорія
TL;DR
- Анатомія:
docker run [FLAGS] IMAGE[:TAG] [COMMAND] [ARGS...] - Image йде між флагами і будь-яким override команди. Усе після image замінює
CMDimage. - Шість флагів покривають 90% кейсів:
-d,--name,-p,-v,-e,--rm. docker run=docker pull(якщо нема) +docker create+docker start. Три операції в одній команді.- Бери
--rmдля одноразових команд (авто-cleanup на виході). Бери-d+--restartдля довгоживучих сервісів.
Швидкий приклад
# Мінімум: pull і run
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
Digest: sha256:9f8e7d6c...
Status: Downloaded newer image for hello-world:latest
Hello from Docker!Daemon помітив, що image нема, стягнув з Docker Hub, потім запустив. Одна команда, три операції.
Шість флагів, які ти будеш використовувати щодня
-d / --detach — запуск у фоні
docker run -d nginx:1.27-alpine
# Повертає одразу container ID; container продовжує крутитися.Без -d CLI стрімить логи і виходить, коли container виходить. З -d ти миттєво повертаєшся у shell.
--name — задай йому ім'я
docker run -d --name web nginx:1.27-alpine
# Тепер можна: docker stop web, docker logs web тощо.
# Без --name Docker дає випадкове ім'я типу "sleepy_einstein".-p / --publish — публікувати порти
# Формат: HOST_PORT:CONTAINER_PORT
docker run -d -p 8080:80 nginx:1.27-alpine
# Порт 80 container доступний на http://localhost:8080
# Прив'язатися до конкретного host-інтерфейсу
docker run -d -p 127.0.0.1:8080:80 nginx:1.27-alpine
# Тільки loopback, не публічна мережа
# Випадковий host-порт (авто-присвоєний)
docker run -d -p 80 nginx:1.27-alpine
# docker port <name>, щоб дізнатися, який host-порт обраноБез -p container ізольований на своїй мережі: доступний з інших container на тій самій мережі, але не з host.
-v / --volume — монтувати сховище
# Named volume
docker run -d -v pgdata:/var/lib/postgresql/data postgres:16
# Bind mount (конкретний host-шлях)
docker run -d -v /home/me/site:/usr/share/nginx/html nginx:1.27-alpine
# Read-only mount
docker run -d -v ./conf:/etc/myapp:ro myappNamed volume для персистентного стану, bind mount для live-reload dev або конкретних host-шляхів.
-e / --env — env-змінні
# Одна змінна
docker run -e POSTGRES_PASSWORD=devpass postgres:16
# Пробросити з shell
docker run -e API_KEY postgres:16
# З файлу
docker run --env-file .env postgres:16Не передавай secret через -e у проді, вони показуються у docker inspect, image-history і process listing. Бери Swarm secret, BuildKit secret mount або external secret manager.
--rm — авто-cleanup на виході
# Одноразова команда, container зникає по завершенні
docker run --rm -it alpine sh
# Коли вийдеш з shell, container видаляється (без orphan).Робить ad-hoc команди схожими на запуск локальних скриптів. Без --rm кожен exited container накопичується, поки не docker rm його.
Флаги для довгоживучих сервісів
--restart=no # дефолт: не рестартити
--restart=on-failure # рестартити лише якщо exit code != 0
--restart=always # рестартити завжди (навіть при рестарті daemon)
--restart=unless-stopped # як 'always', але поважає ручний docker stopДля прод-сервісів зазвичай --restart=unless-stopped.
Все разом: реалістична команда
docker run -d \
--name api \
--restart=unless-stopped \
-p 3000:3000 \
-v api_uploads:/app/uploads \
-v ./api/.env:/app/.env:ro \
-e NODE_ENV=production \
--memory=512m \
--cpus=0.5 \
--health-cmd='curl -f http://localhost:3000/health' \
--health-interval=30s \
myapp:1.0Це по суті як виглядає прод single-host deploy, перш ніж ти переходиш на Compose, Swarm або Kubernetes.
Перевизначення CMD image
Усе після імені image замінює дефолтну команду image:
# Дефолтний CMD image (зазвичай сервіс)
docker run nginx:1.27-alpine
# Перевизначити CMD одноразовою командою
docker run nginx:1.27-alpine sh -c 'nginx -V'
# Запустить nginx -V і вийде, замість того щоб запускати daemon.
# Кинутися у shell для дебагу
docker run -it nginx:1.27-alpine shЯкщо image має ENTRYPOINT, твої trailing args стають його аргументами. Використовуй --entrypoint /bin/sh, щоб повністю перевизначити entrypoint при дебагу.
Типові помилки
Забути -d для сервісу
$ docker run nginx:1.27-alpine
# Термінал висить, стрімить nginx-логи.
# Ctrl+C зупиняє container.Для чого-небудь крім одноразової команди зазвичай хочеш -d.
Неправильний напрямок порту у -p
# НЕПРАВИЛЬНО: думає, що 80 на host, 8080 у container
docker run -p 80:8080 nginx:1.27-alpine
# Ніщо не слухає порт 8080 у container; на host:80 connection refused.
# ПРАВИЛЬНО: HOST:CONTAINER
docker run -p 8080:80 nginx:1.27-alpineПорядок: host перший, container другий. Поширений gotcha.
Класти флаги після імені image
# НЕПРАВИЛЬНО: -p трактується як аргумент для nginx
docker run nginx:1.27-alpine -p 8080:80
# ПРАВИЛЬНО: флаги перед image
docker run -p 8080:80 nginx:1.27-alpineDocker припиняє парсити флаги на імені image. Усе після це команда для container, не для docker run.
Запускати інтерактив без -it
# НЕПРАВИЛЬНО: shell виходить одразу, бо нема TTY
docker run alpine sh
# ПРАВИЛЬНО: -i тримає stdin відкритим, -t виділяє TTY
docker run -it alpine sh-it (або -i -t) це магічна формула для інтерактивних сесій.
Реальне застосування
- Локальна розробка:
docker run --rm -it -v $PWD:/work node:22 npm test— одноразовий container, монтує поточну директорію, проганяє тести, зникає. - Staging/single-host deploy: довга форма
docker run -d --name api --restart=unless-stopped ..., часто загорнута у shell-скрипт або Compose-файл. - CI/CD:
docker run --rm myapp:test npm run testдає exit code, який CI використовує для pass/fail. - Одноразові DB-міграції:
docker run --rm --network mynet -e DATABASE_URL=... migrator:1.0запускається і зникає.
Питання для поглиблення
Q: Яка різниця між docker run і docker create?
A: create виділяє container, але не стартує; треба docker start після. run робить обидва. create корисний, коли хочеш налаштувати container і запустити пізніше, або подивитися його config (docker inspect) перед стартом.
Q: Як виконати команду в існуючому container замість запуску нового?
A: docker exec. docker run завжди створює новий container; docker exec запускає команду у вже запущеному. Для shell у існуючий: docker exec -it <name> sh.
Q: Чому мій інтерактивний docker run -it одразу виходить?
A: Скоріш за все, бо ENTRYPOINT або CMD image це не shell. Спробуй docker run -it --entrypoint sh <image>, щоб форсувати shell. Або глянь у docs image, яка правильна команда.
Q: Чи можу я запустити container, не давши йому ім'я?
A: Так, Docker генерує випадкове (musing_einstein, crazy_curie). Нормально для одноразових --rm команд. Для чогось, на що будеш посилатися пізніше (логи, exec, stop), --name економить набирання.
Q: (Senior) Чому у проді можеш уникати docker run і брати Compose або Kubernetes?
A: Довга docker run команда це імперативний стан, що живе у чийсь shell-history. Compose робить його декларативним (у compose.yaml), version-controllable, відтворюваним. Kubernetes іде далі (multi-host, self-healing, rolling updates). Для одноразового сервісу docker run нормально. Для чого-небудь, що будеш redeploy'ити, декларативно перемагає імперативно.
Приклади
Локальний one-off: швидкий тест
$ docker run --rm -it \
-v $PWD:/work \
-w /work \
node:22-alpine \
npm test
# Тести крутяться всередині container, вивід стрімить у термінал,
# container видаляється по завершенні. Лептоп лишається чистим.--rm, -it, -v $PWD:/work, -w /work: чотири флаги, що роблять container схожим на локальний скрипт.
Production-style web-сервіс
$ docker run -d \
--name web \
--restart=unless-stopped \
-p 80:80 -p 443:443 \
-v web_certs:/etc/nginx/certs \
-v ./nginx.conf:/etc/nginx/nginx.conf:ro \
--memory=256m \
nginx:1.27-alpine
$ docker ps --filter name=web
CONTAINER ID IMAGE STATUS PORTS NAMES
f7c2a9e1b8d4 nginx:1.27-alpine Up 3 seconds 0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp webDetached, named, restart-on-reboot, два порти опубліковано, серти у named volume, конфіг bind-mounted read-only, ліміт пам'яті.
Перевизначення CMD image для дебагу
# Дефолтний CMD image стартує postgres. Хочемо shell.
$ docker run --rm -it postgres:16 bash
# Або скіпни entrypoint повністю
$ docker run --rm -it --entrypoint sh postgres:16Корисно, коли старт image падає і треба полазити всередині.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів