I am using CentOS 8 and GitLab ci/cd and I’m trying to deploy a Django project, I don’t have any idea why the Django container can not connect to Postgres container, you can see all of the configurations below:
Dockerfile NEW
# 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 NEW
#!/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:[email protected]/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-compose UPDATED
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 DB settings:
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 network ls NEW
8d0bd4bcca7d bridge bridge local
661e1139c1b8 host host local
8323f73cc95e meet-pet_default bridge local
428d1baf38ea none null local
docker meet-pet_default network inspect UPDATED
[
{
"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-compose FULL logs:
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
I’ve checked every solution that I could found, but none of them works and I still have this error.
2
Answers
The problem is not with docker-compose, It's because of the firewall. CentOS firewall blocked 5432 port.
to open 5432 port permanently use the below commands:
Notice: swap out "[YOURPORT]" for the actual port.. i.e. 5432 and swap out the "docker0" network if you've named it something else.
for checking network list use:
docker network ls
and you can see all networks.Postgres needs about ten or so seconds to initialize an empty database. Don’t be fooled by this fancy
depends_on
property: it only waits for the mentioned container(s) to start. It doesn’t care if it’s ready. Docker documentation says about it that you have to create an application that can tolerate missing components instead of relying ondepends_on
.While you didn’t make one, you can add
restart: on-failure
property to your service definition in the compose file. With it Docker will restart the container if it fails. You can also add some simple check that the database is at least listening:while !</dev/tcp/db/5432; do sleep 3; done;
. Add this beforepython manage.py
and it will run a loop checking ifdb
is listening on 5432 and sleeping if it’s not.