Skip to main content

Як запустити контейнер з Docker image?

docker run це найвживаніша команда у всьому Docker CLI. Вона тягне image, якщо треба, створює container і стартує його, усе одним махом. Знання шести флагів, що з'являються у кожній прод-команді, це і є більшість того, що значить «використовувати Docker».

Теорія

TL;DR

  • Анатомія: docker run [FLAGS] IMAGE[:TAG] [COMMAND] [ARGS...]
  • Image йде між флагами і будь-яким override команди. Усе після image замінює CMD image.
  • Шість флагів покривають 90% кейсів: -d, --name, -p, -v, -e, --rm.
  • docker run = docker pull (якщо нема) + docker create + docker start. Три операції в одній команді.
  • Бери --rm для одноразових команд (авто-cleanup на виході). Бери -d + --restart для довгоживучих сервісів.

Швидкий приклад

bash
# Мінімум: 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 — запуск у фоні

bash
docker run -d nginx:1.27-alpine # Повертає одразу container ID; container продовжує крутитися.

Без -d CLI стрімить логи і виходить, коли container виходить. З -d ти миттєво повертаєшся у shell.

--name — задай йому ім'я

bash
docker run -d --name web nginx:1.27-alpine # Тепер можна: docker stop web, docker logs web тощо. # Без --name Docker дає випадкове ім'я типу "sleepy_einstein".

-p / --publish — публікувати порти

bash
# Формат: 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 — монтувати сховище

bash
# 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 myapp

Named volume для персистентного стану, bind mount для live-reload dev або конкретних host-шляхів.

-e / --env — env-змінні

bash
# Одна змінна 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 на виході

bash
# Одноразова команда, container зникає по завершенні docker run --rm -it alpine sh # Коли вийдеш з shell, container видаляється (без orphan).

Робить ad-hoc команди схожими на запуск локальних скриптів. Без --rm кожен exited container накопичується, поки не docker rm його.

Флаги для довгоживучих сервісів

bash
--restart=no # дефолт: не рестартити --restart=on-failure # рестартити лише якщо exit code != 0 --restart=always # рестартити завжди (навіть при рестарті daemon) --restart=unless-stopped # як 'always', але поважає ручний docker stop

Для прод-сервісів зазвичай --restart=unless-stopped.

Все разом: реалістична команда

bash
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:

bash
# Дефолтний 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 для сервісу

bash
$ docker run nginx:1.27-alpine # Термінал висить, стрімить nginx-логи. # Ctrl+C зупиняє container.

Для чого-небудь крім одноразової команди зазвичай хочеш -d.

Неправильний напрямок порту у -p

bash
# НЕПРАВИЛЬНО: думає, що 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

bash
# НЕПРАВИЛЬНО: -p трактується як аргумент для nginx docker run nginx:1.27-alpine -p 8080:80 # ПРАВИЛЬНО: флаги перед image docker run -p 8080:80 nginx:1.27-alpine

Docker припиняє парсити флаги на імені image. Усе після це команда для container, не для docker run.

Запускати інтерактив без -it

bash
# НЕПРАВИЛЬНО: 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: швидкий тест

bash
$ 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-сервіс

bash
$ 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 web

Detached, named, restart-on-reboot, два порти опубліковано, серти у named volume, конфіг bind-mounted read-only, ліміт пам'яті.

Перевизначення CMD image для дебагу

bash
# Дефолтний CMD image стартує postgres. Хочемо shell. $ docker run --rm -it postgres:16 bash # Або скіпни entrypoint повністю $ docker run --rm -it --entrypoint sh postgres:16

Корисно, коли старт image падає і треба полазити всередині.

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

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

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

Коментарі

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