我需要编写一个shell脚本,该脚本将允许docker等待postgres数据库。 我有一个名为 wait-for-postgres.sh 的以下shell脚本:
#!/bin/sh
# wait-for-postgres.sh
set -e
host="$1"
shift
cmd="$@"
until PGPASSWORD=$POSTGRES_PASSWORD psql -h "$host" -U "postgres" -c '\q'; do
>&2 echo "Postgres is unavailable - sleeping"
sleep 1
done
>&2 echo "Postgres is up - executing command"
exec $cmd
docker-compose.yml:
version: '3'
services:
db:
image: kartoza/postgis:12.0
environment:
- POSTGRES_DB=amr_or
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=root
ports:
- "5432:5432"
web:
build: ./
command: bash -c " ./wait-for-postgres.sh && python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput --i rest_framework && gunicorn orion-amr.wsgi:application --bind 0.0.0.0:8000 --workers=2"
ports:
- "8000:8000"
env_file:
- ./.env.dev
depends_on:
- db
Dockerfile:
FROM python:2.7
WORKDIR /orion-amr/
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
RUN apt-get update
RUN apt-get install -y binutils libproj-dev gdal-bin
COPY wait-for-postgres.sh /wait-for-postgres.sh
COPY . /orion-amr/
如何将docker-compose.yml(python manage.py ...等)中的现有命令添加到shell脚本中?
答案 0 :(得分:1)
在 Dockerfile 中添加:
RUN apt-get install -y postgresql-client
在 wait-for-postgres.sh 中:
#!/bin/bash
### WAITING POSTGRES START ###
RETRIES=7
while [ "$RETRIES" -gt 0 ]
do
echo "Waiting for postgres server, $((RETRIES--)) remaining attempts..."
PG_STATUS="$(pg_isready -h $host -U postgres)"
PG_EXIT=$(echo $?)
echo "Postgres Status: $PG_EXIT - $PG_STATUS"
if [ "$PG_EXIT" = "0" ];
then
RETRIES=0
fi
sleep 5 # timeout for new loop
done
### DJANGO MANAGE COMMANDS ###
python manage.py makemigrations &&
python manage.py migrate &&
python manage.py collectstatic --noinput --i rest_framework &&
gunicorn orion-amr.wsgi:application --bind 0.0.0.0:8000 --workers=2
在 docker-compose.yml 的服务性网络中,删除命令并添加入口点:
version: '3'
services:
db:
image: kartoza/postgis:12.0
environment:
- POSTGRES_DB=amr_or
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=root
ports:
- "5432:5432"
web:
build: ./
entrypoint: ["bash","./wait-for-postgres.sh"]
ports:
- "8000:8000"
env_file:
- ./.env.dev
depends_on:
- db
答案 1 :(得分:0)
您编写的内容应在Docker中用作ENTRYPOINT
。如果您以ENTRYPOINT
身份运行此脚本,则来自docker-compose.yml文件的命令将以$cmd
的形式在入口点脚本中传递。
FROM python:2.7
WORKDIR /orion-amr/
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt ./requirements.txt
RUN pip install -r requirements.txt
RUN apt-get update
RUN apt-get install -y binutils libproj-dev gdal-bin
COPY wait-for-postgres.sh /wait-for-postgres.sh
COPY . /orion-amr/
RUN chmod +x /wait-for-postgres.sh
ENTRYPOINT ["/wait-for-postgres.sh"]
然后从docker-compose.yml
中删除该脚本:
command: bash -c " python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput --i rest_framework && gunicorn orion-amr.wsgi:application --bind 0.0.0.0:8000 --workers=2"
答案 2 :(得分:0)
首先最好将CMD
放置在Dockerfile中,并在需要时从docker-compose文件中覆盖。
所以Dockerfile看起来像
RUN chmod +x /wait-for-postgres.sh
ENTRYPOINT ["/wait-for-postgres.sh"]
CMD [ "python", "manage.py", "migrate", "&&", "python", "manage.py", "collectstatic", "--noinput", "--i", "rest_framework", "&&", "gunicorn", "orion-amr.wsgi:application", "--bind", "0.0.0.0:8000", "--workers=2"]
或者如果您想使用compose运行,则无需指定bin/bash
,因为您已经在bash脚本中使用了CMD
。
web:
build: ./
command: "python manage.py makemigrations && python manage.py migrate && python manage.py collectstatic --noinput --i rest_framework && gunicorn orion-amr.wsgi:application --bind 0.0.0.0:8000 --workers=2"
ports:
- "8000:8000"
env_file:
- ./.env.dev
depends_on:
- db
所以现在如果您检查容器,CMD
将会像
"Cmd": [
"python",
"manage.py",
"makemigrations",
"&&",
"python",
"manage.py",
"migrate",
"&&",
"python",
"manage.py",
"collectstatic",
"--noinput",
"--i",
"rest_framework",
"&&",
"gunicorn",
"orion-amr.wsgi:application",
"--bind",
"0.0.0.0:8000",
"--workers=2"
]