Docker compose игнорирует зависимость одного сервиса от другого

Вот актуально docker-compose.yml

version: '3'

services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=my_app
    ports:
      - '5432:5432'
  web:
    build: .
    image: my-app
    ports:
      - "8000:8000"
    depends_on:
      - db
    command: sh -c "python manage.py migrate && 
             python manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    environment:
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_HOST=db
      - DB_NAME=my_app

Когда я запускаю приложение в первый раз, это происходит:

% docker compose build && docker compose up
[+] Building 2.5s (10/10) FINISHED                                              
 => [internal] load build definition from Dockerfile                       0.1s
 => => transferring dockerfile: 189B                                       0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 150B                                          0.0s
 => [internal] load metadata for docker.io/library/python:3.11.1-bullseye  2.0s
 => [1/5] FROM docker.io/library/python:3.11.1-bullseye@sha256:cc4910af48  0.0s
 => [internal] load build context                                          0.2s
 => => transferring context: 1.21MB                                        0.2s
 => CACHED [2/5] COPY requirements.txt requirements.txt                    0.0s
 => CACHED [3/5] RUN pip install -r requirements.txt                       0.0s
 => CACHED [4/5] COPY . /app                                               0.0s
 => CACHED [5/5] WORKDIR /app                                              0.0s
 => exporting to image                                                     0.0s
 => => exporting layers                                                    0.0s
 => => writing image sha256:d7b4a64b01b9de03dec4a0732eaf975b7bc68f1daefb4  0.0s
 => => naming to docker.io/library/my-app                    0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/3
 ⠿ Network my_app_default  Created                           0.2s
 ⠿ Container my_app-db-1   Created                           0.1s
 ⠿ Container my_app-web-1  Created                           0.2s
