Docker Compose, щоб контейнер працював


94

Я хочу запустити службу з docker-compose і тримати контейнер запущеним, щоб я міг отримати його IP-адресу через 'docker inspect'. Однак контейнер завжди виходить відразу після запуску.

Я намагався додати "command: [" sleep "," 60 "]" та інші речі до docker-compose.yml, але всякий раз, коли я додаю рядок з "command: ...", я не можу викликати "docker-compose up" оскільки я отримаю повідомлення "Не вдається запустити контейнер ..... Помилка системи: недійсний символ 'k' шукає початок значення"

Я також спробував додати "CMD sleep 60" і ще щось до самого Dockerfile, але ці команди, здається, не виконуються.

Чи є простий спосіб зберегти контейнер живим або виправити одну з моїх проблем?

EDIT: Ось файл Compose, який я хочу запустити:

version: '2'
services:
  my-test:
    image: ubuntu
    command: bash -c "while true; do echo hello; sleep 2; done"

Це працює нормально, якщо я почну це з docker-compose під OS X, але якщо я спробую те саме під Ubuntu 16.04, це дасть мені вище повідомлення про помилку.

Якщо я спробую підхід з Dockerfile, Dockerfile виглядає так:

FROM ubuntu:latest
CMD ["sleep", "60"]

Що, здається, нічого не робить

РЕДАГУВАТИ 2: Я повинен виправити себе, виявилося, що це та сама проблема з Dockerfile та docker-compose.yml: Кожного разу, коли я додаю або "CMD ..." до Dockerfile АБО додати "command ..." до файл створення, я отримую вище помилку з недійсним символом. Якщо я видалю обидві команди, це працює бездоганно.


1
Будь ласка, включіть docker-compose.yml, Dockerfile та будь-які сценарії, які ви намагаєтеся налагодити.
BMitch

Відповіді:


119

Щоб продовжити роботу контейнера під час запуску docker-compose, скористайтеся наступною командою

command: tail -F anything

Отже, ваш docker-compose.yml стає

version: '2'
services:
  my-test:
    image: ubuntu
    command: tail -F anything

і ви можете запустити оболонку, щоб потрапити в контейнер, використовуючи наступну команду

docker exec -i -t composename_my-test_1 bash

де composenameназва, яка docker-composeдодається до ваших контейнерів.


1
Як зупинити контейнер, коли закінчите з ним? Чи існує тип команди Ctrl + C, Ctrl + Z? Зараз я повинен закрити термінал, щоб вийти.
mac10688

Якщо ви знаходитесь всередині контейнера, ви можете ввести текст, exitщоб повернутися до хост-машини. Якщо ви перебуваєте на своєму хості, ви можете зупинити контейнер за допомогою Docker ( docker stop composename_my-test_1) або Docker Compose ( docker-compose stop).
Нік Сеттьє

2
@ Alexis.Rolland Якщо ви готові задати нове запитання SO та поділитися деякими деталями, то я був би з радістю поглянути на нього. Я припускаю, що ваша помилка має щось спільне з внутрішніми елементами одного з ваших контейнерів, на відміну від проблеми з Docker або операційною системою вашого хосту.
Нік Сеттьє

1
@ mac10688, якщо у підключеному сеансі контейнера немає запиту, спробуйте ctrl-d від'єднати
Старк

5
/dev/nullбуло б краще на місці для anythingкоманди хвоста ref. stackoverflow.com/a/48732671/248616
Nam G VU

80

Ви можете використовувати ttyопцію конфігурації.

version: '3'

services:
  app:
    image: node:8
    tty: true           # <-- This option

Примітка: Якщо ви використовуєте Dockerfile для зображення та CMDу Dockerfile, ця опція не працюватиме; однак ви можете використовувати entrypointопцію у файлі створення, яка очищає файл із файлу CMDDocker.


7
Це працює, і здається менш удачним, ніж tail -f /dev/null. Завдяки цьому я можу запустити контейнерне середовище розробника з підключеною базою даних postgres docker-compose upі запустити оболонку через інший термінал, використовуючи docker exec.
Psiloc

1
Хоча в даний час НЕ добре документовано. Це офіційні варіанти, які дозволять досягти того самого ефекту, що tail -f /dev/nullі tail -f anything, або дивіться тут: docs.docker.com/compose/compose-file
b01

