Как изменить IP-адрес по умолчанию на mysql с помощью Dockerfile - PullRequest
0 голосов
/ 08 января 2020

Здравствуйте, есть ли способ изменить IP на mysql, используя dockerfile? потому что у меня проблема с моим приложением.

У меня есть такая конфигурация:

let ormConfig: any;

if (process.env.NODE_ENV === 'test') {
  // test environment database should be drop every time. so synchronize should be true for this config
  ormConfig = {
    type: 'mysql',
    host: '0.0.0.0',
    // host: 'localhost', // not needed if run on docker
    username: 'root',
    password: 'password',
    database: 'test_db',
    synchronize: true,
    dropSchema: true,
    entities: ['src/models/**/*.ts']
  };
} else {
  ormConfig = {
    type: 'mysql',
    host: 'db', // docker service database name
    // host: 'localhost', // not needed if run on docker
    // port: 3306, // not needed if run on docker
    username: 'root',
    password: 'password',
    database: 'development_db',
    synchronize: false,
    logging: true,
    entities: ['src/models/**/*.ts'],
    migrations: ['db/migrations/**/*.ts'],
    subscribers: ['src/subscribers/**/*.ts'],
    cli: {
      entitiesDir: 'src/models',
      migrationsDir: 'db/migrations',
      subscribersDir: 'src/subscribers'
    }
  };
}

export = ormConfig;

я использую typeorm для своего ORM. В другом блоке у меня есть имя хоста db, это работает при подключении к моей БД, если я использую мое приложение, но когда я попытался запустить миграцию, мне нужно изменить хост на 0.0.0.0 и выяснить, что это из-за * Контейнер 1072 * mysql (изображение server_db):

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
aaaa4d178537        server_server       "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:8000->8000/tcp              server_server_1
e5021687b86b        server_db           "docker-entrypoint.s…"   About an hour ago   Up About an hour    0.0.0.0:3306->3306/tcp, 33060/tcp   server_db_1

Я просто устал его менять и менять до и после миграции.

Есть идеи просто использовать localhost? или пользовательский IP вроде 1.2.3.456 что-то подобное?

также вот мой docker -компонентный файл:

version: "3.3"
services:
  db:
    build: ./db
    restart: always
    env_file:
      - .env
    ports:
      - "3306:3306"
    networks:
      - app_network
  server:
    depends_on:
      - "db" # this is important for sql connection. it has to wait for mysql to establish connection then run this bish
    build: .
    command: ["npm", "run", "dev"]
    restart: always
    ports:
      - "8000:8000"
    volumes:
      - /server/node_modules/ # added this because of bcrypt elm error
      - type: bind
        source: .
        target: /server # this name is from dockerfile workdir
    networks:
      - app_network

networks:
  app_network:
volumes:
  app_volume:

и мой Dob-файл базы данных

FROM mysql:8.0.18
EXPOSE 3306
COPY ./init_db.sql /docker-entrypoint-initdb.d/

ОБНОВЛЕНИЕ

, чтобы ответить на вопрос @ ckaserer

  • Откуда вы запускаете миграцию? Например, вы пытаетесь подключиться с вашей рабочей станции / docker хоста к mysql контейнеру?

    • ответ: я запускаю его вне контейнера через npm с помощью команды npm run migration:run
  • Любые журналы ошибок, которыми вы можете поделиться?

    • ответ: ошибка говорит, что не может подключиться к db:3306, поэтому я должен изменить его на 0.0.0.0:3306
  • Вы можете уточнить ваш рабочий процесс миграции и где он терпит неудачу? (в том числе из какой системы он выполняется. например, контейнер x, рабочая станция, ..)

    • Ответ: миграция происходит вне контейнера с использованием typeOrm cli, я создаю миграцию, затем cli проверяет мой ormconfig.ts и проверит блок else на тип и хост. (я не уверен, что это то, о чем вы спрашиваете)

ОБНОВЛЕНИЕ

вот ошибка, если я запустил миграцию.

Error: getaddrinfo ENOTFOUND db db:3306 IP: порт является проблемой. grrrr.

Ссылка на хранилище кодов: https://github.com/artoodeeto/ggpo-server

Ответы [ 2 ]

1 голос
/ 08 января 2020

Вы можете запустить обе ваши службы в network_mode: "host", и тогда оба ваших приложения будут работать в локальной сети компьютера. Нет необходимости сопоставлять порт в этом случае, просто удалите порты.

1 голос
/ 08 января 2020

Проверьте

проверьте, можете ли вы воспроизвести следующее на вашем хосте во время работы ваших контейнеров.

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 и не может быть назначен снова.

...