好,所以,我正在尝试使用Django和docker启动一个项目。第一步很简单,我只想在容器中启动一个默认的django应用程序,然后在浏览器中看到django启动屏幕。我也想连接一个最简单的postgres容器来运行它。一切都很好。 我为我的应用创建了一个简单的图片,没什么花哨的:
FROM python:3.7
RUN mkdir /app
COPY requirements.txt /app/
WORKDIR /app
RUN pip install -r requirements.txt
COPY . /code/
还有一个docker-compose.yml:
version: '3'
services:
python:
build:
context: .
dockerfile: docker/python/Dockerfile
volumes:
- .:/app
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
depends_on:
- db
restart: always
db:
image: postgres:9.5
environment:
POSTGRES_USER: cards
POSTGRES_DB: cards
POSTGRES_PASSWORD: cards
如您所见,我什至没有将任何源代码复制到docker映像中,我正在安装django的卷以从主机读取它。
问题是当我启动容器时,django服务器启动得太早而无法准备postgres,而psycopg2抛出了OperationalError。 这是我启动新容器时的日志:
Creating network "backend_default" with the default driver
Creating backend_db_1 ... done
Creating python ... done
Attaching to backend_db_1, python
db_1 | The files belonging to this database system will be owned by user "postgres".
db_1 | This user must also own the server process.
db_1 |
db_1 | The database cluster will be initialized with locale "en_US.utf8".
db_1 | The default database encoding has accordingly been set to "UTF8".
db_1 | The default text search configuration will be set to "english".
db_1 |
db_1 | Data page checksums are disabled.
db_1 |
db_1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db_1 | creating subdirectories ... ok
db_1 | selecting default max_connections ... 100
db_1 | selecting default shared_buffers ... 128MB
db_1 | selecting default timezone ... Etc/UTC
db_1 | selecting dynamic shared memory implementation ... posix
db_1 | creating configuration files ... ok
db_1 | creating template1 database in /var/lib/postgresql/data/base/1 ... ok
db_1 | initializing pg_authid ... ok
db_1 | setting password ... ok
db_1 | initializing dependencies ... ok
db_1 | creating system views ... ok
db_1 | loading system objects' descriptions ... ok
db_1 | creating collations ... ok
db_1 | creating conversions ... ok
db_1 | creating dictionaries ... ok
db_1 | setting privileges on built-in objects ... ok
db_1 | creating information schema ... ok
db_1 | loading PL/pgSQL server-side language ... ok
db_1 | vacuuming database template1 ... ok
db_1 | copying template1 to template0 ... ok
db_1 | copying template1 to postgres ... ok
python | Watching for file changes with StatReloader
python | Performing system checks...
python |
db_1 | syncing data to disk ...
db_1 | WARNING: enabling "trust" authentication for local connections
db_1 | You can change this by editing pg_hba.conf or using the option -A, or
db_1 | --auth-local and --auth-host, the next time you run initdb.
db_1 | ok
db_1 |
db_1 | Success. You can now start the database server using:
db_1 |
db_1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
db_1 |
db_1 | waiting for server to start....LOG: database system was shut down at 2020-04-12 14:17:12 UTC
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
python | System check identified no issues (0 silenced).
python | Exception in thread django-main-thread:
python | Traceback (most recent call last):
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
python | self.connect()
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 195, in connect
python | self.connection = self.get_new_connection(conn_params)
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
python | connection = Database.connect(**conn_params)
python | File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 127, in connect
python | conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
python | psycopg2.OperationalError: could not connect to server: Connection refused
python | Is the server running on host "db" (192.168.160.2) and accepting
python | TCP/IP connections on port 5432?
python |
python |
python | The above exception was the direct cause of the following exception:
python |
python | Traceback (most recent call last):
python | File "/usr/local/lib/python3.7/threading.py", line 926, in _bootstrap_inner
python | self.run()
python | File "/usr/local/lib/python3.7/threading.py", line 870, in run
python | self._target(*self._args, **self._kwargs)
python | File "/usr/local/lib/python3.7/site-packages/django/utils/autoreload.py", line 54, in wrapper
python | fn(*args, **kwargs)
python | File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
python | self.check_migrations()
python | File "/usr/local/lib/python3.7/site-packages/django/core/management/base.py", line 453, in check_migrations
python | executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
python | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/executor.py", line 18, in __init__
python | self.loader = MigrationLoader(self.connection)
python | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/loader.py", line 49, in __init__
python | self.build_graph()
python | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/loader.py", line 212, in build_graph
python | self.applied_migrations = recorder.applied_migrations()
python | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/recorder.py", line 73, in applied_migrations
python | if self.has_table():
python | File "/usr/local/lib/python3.7/site-packages/django/db/migrations/recorder.py", line 56, in has_table
python | return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 256, in cursor
python | return self._cursor()
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 233, in _cursor
python | self.ensure_connection()
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
python | self.connect()
python | File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 89, in __exit__
python | raise dj_exc_value.with_traceback(traceback) from exc_value
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 217, in ensure_connection
python | self.connect()
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/base/base.py", line 195, in connect
python | self.connection = self.get_new_connection(conn_params)
python | File "/usr/local/lib/python3.7/site-packages/django/db/backends/postgresql/base.py", line 178, in get_new_connection
python | connection = Database.connect(**conn_params)
python | File "/usr/local/lib/python3.7/site-packages/psycopg2/__init__.py", line 127, in connect
python | conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
python | django.db.utils.OperationalError: could not connect to server: Connection refused
python | Is the server running on host "db" (192.168.160.2) and accepting
python | TCP/IP connections on port 5432?
python |
python |
db_1 | done
db_1 | server started
db_1 | CREATE DATABASE
db_1 |
db_1 |
db_1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db_1 |
db_1 | waiting for server to shut down...LOG: received fast shutdown request
db_1 | LOG: aborting any active transactions
db_1 | LOG: autovacuum launcher shutting down
db_1 | .LOG: shutting down
db_1 | LOG: database system is shut down
db_1 | done
db_1 | server stopped
db_1 |
db_1 | PostgreSQL init process complete; ready for start up.
db_1 |
db_1 | LOG: database system was shut down at 2020-04-12 14:17:13 UTC
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
如您所见,django容器在postgres设置的中间启动,并且无法连接。如果我只是重新启动django容器(另一件事,即使runserver命令失败,则docker容器也不会认为这是一个错误,并且无需重新启动就可以继续工作-我认为这是可以理解的,因为它是使用StatReloader启动的),当然可以,但是如果我可以让应用程序从第一次启动开始运行,而不是故意重新启动它,我将很高兴...
是否有防止发生这种情况的方法?我在这里犯了任何错误,还是应该对此采取其他方法?
谢谢。
答案 0 :(得分:0)
您必须添加一些代码来检查数据库状态。
例如创建文件“ wait_for_db.sh”:
#!/bin/bash
echo "Waiting Postgres to launch on 5432..."
while ! nc -z db 5432; do
sleep 0.1 # wait for 1/10 of the second before check again
done
echo "Postgres launched"
然后将其添加到您的Dockerfile中:
COPY wait_for_db.sh .
并将docker-compose.yml中的命令更改为:
command: wait_for_db.sh && python manage.py runserver 0.0.0.0:8000
祝你好运