Проверьте
проверьте, можете ли вы воспроизвести следующее на вашем хосте во время работы ваших контейнеров.
1) запустите ваше приложение
просто выполните docker-compose up
2) подключиться к БД
попытаться подключиться к вашей mysql базе данных с вашего хост-компьютера следующим образом
mysql -u root -ppassword -h 127.0.0.1
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.18 MySQL Community Server - GPL
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
#+--------------------+
| Database |
+--------------------+
| development_db |
| information_schema |
| mysql |
| performance_schema |
| production_db |
| sys |
| test_db |
+--------------------+
7 rows in set (0.01 sec)
Но почему это работает?
Несколько вещей здесь. Во-первых, ваш ormconfig.ts
подходит для вашего приложения в контейнере. Ваш контейнер server
хочет подключиться к контейнеру db
. Это работает. В вашем docker -компонентном файле вы явно указали порт db
3306
для всех доступных интерфейсов на вашем хосте. Вы можете проверить это, запустив
docker container ls
8b5c4dc41892 ggpo-server_server "docker-entrypoint.s…" 47 hours ago Up 5 seconds 0.0.0.0:8000->8000/tcp ggpo-server_server_1
a0ca405d8020 ggpo-server_db "docker-entrypoint.s…" 47 hours ago Up 6 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp ggpo-server_db_1
Это означает, что ваша база данных будет доступна на вашем хосте в 127.0.0.1:3306
и [HOST-IP]:3306
. Вот почему предыдущий mysql connect работал с 127.0.0.1
.
Но почему моя миграция не работает?
Здесь мы go! Как я уже говорил, ваш ormconfig.ts
подходит для вашего приложения в контейнере, но не в том случае, если вы хотите подключиться к базе данных с вашего хоста. Ваш хост не знает о DNS-имени db
, поэтому ваш ormconfig.ts
не будет работать. Для доступа к нему с вашего хоста вам нужно host: localhost
, а для работы вашего сервера вам нужно host: db
. Но вы не можете установить оба. Поэтому вы можете захотеть ввести какую-то дополнительную конфигурацию env, которая различает 2 сценария ios.
if (process.env.NODE_ENV === 'test') {
// test environment database
...
} else if (process.env.NODE_ENV === 'local') {
// new config with host: localhost
} else {
// default
}
Оригинальный ответ от 9.01.2020
Нет, вы можете Не назначайте фиксированный IP для изображения в вашем файле Docker. Это нарушит мобильность и масштабируемость, поскольку IP-адрес должен быть уникальным.
В этом случае вам потребуется привязка host
к 0.0.0.0
. Он связывает сервис mysql со всеми доступными сетевыми интерфейсами. В вашем случае до localhost
и app_network
внутри контейнера.
Таким образом, вы можете добраться до контейнера из любого другого контейнера внутри вашего app_network
или вы можете go в контейнер db
и выполнить миграцию напрямую через mysql соединение с localhost
.
доступом к БД с вашей рабочей станции
Вы почти там. У вас уже есть определение экспозиции порта для вашего db
в вашем docker-compose.yml
.
version: "3.3"
services:
db:
ports:
- "3306:3306"
Однако вы не можете получить доступ к контейнеру по его имени из внешнего мира. Определение экспозиции порта port
указывает docker пересылать любой трафик c, который ваш хост получает на 3306
, в контейнер db
на порту 3306
. Тем не менее, вы можете, следовательно, получить доступ к db
с вашего хоста, используя IP-адрес вашего хоста или имя хоста, поскольку вы уже находитесь на машине, на которой запущен контейнер, вы можете просто использовать localhost
или 127.0.0.1
в своей миграции.
Вам необходимо изменить ormconfig.ts, который вы используете для своей миграции. В частности, значение host
от db
до localhost
.
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "test",
"password": "test",
"database": "test"
}
Это должно решить вашу проблему.
Бонус
1) Почему я не могу назначить IP для изображения
Изображение не запущено, поэтому нет назначения IP.
Однако вы можете указать фиксированный IP для вашего контейнера в вашей docker -композиции .yml вот так
version: '2'
services:
app:
image: busybox
command: ifconfig
networks:
app_net:
ipv4_address: 172.18.18.10
networks:
app_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 172.18.18.0/24
gateway: 172.18.18.1
2) почему не следует делать 1)
IP - это уникальный идентификатор системы в этой конкретной сети. Так что же происходит, когда вы хотите иметь 2 экземпляра app
?
docker-compose up --scale app=2
Creating network "playground_app_net" with driver "bridge"
Creating playground_app_1 ... done
Creating playground_app_2 ... error
ERROR: for playground_app_2 Cannot start service app: b'Address already in use'
ERROR: for app Cannot start service app: b'Address already in use'
ERROR: Encountered errors while bringing up the project.
Docker, которые сообщают вам, что IP-адрес уже используется при первом создании app
и не может быть назначен снова.