Attaching to my_app-db-1, my_app-web-1
my_app-db-1   | The files belonging to this database system will be owned by user "postgres".
my_app-db-1   | This user must also own the server process.
my_app-db-1   | 
my_app-db-1   | The database cluster will be initialized with locale "en_US.utf8".
my_app-db-1   | The default database encoding has accordingly been set to "UTF8".
my_app-db-1   | The default text search configuration will be set to "english".
my_app-db-1   | 
my_app-db-1   | Data page checksums are disabled.
my_app-db-1   | 
my_app-db-1   | fixing permissions on existing directory /var/lib/postgresql/data ... ok
my_app-db-1   | creating subdirectories ... ok
my_app-db-1   | selecting dynamic shared memory implementation ... posix
my_app-db-1   | selecting default max_connections ... 100
my_app-db-1   | selecting default shared_buffers ... 128MB
my_app-db-1   | selecting default time zone ... Etc/UTC
my_app-db-1   | creating configuration files ... ok
my_app-db-1   | running bootstrap script ... ok
my_app-db-1   | performing post-bootstrap initialization ... ok
my_app-db-1   | syncing data to disk ... ok
my_app-db-1   | 
my_app-db-1   | 
my_app-db-1   | Success. You can now start the database server using:
my_app-db-1   | 
my_app-db-1   |     pg_ctl -D /var/lib/postgresql/data -l logfile start
my_app-db-1   | 
my_app-db-1   | initdb: warning: enabling "trust" authentication for local connections
my_app-db-1   | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
my_app-web-1  | Traceback (most recent call last):
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
my_app-web-1  |     self.connect()
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 263, in connect
my_app-web-1  |     self.connection = self.get_new_connection(conn_params)
my_app-web-1  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/postgresql/base.py", line 215, in get_new_connection
my_app-web-1  |     connection = Database.connect(**conn_params)
my_app-web-1  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/psycopg2/__init__.py", line 122, in connect
my_app-web-1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  | psycopg2.OperationalError: could not connect to server: Connection refused
my_app-web-1  |     Is the server running on host "db" (172.24.0.2) and accepting
my_app-web-1  |     TCP/IP connections on port 5432?
my_app-web-1  | 
my_app-web-1  | 
my_app-web-1  | The above exception was the direct cause of the following exception:
my_app-web-1  | 
my_app-web-1  | Traceback (most recent call last):
my_app-web-1  |   File "/app/manage.py", line 22, in <module>
my_app-web-1  |     main()
my_app-web-1  |   File "/app/manage.py", line 18, in main
my_app-web-1  |     execute_from_command_line(sys.argv)
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
my_app-web-1  |     utility.execute()
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/__init__.py", line 440, in execute
my_app-web-1  |     self.fetch_command(subcommand).run_from_argv(self.argv)
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 402, in run_from_argv
my_app-web-1  |     self.execute(*args, **cmd_options)
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 448, in execute
my_app-web-1  |     output = self.handle(*args, **options)
my_app-web-1  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/base.py", line 96, in wrapped
my_app-web-1  |     res = handle_func(*args, **kwargs)
my_app-web-1  |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/core/management/commands/migrate.py", line 114, in handle
my_app-web-1  |     executor = MigrationExecutor(connection, self.migration_progress_callback)
my_app-web-1  |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/migrations/executor.py", line 18, in __init__
my_app-web-1  |     self.loader = MigrationLoader(self.connection)
my_app-web-1  |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/migrations/loader.py", line 58, in __init__
my_app-web-1  |     self.build_graph()
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/migrations/loader.py", line 235, in build_graph
my_app-web-1  |     self.applied_migrations = recorder.applied_migrations()
my_app-web-1  |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 81, in applied_migrations
my_app-web-1  |     if self.has_table():
my_app-web-1  |        ^^^^^^^^^^^^^^^^
my_app-db-1   | waiting for server to start....2023-01-08 12:43:30.440 UTC [47] LOG:  starting PostgreSQL 15.1 (Debian 15.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/migrations/recorder.py", line 57, in has_table
my_app-web-1  |     with self.connection.cursor() as cursor:
my_app-web-1  |          ^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 323, in cursor
my_app-web-1  |     return self._cursor()
my_app-web-1  |            ^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 299, in _cursor
my_app-web-1  |     self.ensure_connection()
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 281, in ensure_connection
my_app-web-1  |     with self.wrap_database_errors:
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/utils.py", line 91, in __exit__
my_app-web-1  |     raise dj_exc_value.with_traceback(traceback) from exc_value
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 282, in ensure_connection
my_app-web-1  |     self.connect()
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/base/base.py", line 263, in connect
my_app-web-1  |     self.connection = self.get_new_connection(conn_params)
my_app-web-1  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/utils/asyncio.py", line 26, in inner
my_app-web-1  |     return func(*args, **kwargs)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/django/db/backends/postgresql/base.py", line 215, in get_new_connection
my_app-web-1  |     connection = Database.connect(**conn_params)
my_app-web-1  |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-web-1  |   File "/usr/local/lib/python3.11/site-packages/psycopg2/__init__.py", line 122, in connect
my_app-web-1  |     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
my_app-web-1  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
my_app-db-1   | 2023-01-08 12:43:30.457 UTC [47] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my_app-web-1  | django.db.utils.OperationalError: could not connect to server: Connection refused
my_app-web-1  |     Is the server running on host "db" (172.24.0.2) and accepting
my_app-web-1  |     TCP/IP connections on port 5432?
my_app-web-1  | 
my_app-db-1   | 2023-01-08 12:43:30.476 UTC [50] LOG:  database system was shut down at 2023-01-08 12:43:29 UTC
my_app-db-1   | 2023-01-08 12:43:30.490 UTC [47] LOG:  database system is ready to accept connections
my_app-db-1   |  done
my_app-db-1   | server started
my_app-db-1   | CREATE DATABASE
my_app-db-1   | 
my_app-db-1   | 
my_app-db-1   | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
my_app-db-1   | 
my_app-web-1 exited with code 1
my_app-db-1   | 2023-01-08 12:43:31.286 UTC [47] LOG:  received fast shutdown request
my_app-db-1   | waiting for server to shut down....2023-01-08 12:43:31.288 UTC [47] LOG:  aborting any active transactions
my_app-db-1   | 2023-01-08 12:43:31.319 UTC [47] LOG:  background worker "logical replication launcher" (PID 53) exited with exit code 1
my_app-db-1   | 2023-01-08 12:43:31.320 UTC [48] LOG:  shutting down
my_app-db-1   | 2023-01-08 12:43:31.326 UTC [48] LOG:  checkpoint starting: shutdown immediate
my_app-db-1   | 2023-01-08 12:43:31.469 UTC [48] LOG:  checkpoint complete: wrote 918 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.054 s, sync=0.076 s, total=0.149 s; sync files=250, longest=0.023 s, average=0.001 s; distance=4217 kB, estimate=4217 kB
my_app-db-1   | 2023-01-08 12:43:31.488 UTC [47] LOG:  database system is shut down
my_app-db-1   |  done
my_app-db-1   | server stopped
my_app-db-1   | 
my_app-db-1   | PostgreSQL init process complete; ready for start up.
my_app-db-1   | 
my_app-db-1   | 2023-01-08 12:43:31.692 UTC [1] LOG:  starting PostgreSQL 15.1 (Debian 15.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
my_app-db-1   | 2023-01-08 12:43:31.695 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
my_app-db-1   | 2023-01-08 12:43:31.695 UTC [1] LOG:  listening on IPv6 address "::", port 5432
my_app-db-1   | 2023-01-08 12:43:31.701 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my_app-db-1   | 2023-01-08 12:43:31.708 UTC [63] LOG:  database system was shut down at 2023-01-08 12:43:31 UTC
my_app-db-1   | 2023-01-08 12:43:31.720 UTC [1] LOG:  database system is ready to accept connections

Не удается подключиться к db, потому что служба еще не запущена, несмотря на то, что она указана как зависимость. Вот 2-й раз:

% docker compose build && docker compose up
[+] Building 4.8s (11/11) FINISHED                                              
 => [internal] load build definition from Dockerfile                       0.0s
 => => transferring dockerfile: 32B                                        0.0s
 => [internal] load .dockerignore                                          0.0s
 => => transferring context: 34B                                           0.0s
 => [internal] load metadata for docker.io/library/python:3.11.1-bullseye  4.2s
 => [auth] library/python:pull token for registry-1.docker.io              0.0s
 => [1/5] FROM docker.io/library/python:3.11.1-bullseye@sha256:cc4910af48  0.0s
 => [internal] load build context                                          0.1s
 => => transferring context: 8.42kB                                        0.1s
 => CACHED [2/5] COPY requirements.txt requirements.txt                    0.0s
 => CACHED [3/5] RUN pip install -r requirements.txt                       0.0s
 => CACHED [4/5] COPY . /app                                               0.0s
 => CACHED [5/5] WORKDIR /app                                              0.0s
 => exporting to image                                                     0.0s
 => => exporting layers                                                    0.0s
 => => writing image sha256:d7b4a64b01b9de03dec4a0732eaf975b7bc68f1daefb4  0.0s
 => => naming to docker.io/library/my-app                    0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 2/0
 ⠿ Container my_app-db-1   Created                           0.0s
 ⠿ Container my_app-web-1  Created                           0.0s
Attaching to my_app-db-1, my_app-web-1
my_app-db-1   | 
my_app-db-1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
my_app-db-1   | 
my_app-db-1   | 2023-01-08 12:48:54.148 UTC [1] LOG:  starting PostgreSQL 15.1 (Debian 15.1-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
my_app-db-1   | 2023-01-08 12:48:54.152 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
my_app-db-1   | 2023-01-08 12:48:54.153 UTC [1] LOG:  listening on IPv6 address "::", port 5432
my_app-db-1   | 2023-01-08 12:48:54.157 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
my_app-db-1   | 2023-01-08 12:48:54.171 UTC [28] LOG:  database system was shut down at 2023-01-08 12:48:30 UTC
my_app-db-1   | 2023-01-08 12:48:54.187 UTC [1] LOG:  database system is ready to accept connections
my_app-web-1  | Operations to perform:
my_app-web-1  |   Apply all migrations: admin, auth, contenttypes, core, sessions
my_app-web-1  | Running migrations:
my_app-web-1  |   Applying contenttypes.0001_initial... OK
my_app-web-1  |   Applying auth.0001_initial... OK
my_app-web-1  |   Applying admin.0001_initial... OK
my_app-web-1  |   Applying admin.0002_logentry_remove_auto_add... OK
my_app-web-1  |   Applying admin.0003_logentry_add_action_flag_choices... OK
my_app-web-1  |   Applying contenttypes.0002_remove_content_type_name... OK
my_app-web-1  |   Applying auth.0002_alter_permission_name_max_length... OK
my_app-web-1  |   Applying auth.0003_alter_user_email_max_length... OK
my_app-web-1  |   Applying auth.0004_alter_user_username_opts... OK
my_app-web-1  |   Applying auth.0005_alter_user_last_login_null... OK
my_app-web-1  |   Applying auth.0006_require_contenttypes_0002... OK
my_app-web-1  |   Applying auth.0007_alter_validators_add_error_messages... OK
my_app-web-1  |   Applying auth.0008_alter_user_username_max_length... OK
my_app-web-1  |   Applying auth.0009_alter_user_last_name_max_length... OK
my_app-web-1  |   Applying auth.0010_alter_group_name_max_length... OK
my_app-web-1  |   Applying auth.0011_update_proxy_permissions... OK
my_app-web-1  |   Applying auth.0012_alter_user_first_name_max_length... OK
my_app-web-1  |   Applying sessions.0001_initial... OK
my_app-web-1  | Watching for file changes with StatReloader
my_app-web-1  | Performing system checks...
my_app-web-1  | 
my_app-web-1  | System check identified no issues (0 silenced).
my_app-web-1  | January 08, 2023 - 12:49:01
my_app-web-1  | Django version 4.1.5, using settings 'my_app.settings'
my_app-web-1  | Starting development server at http://0.0.0.0:8000/
my_app-web-1  | Quit the server with CONTROL-C.

Он работает так, как должен был в первый раз.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно документации docker compose , depends_on он не ждет, пока сервис будет готов, а только когда он запущен. По моему опыту, запуск контейнера postgres обычно занимает несколько секунд, и, поскольку вам нужно подождать, пока postgres будет готов принимать соединения, рекомендуется использовать некоторую форму управления запуском.

Вы можете использовать пример, который предоставляет Docker, или сделать это самостоятельно в Django, вот пример из аналогичного потока stackoverflow.

Весь смысл заказа на запуск состоит в том, чтобы избежать подобных проблем. Я не понимаю разницы между этим и вообще не указывать его как зависимость. Оба приводят к одному и тому же результату, что делает его довольно бесполезным.

watch-this 08.01.2023 14:17

Я согласен, это в основном бесполезно, поскольку единственное, в чем вы можете быть уверены, используя depends_on, это то, что служба будет запущена первой, а не в том, что она готова. Единственное, о чем я могу думать, так это о том, что это немного более явно для людей, чтобы читать... может быть

Alexander Freyr 08.01.2023 14:28

Другие вопросы по теме