让Docker撰写等待Django项目中的PostGIS(PostgreS)

时间:2020-07-21 04:59:19

标签: django postgresql docker docker-compose postgis

我需要编写一个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脚本中?

3 个答案:

答案 0 :(得分:1)

使用pg_isready

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"
            ]
相关问题