Я использую docker-compose
.
Некоторые команды вроде up -d service_name
или start service_name
возвращаются сразу, и это очень полезно, если вы не хотите, чтобы работающие контейнеры зависели от состояния оболочки, как это происходит с обычным up service_name
. Единственный вариант использования - запускать его с какого-то сервера непрерывной интеграции / доставки.
Но этот способ запуска / запуска служб не дает никакой обратной связи о фактическом состоянии службы впоследствии.
В Справочник по интерфейсу командной строки Docker Compose для up
команда упоминает соответствующий вариант, но, что касается версии 1.7.1
, он является взаимоисключающим с -d
:
--abort-on-container-exit Stops all containers if any container was stopped. *Incompatible with -d.*
docker-compose ps -q <service_name>
будет отображать идентификатор контейнера независимо от того, запущен он или нет, пока он был создан.docker ps
показывает только те, которые действительно работают.Объединим эти две команды:
if [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then
echo "No, it's not running."
else
echo "Yes, it's running."
fi
docker ps
по умолчанию показывает сокращенную версию идентификаторов, поэтому нам нужно указать --no-trunc
флаг.
ОБНОВИТЬ: Он выдавал предупреждение об использовании grep, если служба не работала. Благодаря @Dzhuneyt, вот обновленный ответ.
if [ -z `docker-compose ps -q <service_name>` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q <service_name>)` ]; then
echo "No, it's not running."
else
echo "Yes, it's running."
fi
Что касается версии 1.7.1
, таких встроенных команд нет.
Вместо этого exec
можно использовать аналогичным образом.
Когда вы запустите его для службы, в которой есть несколько контейнеров, она будет работать нормально:
~/apperture-science $ docker-compose exec chell echo 'Still alive!'
Still alive!
~/apperture-science $ echo $?
0
Но когда вы запускаете его для службы, которая не запущена служба контейнеры, он покажет ошибку:
~/apperture-science $ docker-compose exec glados echo "Still alive!"
ERROR: No container found for apperture-science-glados_1
~/apperture-science $ echo $?
1
Таким образом, с его помощью можно проверить, есть ли «живые» контейнеры для данной службы.
Вы можете запустить:
docker-compose ps -q service-name
И вы получите идентификатор контейнера, если service-name
это работает. Что-то вроде:
18a04e61240d8ffaf4dc3f021effe9e951572ef0cb31da7ce6118f681f585c7f
Если служба не запущена, вывод будет пустым, поэтому, если вы хотите использовать это в сценарии, вы можете сделать что-то вроде:
IS_RUNNING=`docker-compose ps -q service-name`
if [[ "$IS_RUNNING" != "" ]]; then
echo "The service is running!!!"
fi
У меня была аналогичная потребность. Однако у меня есть restart: always
в моем окружении. Таким образом, может быть немного сложно определить, что что-то выходит из строя и перезапускается в цикле.
Я сделал проверку Icinga / Nagios, чтобы также сравнить время создания и время запуска. Может быть, это пригодится кому-то еще в будущем:
#!/usr/bin/env python
from __future__ import print_function
import argparse
from datetime import timedelta
from datetime import datetime
import sys
from dateutil.parser import parse as parse_date
import docker
import pytz
parser = argparse.ArgumentParser()
parser.add_argument("compose_project",
help="The name of the docker-compose project")
parser.add_argument("compose_service",
help="The name of the docker-compose service")
args = vars(parser.parse_args())
client = docker.from_env()
service_containers = client.containers.list(filters={
"label": [
"com.docker.compose.oneoff=False",
"com.docker.compose.project={}".format(args["compose_project"]),
"com.docker.compose.service={}".format(args["compose_service"])
]})
if len(service_containers) == 0:
print("CRITICAL: project({})/service({}) doesn't exist!".format(
args["compose_project"], args["compose_service"]))
sys.exit(2)
elif len(service_containers) > 1:
print("CRITICAL: project({})/service({}) has more than 1 "
"container!".format(
args["compose_project"], args["compose_service"]))
sys.exit(2)
service_container = service_containers[0]
created_at = parse_date(service_container.attrs['Created'])
status = service_container.attrs['State']['Status']
started_at = parse_date(service_container.attrs['State']['StartedAt'])
now = datetime.utcnow().replace(tzinfo=pytz.utc)
uptime = now - started_at
if status in ['stopped', 'exited', 'dead']:
print("CRITICAL: project({})/service({}) is status={}".format(
args["compose_project"], args["compose_service"], status))
sys.exit(2)
if (started_at - created_at) > timedelta(minutes=5):
if uptime < timedelta(seconds=5):
print("CRITICAL: project({})/service({}) appears to be "
"crash-looping".format(
args["compose_project"], args["compose_service"]))
sys.exit(2)
if status == "restarting":
print("WARNING: project({})/service({}) is restarting".format(
args["compose_project"], args["compose_service"]))
sys.exit(1)
print ("OK: project({})/service({}) is up for {}".format(
args["compose_project"], args["compose_service"], uptime
))
sys.exit(0)
Увидеть все запущенные службы:
docker-compose ps --services --filter "status=running"
Увидеть, если ваша служба это работает:
docker-compose ps --services --filter "status=running" | grep <your-service>
Обратите внимание, что --filter
должен использоваться с --services
по какой-то иностранной причине.
Если вы предполагаете этот сценарий:
вы можете проверить, есть ли остановленный контейнер из-за ошибки: docker ps -a | grep 'Exited (255)'
.
Эта проверка работает правильно даже в случае контейнеров, которые, как ожидается, немедленно остановятся без ошибок (например, контейнеры данных), поскольку их статус (от docker ps -a
) отмечен как Exited (0)
.
Например, в нашем docker-compose.yml мы запускаем наши контейнеры с:
command: sh -c 'node dotenv_check.js && pm2 start --no-daemon src/worker.js --watch'
Для php-fpm мы используем аналогичную команду:
command: >-
sh -c '
set -e;
for PROJECT in frontend backend; do
cd /var/www/$${PROJECT};
php dotenv_check.php;
done;
php-fpm
'
В dotenv_check.js
и dotenv_check.php
это скрипты, которые выходят с кодом ошибки в случае отсутствия необходимой переменной env.
В set -e
команда, сообщает скрипту останавливаться при ошибке, которая, в свою очередь, немедленно останавливает контейнер. О set-e
Как насчет этого?
docker-compose ps | awk '$4 == "Up" {print $1}' | grep <service-name>
вы перечисляете процессы, выбираете строки, где «Вверх» находится в столбце 4, и выполняете фильтрацию на соответствие имени службы.