Postgres-alpine 无法连接到 Django 项目容器
Postgres-alpine can not connect to Django project container
我正在使用 CentOS 8 和 GitLab ci/cd 我正在尝试部署一个 Django 项目,我不知道为什么 Django 容器无法连接到 Postgres 容器,你可以看到所有以下配置:
Dockerfile 新
# pull official base image
FROM python:3.9-alpine
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV APP_ROOT /meet-pet
# set work directory
WORKDIR ${APP_ROOT}
# install dependencies
RUN pip3 install -U pip
# install psycopg2 dependencies
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev gcc python3-dev musl-dev \
&& apk del build-deps \
&& apk --no-cache add musl-dev linux-headers g++ bash
COPY requirements.txt ${APP_ROOT}/requirements.txt
COPY entrypoint.sh ${APP_ROOT}/entrypoint.sh
RUN pip3 install -r ${APP_ROOT}/requirements.txt
# Set the working directory to /meet_pet
WORKDIR ${APP_ROOT}
# Copy the current directory contents into the container at /meet_pet
ADD . ${APP_ROOT}
RUN chmod 775 -R ${APP_ROOT}
ENTRYPOINT ["/meet-pet/entrypoint.sh"]
entrypoint.sh 新
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do
sleep 10
done
echo "PostgreSQL started"
fi
exec "$@"
.env
POSTGRES_DB = somthing
POSTGRES_USER = user
POSTGRES_PASSWORD = pass
POSTGRES_HOST = db
POSTGRES_PORT = 5432
.env.db
POSTGRES_DB=somthing
POSTGRES_USER=user
POSTGRES_PASSWORD=pass
POSTGRES_PORT = 5432
deploy.sh
#!/usr/bin/env bash
ssh -o StrictHostKeyChecking=no something@my_ip<< 'ENDSSH'
cd some-thing/
docker-compose down
git pull https:/user:pass@gitlab.com/neo1992/something.git
docker login -u user -p pass registry.gitlab.com
docker pull registry.gitlab.com/neo1992/some-thing:latest
docker-compose up -d
ENDSSH
docker-撰写已更新
version: "3.8"
services:
web:
image: registry.gitlab.com/neo1992/meet-pet:latest
build:
context: .
container_name: web
command: bash -c 'python manage.py migrate --noinput && python manage.py makemigrations && python manage.py migrate --noinput && python manage.py collectstatic --noinput && gunicorn meet_pet.wsgi:application -b 0.0.0.0:8000 --capture-output --log-level=info'
volumes:
- static_volume:/home/meetpet/meet-pet/static
- media_volume:/home/meetpet/meet-pet/media
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:12.0-alpine
container_name: db
ports:
- "5432"
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=meet_pet
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- DATABASE=postgres
nginx:
build: ./nginx
container_name: nginx
ports:
- "80:80"
volumes:
- static_volume:/home/meetpet/meet-pet/static
- media_volume:/home/meetpet/meet-pet/media
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
Django==3.1.3 数据库设置:
Django setting:
from envparse import env
env.read_envfile()
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": env("POSTGRES_DB", default=""),
"USER": env("POSTGRES_USER", default=""),
"PASSWORD": env("POSTGRES_PASSWORD", default=""),
"HOST": env("POSTGRES_HOST", default=""),
"PORT": env("POSTGRES_PORT", default=""),
}
}
gitlab-ci.yml
image: docker:stable
services:
- docker:dind
stages:
- build
- test
- deploy
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
before_script:
- apk add --no-cache --update py-pip
- pip install docker-compose~=1.23.0
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
build:
stage: build
script:
- docker build -t registry.gitlab.com/neo1992/some-thing .
- docker push registry.gitlab.com/neo1992/some-thing
only:
- master
deploy:
stage: deploy
before_script:
- apk add --no-cache openssh-client bash
- mkdir -p ~/.ssh
- echo "$DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- cat ~/.ssh/id_rsa
- chmod 700 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_rsa
- ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
script:
- bash ./deploy.sh
only:
- master
docker 网络 ls NEW
8d0bd4bcca7d bridge bridge local
661e1139c1b8 host host local
8323f73cc95e meet-pet_default bridge local
428d1baf38ea none null local
docker meet-pet_default 网络检查 已更新
[
{
"Name": "meet-pet_default",
"Id": "8323f73cc95ef0a2294b40da4ec0b20ac2a4e59a4235832f291a8601e15fad54",
"Created": "2020-12-04T15:44:42.113742176Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.26.0.0/16",
"Gateway": "172.26.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ccd43c63a88d566cda572ef1fc62d12d8ba31de485feedb3c47b96ec8fc484f4": {
"Name": "db",
"EndpointID": "c6598512aa0d837dd429ad0813d9206dc21ac2f6e6561c9296a1c401747e089b",
"MacAddress": "02:42:ac:1a:00:02",
"IPv4Address": "172.26.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "meet-pet",
"com.docker.compose.version": "1.27.4"
}
}
]
docker-撰写完整日志:
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
ESC[33mnginx |ESC[0m 10-listen-on-ipv6-by-default.sh: /etc/nginx/conf.d/default.conf is not a file or does not exist, exiting
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Configuration complete; ready for start up
ESC[33mnginx |ESC[0m 2020/12/04 09:02:28 [emerg] 1#1: host not found in upstream "meet_pet:8000" in /etc/nginx/conf.d/nginx.conf:3
ESC[33mnginx |ESC[0m nginx: [emerg] host not found in upstream "meet_pet:8000" in /etc/nginx/conf.d/nginx.conf:3
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.279 UTC [1] LOG: starting PostgreSQL 12.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.
3.0, 64-bit
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.280 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.280 UTC [1] LOG: listening on IPv6 address "::", port 5432
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.281 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.315 UTC [18] LOG: database system was shut down at 2020-12-04 09:02:09 UTC
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.318 UTC [1] LOG: database system is ready to accept connections
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m psycopg2.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m The above exception was the direct cause of the following exception:
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 22, in <module>
ESC[32mweb |ESC[0m main()
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 18, in main
ESC[32mweb |ESC[0m execute_from_command_line(sys.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
ESC[32mweb |ESC[0m utility.execute()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
ESC[32mweb |ESC[0m self.fetch_command(subcommand).run_from_argv(self.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 330, in run_from_argv
ESC[32mweb |ESC[0m self.execute(*args, **cmd_options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 371, in execute
ESC[32mweb |ESC[0m output = self.handle(*args, **options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 85, in wrapped
ESC[32mweb |ESC[0m res = handle_func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 92, in handle
ESC[32mweb |ESC[0m executor = MigrationExecutor(connection, self.migration_progress_callback)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
ESC[32mweb |ESC[0m self.loader = MigrationLoader(self.connection)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
ESC[32mweb |ESC[0m self.build_graph()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
ESC[32mweb |ESC[0m self.applied_migrations = recorder.applied_migrations()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
ESC[32mweb |ESC[0m if self.has_table():
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
ESC[32mweb |ESC[0m with self.connection.cursor() as cursor:
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
ESC[32mweb |ESC[0m raise dj_exc_value.with_traceback(traceback) from exc_value
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m django.db.utils.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m psycopg2.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m The above exception was the direct cause of the following exception:
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 22, in <module>
ESC[32mweb |ESC[0m main()
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 18, in main
ESC[32mweb |ESC[0m execute_from_command_line(sys.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
ESC[32mweb |ESC[0m utility.execute()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
ESC[32mweb |ESC[0m self.fetch_command(subcommand).run_from_argv(self.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 330, in run_from_argv
ESC[32mweb |ESC[0m self.execute(*args, **cmd_options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 371, in execute
ESC[32mweb |ESC[0m output = self.handle(*args, **options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 85, in wrapped
ESC[32mweb |ESC[0m res = handle_func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 92, in handle
ESC[32mweb |ESC[0m executor = MigrationExecutor(connection, self.migration_progress_callback)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
ESC[32mweb |ESC[0m self.loader = MigrationLoader(self.connection)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
ESC[32mweb |ESC[0m self.build_graph()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
ESC[32mweb |ESC[0m self.applied_migrations = recorder.applied_migrations()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
ESC[32mweb |ESC[0m if self.has_table():
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
ESC[32mweb |ESC[0m with self.connection.cursor() as cursor:
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 259, in cursor
ESC[32mweb |ESC[0m return self._cursor()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 235, in _cursor
ESC[32mweb |ESC[0m self.ensure_connection()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
ESC[32mweb |ESC[0m raise dj_exc_value.with_traceback(traceback) from exc_value
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m django.db.utils.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
我已经检查了我能找到的所有解决方案,但其中 none 个有效,但我仍然遇到此错误。
Postgres 大约需要十秒左右的时间来初始化一个空数据库。不要被这个花哨的 depends_on
属性 所迷惑:它只等待提到的容器启动。它不在乎它是否准备好。 Docker 文档说你必须创建一个可以容忍缺失组件的应用程序,而不是依赖 depends_on
.
虽然您没有创建,但您可以将 restart: on-failure
属性 添加到撰写文件中的服务定义中。使用它 Docker 将在失败时重新启动容器。您还可以添加一些简单的检查以确保数据库至少正在侦听:while !</dev/tcp/db/5432; do sleep 3; done;
。在 python manage.py
之前添加它,它将 运行 一个循环检查 db
是否正在监听 5432,如果没有则进入休眠状态。
问题不在于 docker-compose,而是防火墙的问题。 CentOS 防火墙阻止了 5432 端口。
永久打开5432端口使用以下命令:
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --permanent --zone=public --change-interface=docker0
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 4 -i docker0 -j ACCEPT
sudo firewall-cmd --permanent --zone=public --add-port=[YOURPORT]/tcp
注意: 将“[YOURPORT]”换出实际端口.. 即 5432 并换出“docker0”网络(如果您已命名)它是别的东西。
用于检查网络列表使用:
docker network ls
你可以看到所有的网络。
我正在使用 CentOS 8 和 GitLab ci/cd 我正在尝试部署一个 Django 项目,我不知道为什么 Django 容器无法连接到 Postgres 容器,你可以看到所有以下配置:
Dockerfile 新
# pull official base image
FROM python:3.9-alpine
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
ENV APP_ROOT /meet-pet
# set work directory
WORKDIR ${APP_ROOT}
# install dependencies
RUN pip3 install -U pip
# install psycopg2 dependencies
RUN apk update \
&& apk add --virtual build-deps gcc python3-dev musl-dev \
&& apk add postgresql-dev gcc python3-dev musl-dev \
&& apk del build-deps \
&& apk --no-cache add musl-dev linux-headers g++ bash
COPY requirements.txt ${APP_ROOT}/requirements.txt
COPY entrypoint.sh ${APP_ROOT}/entrypoint.sh
RUN pip3 install -r ${APP_ROOT}/requirements.txt
# Set the working directory to /meet_pet
WORKDIR ${APP_ROOT}
# Copy the current directory contents into the container at /meet_pet
ADD . ${APP_ROOT}
RUN chmod 775 -R ${APP_ROOT}
ENTRYPOINT ["/meet-pet/entrypoint.sh"]
entrypoint.sh 新
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $POSTGRES_HOST $POSTGRES_PORT; do
sleep 10
done
echo "PostgreSQL started"
fi
exec "$@"
.env
POSTGRES_DB = somthing
POSTGRES_USER = user
POSTGRES_PASSWORD = pass
POSTGRES_HOST = db
POSTGRES_PORT = 5432
.env.db
POSTGRES_DB=somthing
POSTGRES_USER=user
POSTGRES_PASSWORD=pass
POSTGRES_PORT = 5432
deploy.sh
#!/usr/bin/env bash
ssh -o StrictHostKeyChecking=no something@my_ip<< 'ENDSSH'
cd some-thing/
docker-compose down
git pull https:/user:pass@gitlab.com/neo1992/something.git
docker login -u user -p pass registry.gitlab.com
docker pull registry.gitlab.com/neo1992/some-thing:latest
docker-compose up -d
ENDSSH
docker-撰写已更新
version: "3.8"
services:
web:
image: registry.gitlab.com/neo1992/meet-pet:latest
build:
context: .
container_name: web
command: bash -c 'python manage.py migrate --noinput && python manage.py makemigrations && python manage.py migrate --noinput && python manage.py collectstatic --noinput && gunicorn meet_pet.wsgi:application -b 0.0.0.0:8000 --capture-output --log-level=info'
volumes:
- static_volume:/home/meetpet/meet-pet/static
- media_volume:/home/meetpet/meet-pet/media
ports:
- "8000:8000"
depends_on:
- db
db:
image: postgres:12.0-alpine
container_name: db
ports:
- "5432"
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=meet_pet
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- DATABASE=postgres
nginx:
build: ./nginx
container_name: nginx
ports:
- "80:80"
volumes:
- static_volume:/home/meetpet/meet-pet/static
- media_volume:/home/meetpet/meet-pet/media
depends_on:
- web
volumes:
postgres_data:
static_volume:
media_volume:
Django==3.1.3 数据库设置:
Django setting:
from envparse import env
env.read_envfile()
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": env("POSTGRES_DB", default=""),
"USER": env("POSTGRES_USER", default=""),
"PASSWORD": env("POSTGRES_PASSWORD", default=""),
"HOST": env("POSTGRES_HOST", default=""),
"PORT": env("POSTGRES_PORT", default=""),
}
}
gitlab-ci.yml
image: docker:stable
services:
- docker:dind
stages:
- build
- test
- deploy
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
before_script:
- apk add --no-cache --update py-pip
- pip install docker-compose~=1.23.0
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com
build:
stage: build
script:
- docker build -t registry.gitlab.com/neo1992/some-thing .
- docker push registry.gitlab.com/neo1992/some-thing
only:
- master
deploy:
stage: deploy
before_script:
- apk add --no-cache openssh-client bash
- mkdir -p ~/.ssh
- echo "$DEPLOY_KEY" | tr -d '\r' > ~/.ssh/id_rsa
- cat ~/.ssh/id_rsa
- chmod 700 ~/.ssh/id_rsa
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_rsa
- ssh-keyscan -H 'gitlab.com' >> ~/.ssh/known_hosts
script:
- bash ./deploy.sh
only:
- master
docker 网络 ls NEW
8d0bd4bcca7d bridge bridge local
661e1139c1b8 host host local
8323f73cc95e meet-pet_default bridge local
428d1baf38ea none null local
docker meet-pet_default 网络检查 已更新
[
{
"Name": "meet-pet_default",
"Id": "8323f73cc95ef0a2294b40da4ec0b20ac2a4e59a4235832f291a8601e15fad54",
"Created": "2020-12-04T15:44:42.113742176Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.26.0.0/16",
"Gateway": "172.26.0.1"
}
]
},
"Internal": false,
"Attachable": true,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ccd43c63a88d566cda572ef1fc62d12d8ba31de485feedb3c47b96ec8fc484f4": {
"Name": "db",
"EndpointID": "c6598512aa0d837dd429ad0813d9206dc21ac2f6e6561c9296a1c401747e089b",
"MacAddress": "02:42:ac:1a:00:02",
"IPv4Address": "172.26.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {
"com.docker.compose.network": "default",
"com.docker.compose.project": "meet-pet",
"com.docker.compose.version": "1.27.4"
}
}
]
docker-撰写完整日志:
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
ESC[33mnginx |ESC[0m 10-listen-on-ipv6-by-default.sh: /etc/nginx/conf.d/default.conf is not a file or does not exist, exiting
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
ESC[33mnginx |ESC[0m /docker-entrypoint.sh: Configuration complete; ready for start up
ESC[33mnginx |ESC[0m 2020/12/04 09:02:28 [emerg] 1#1: host not found in upstream "meet_pet:8000" in /etc/nginx/conf.d/nginx.conf:3
ESC[33mnginx |ESC[0m nginx: [emerg] host not found in upstream "meet_pet:8000" in /etc/nginx/conf.d/nginx.conf:3
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.279 UTC [1] LOG: starting PostgreSQL 12.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.
3.0, 64-bit
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.280 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.280 UTC [1] LOG: listening on IPv6 address "::", port 5432
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.281 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.315 UTC [18] LOG: database system was shut down at 2020-12-04 09:02:09 UTC
ESC[36mdb |ESC[0m 2020-12-04 09:02:27.318 UTC [1] LOG: database system is ready to accept connections
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m psycopg2.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m The above exception was the direct cause of the following exception:
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 22, in <module>
ESC[32mweb |ESC[0m main()
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 18, in main
ESC[32mweb |ESC[0m execute_from_command_line(sys.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
ESC[32mweb |ESC[0m utility.execute()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
ESC[32mweb |ESC[0m self.fetch_command(subcommand).run_from_argv(self.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 330, in run_from_argv
ESC[32mweb |ESC[0m self.execute(*args, **cmd_options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 371, in execute
ESC[32mweb |ESC[0m output = self.handle(*args, **options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 85, in wrapped
ESC[32mweb |ESC[0m res = handle_func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 92, in handle
ESC[32mweb |ESC[0m executor = MigrationExecutor(connection, self.migration_progress_callback)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
ESC[32mweb |ESC[0m self.loader = MigrationLoader(self.connection)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
ESC[32mweb |ESC[0m self.build_graph()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
ESC[32mweb |ESC[0m self.applied_migrations = recorder.applied_migrations()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
ESC[32mweb |ESC[0m if self.has_table():
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
ESC[32mweb |ESC[0m with self.connection.cursor() as cursor:
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
ESC[32mweb |ESC[0m raise dj_exc_value.with_traceback(traceback) from exc_value
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m django.db.utils.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m psycopg2.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m The above exception was the direct cause of the following exception:
ESC[32mweb |ESC[0m
ESC[32mweb |ESC[0m Traceback (most recent call last):
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 22, in <module>
ESC[32mweb |ESC[0m main()
ESC[32mweb |ESC[0m File "/meet-pet/manage.py", line 18, in main
ESC[32mweb |ESC[0m execute_from_command_line(sys.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 401, in execute_from_command_line
ESC[32mweb |ESC[0m utility.execute()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py", line 395, in execute
ESC[32mweb |ESC[0m self.fetch_command(subcommand).run_from_argv(self.argv)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 330, in run_from_argv
ESC[32mweb |ESC[0m self.execute(*args, **cmd_options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 371, in execute
ESC[32mweb |ESC[0m output = self.handle(*args, **options)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/base.py", line 85, in wrapped
ESC[32mweb |ESC[0m res = handle_func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/core/management/commands/migrate.py", line 92, in handle
ESC[32mweb |ESC[0m executor = MigrationExecutor(connection, self.migration_progress_callback)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/executor.py", line 18, in __init__
ESC[32mweb |ESC[0m self.loader = MigrationLoader(self.connection)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 53, in __init__
ESC[32mweb |ESC[0m self.build_graph()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/loader.py", line 216, in build_graph
ESC[32mweb |ESC[0m self.applied_migrations = recorder.applied_migrations()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 77, in applied_migrations
ESC[32mweb |ESC[0m if self.has_table():
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/migrations/recorder.py", line 55, in has_table
ESC[32mweb |ESC[0m with self.connection.cursor() as cursor:
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 259, in cursor
ESC[32mweb |ESC[0m return self._cursor()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 235, in _cursor
ESC[32mweb |ESC[0m self.ensure_connection()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/utils.py", line 90, in __exit__
ESC[32mweb |ESC[0m raise dj_exc_value.with_traceback(traceback) from exc_value
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 219, in ensure_connection
ESC[32mweb |ESC[0m self.connect()
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py", line 200, in connect
ESC[32mweb |ESC[0m self.connection = self.get_new_connection(conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py", line 26, in inner
ESC[32mweb |ESC[0m return func(*args, **kwargs)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/django/db/backends/postgresql/base.py", line 187, in get_new_connection
ESC[32mweb |ESC[0m connection = Database.connect(**conn_params)
ESC[32mweb |ESC[0m File "/usr/local/lib/python3.9/site-packages/psycopg2/__init__.py", line 127, in connect
ESC[32mweb |ESC[0m conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
ESC[32mweb |ESC[0m django.db.utils.OperationalError: could not connect to server: Host is unreachable
ESC[32mweb |ESC[0m Is the server running on host "db" (172.25.0.2) and accepting
ESC[32mweb |ESC[0m TCP/IP connections on port 5432?
ESC[32mweb |ESC[0m
我已经检查了我能找到的所有解决方案,但其中 none 个有效,但我仍然遇到此错误。
Postgres 大约需要十秒左右的时间来初始化一个空数据库。不要被这个花哨的 depends_on
属性 所迷惑:它只等待提到的容器启动。它不在乎它是否准备好。 Docker 文档说你必须创建一个可以容忍缺失组件的应用程序,而不是依赖 depends_on
.
虽然您没有创建,但您可以将 restart: on-failure
属性 添加到撰写文件中的服务定义中。使用它 Docker 将在失败时重新启动容器。您还可以添加一些简单的检查以确保数据库至少正在侦听:while !</dev/tcp/db/5432; do sleep 3; done;
。在 python manage.py
之前添加它,它将 运行 一个循环检查 db
是否正在监听 5432,如果没有则进入休眠状态。
问题不在于 docker-compose,而是防火墙的问题。 CentOS 防火墙阻止了 5432 端口。
永久打开5432端口使用以下命令:
sudo firewall-cmd --zone=public --add-masquerade --permanent
sudo firewall-cmd --permanent --zone=public --change-interface=docker0
sudo firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 4 -i docker0 -j ACCEPT
sudo firewall-cmd --permanent --zone=public --add-port=[YOURPORT]/tcp
注意: 将“[YOURPORT]”换出实际端口.. 即 5432 并换出“docker0”网络(如果您已命名)它是别的东西。
用于检查网络列表使用:
docker network ls
你可以看到所有的网络。