我的剧本中有以下任务:
- 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
一旦我运行了剧本,该任务似乎就成功完成了,但是如果我检查了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
尚未...
命令有什么问题?
docker exec
这里根本不使用。通常,对于这样的任务,您要避免使用它:如果删除并重新创建了容器,则您所做的任何本地设置都docker exec
将丢失。当您尝试使用其API对某种服务器进行更改时,通常只需调用其API,而不是在服务器主机上获取root shell然后执行操作即可,但这是后一步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'
另外,您可以使用Ansible的内置工具像其他任何PostgreSQL数据库一样管理该数据库(本地,云托管,远程等等)。在这种情况下,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
任务是否成功。我的猜测是什么也没发生,因为它无法连接到数据库,但是您永远不会看到此错误。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句