Ansible: команда, связанная с докером, не работает внутри playbook, но работает после прямого запуска

У меня есть следующая задача в моей пьесе:

- name: install pg_stat_statements extension in the postgres container
  shell: docker exec octopus_postgres_{{ group_id }} /bin/bash -c 'psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;"' #  && service postgres restart')"
  async: 10
  poll: 0

Как только я запускаю playbook, эта задача кажется успешно завершенной, но если я проверю базу данных postgres, в ней нет никаких изменений. Задача фактически не удалась.

Если я запускаю вышеупомянутую команду вручную на хосте через bash, все работает нормально, и база данных обновляется, например:

docker exec octopus_postgres_iaa /bin/bash -c 'psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;"'

Пытаясь проверить, что не так с задачей, я попробовал следующее:

- name: install pg_stat_statements extension in the postgres container
  shell: docker exec octopus_postgres_{{ group_id }} /bin/bash -c 'touch /1 && psql -h localhost -U postgres -p 5433 -c "CREATE EXTENSION pg_stat_statements;" && touch /2' #  && service postgres restart')"
  async: 10
  poll: 0

Я заметил, что файл /1 действительно был создан внутри контейнера, но файл /2 не...

Что не так с командой?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
256
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование docker exec здесь неуместно. В общем, вы хотите избежать этого для таких задач: если контейнер будет удален и воссоздан, любая локальная настройка, которую вы сделали с помощью docker exec, будет потеряна. Когда вы пытаетесь внести изменения в какой-то сервер, используя его API, вы обычно просто вызываете его API, вместо того, чтобы получить корневую оболочку на хосте сервера и затем что-то делать, но этот последний шаг — это то, что делает docker exec.

стандартное postgres изображение поддерживает размещение фрагментов SQL в каталоге на стороне контейнера /docker-entrypoint-initdb.d, который будет обрабатываться при первом запуске контейнера (только). Очень типичным использованием является монтирование каталога хост-системы со сценариями инициализации в этот каталог. В Ansible это может выглядеть так:

- name: create pg_stat_statements extension file
  copy:
    dest: /docker/postgres/initdb/create-stat-statements.sql
    content: |-
      CREATE EXTENSION pg_stat_statements;

- name: start postgres container
  docker_container:
    image: 'postgres:11'
    name: octopus_postgres_{{ group_id }}
    published_ports: ['5433:5432']
    volumes:
      - '/docker/postgres/initdb:/docker-entrypoint-initdb.d'
      - '/docker/postgres/data:/var/lib/postgresql/data'

В качестве альтернативы вы можете управлять базой данных, как и любой другой базой данных PostgreSQL (локальной, облачной, удаленной и т. д.), используя встроенные инструменты Ansible; в данном случае модуль postgresql_ext для создания расширений.

- name: enable pg_stat_statements PostgreSQL extension
  postgresql_ext:
    name: pg_stat_statements
    port: 5433

С точки зрения вашего первоначального утверждения, вероятно, происходят две вещи. Прежде всего, если вы используете путь docker exec для взаимодействия с контейнером, вам всегда нужно использовать порт, на котором, по мнению сервера, он работает, а не какие-либо переназначенные порты из опции docker run -p или эквивалентов: в вашем заявлении вам нужно использовать порт по умолчанию 5432, а не 5433. Во-вторых, поскольку вы запускаете задачу с помощью async: 10, poll: 0, Ansible запускает задачу и сразу переходит к следующей, даже не проверяя, успешно ли она выполнена (см. Асинхронные действия и опрос), поэтому вы на самом деле не знаете успешно ли выполнена задача docker exec. Я предполагаю, что ничего не происходит, потому что не удается подключиться к базе данных, но вы никогда не видите эту ошибку.

Другие вопросы по теме