2
@ABMRuman & Psiloc, Він працює лише тоді, коли ви не використовуєте "команду" у файлі docker-compose.yml. При використанні "команди" вам потрібен ще один злом - отже, хвіст -F тут ідеально підходить.
асафель,

Це повинна бути найкраща відповідь, якщо ви використовуєте точку входу в dockerfile.
DDKV587,

53

На основі коментаря @aanand на GitHub 26 серпня 2015 року , можна використовувати tail -f /dev/nullin docker-compose, щоб зберегти контейнер запущеним.

приклад docker-compose.yml

version: '3'
services:
  some-app:
    command: tail -f /dev/null

Чому ця команда?

Єдиною причиною вибору цього варіанту було те, що він отримав велику кількість пальців на GitHub, але відповідь з найбільшою оцінкою не означає, що це найкраща відповідь. Друга причина була прагматичною, оскільки питання повинні були вирішуватися якомога швидше через терміни.


2
чому саме ця команда? Що робить його кращим за інших? У моєму випадку тільки початок
баша

@ N4ppeL Гарне запитання. Єдина причина, по якій я вибрав цей варіант, полягала в тому, що він отримав велику кількість пальців на github, але відповідь з найбільшою оцінкою не означає, що це найкраща відповідь. Друга причина була прагматичною, оскільки мені довелося вирішити питання якомога швидше через терміни.
030

17
  • Створіть файл із назвою docker-compose.yml
  • Додайте до файлу наступне
version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    tty: true
  • Залишаючись в одному каталозі, запустіть docker-compose up -dз терміналу
  • Запустіть, docker psщоб отримати ідентифікатор контейнера або ім'я
  • Можна бігати docker inspect $container_id
  • Ви можете увійти в контейнер і запустити оболонку bash docker-compose exec ubuntu /bin/bashабоdocker-compose exec ubuntu /bin/sh
  • Закінчивши, переконайтеся, що ви знаходитесь поза контейнером, і біжіть docker-compose down

Ось невеликий скрипт bash ( my-docker-shell.sh) для створення файлу складання докера, запуску контейнера, входу в контейнер, а потім остаточного очищення контейнера докера та файлу складання докера при виході з системи.

#!/bin/bash

cat << 'EOF' > ./docker-compose.yml
---

version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    command: /bin/bash
    # tty: true

...
EOF

printf "Now entering the container...\n"
docker-compose run ubuntu bash
docker-compose down

rm -v ./docker-compose.yml

1
Хоча це не була фактичною відповіддю на питання, я знайшов це надзвичайно цінним! Я пішов далі, щоб використовувати глобальні функції bashrc
loopmode

8

У файлі Docker ви можете використовувати команду:

{CMD sleep infinity}

2

Як зазначив коментатор, нам доведеться побачити відповідний Dockerfile, щоб дати вам повну відповідь, але це дуже поширена помилка. Я можу гарантувати, що команда, яку ви намагаєтеся виконати, запускає фоновий процес. Це може бути команда, яку ви виконували б у ситуаціях, що не стосуються Docker, але робити це неправильно у файлі Docker. Наприклад, якщо те, що ви запускаєте, зазвичай визначається як системна служба, ви можете використовувати щось на зразок "systemctl start". Це розпочне процес у фоновому режимі, який не буде працювати. Ви повинні запускати процес на передньому плані, тому весь процес буде блокований.


0

Лише коротка примітка

Я протестував одне зображення на основі golang, тож, коли я зателефоную docker-compose downсюди, отримаю:

version: "3.1"
...
command: tail -f /dev/null   # stopping container takes about 10 sec.
tty: true                    # stopping container takes about 2 sec.

Інформація про мою систему:

Ubuntu 18.04.4 LTS (64-bit)
Docker version 19.03.6, build 369ce74a3c
docker-compose version 1.26.0, build d4451659

-3

Гаразд, я знайшов свою помилку. У файлі Docker для зображення, що використовується для композиції, я вказав, що базовим зображенням має бути ubuntu: latest, але раніше я сам створив образ, який називається ubuntu, і це зображення не працювало. Тому я не використовував оригінальний образ ubuntu, а скоріше корумповану версію власного образу, який також називається ubuntu.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.