gpt4 book ai didi

mysql - 如何使用 Dockerfile 更改 MySQL 上的默认 IP

转载 作者:行者123 更新时间:2023-11-29 06:25:37 26 4
gpt4 key购买 nike

有没有办法使用 Dockerfile 更改 MySQL 上的 IP?我的应用程序有问题。

我有这样的配置:

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。在其他 block 上,我有一个主机名db,如果我正在使用我的应用程序,则在连接到我的数据库时它可以工作,但是当我尝试运行迁移时,我必须将主机更改为0.0.0.0。 0.0,发现是因为docker 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

我只是厌倦了在迁移之前和之后不断地改变它。

有什么想法只使用本地主机吗?或者像 1.2.3.456 这样的自定义 IP?

这也是我的 docker-compose 文件:

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:

和我的数据库 Dockerfile

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

更新

回答@ckaserer的问题:

Where are you running the migration from? e.g. are you trying to connect from your workstation/docker host to the mysql container?

我通过 npm 使用命令 npm run migration:run

在容器外部运行它

Any error logs you can share?

错误提示无法连接到db:3306,这就是为什么我必须将其更改为0.0.0.0:3306

Can you clarify your migration workflow and where it fails? (including from which system it is executed. e.g. container x, workstation,..)

迁移发生在使用 typeOrm cli 的容器外部,我创建一个迁移,然后 cli 将检查我的 ormconfig.ts 并检查 else block 的类型和主机。 (我不确定这是否是你的要求)

更新

如果我运行迁移,则会出现以下错误:

错误:getaddrinfo ENOTFOUND db db:3306 IP:端口是问题所在。咕噜咕噜。

链接到代码存储库:https://github.com/artoodeeto/ggpo-server

最佳答案

验证

检查容器运行时是否可以在主机上重现以下内容。

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-compose 文件中,您明确公开了 db端口3306到主机上的所有可用接口(interface)。您可以通过运行来检查

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 一起工作的原因。 .

但是为什么我的迁移不起作用?

我们开始吧!就像我说的,你的 ormconfig.ts对于容器内的应用程序来说是正确的 - 但如果您想从主机连接到数据库则不正确。您的主机不知道 DNS 名称 db所以你的ormconfig.ts不管用。为了从您的主机访问它,您需要 host: localhost ,为了让您的服务器正常工作,您需要 host: db 。但你不能同时设置两者。因此,您可能需要引入某种额外的环境配置来区分这两种情况。

if (process.env.NODE_ENV === 'test') {
// test environment database
...
} else if (process.env.NODE_ENV === 'local') {
// new config with host: localhost
} else {
// default
}
<小时/>

2020 年 1 月 9 日的原始答案

不,您不能为 dockerfile 中的镜像分配固定 IP。这会破坏可移植性和可扩展性,因为 IP 需要是唯一的。

host绑定(bind)到0.0.0.0在这种情况下你需要什么。它将 mysql 服务绑定(bind)到所有可用的网络接口(interface)。在你的情况下localhostapp_network在容器内。

因此,您可以从app_network内的任何其他容器访问该容器。或者您可以进入 db容器并通过 mysql 连接直接执行迁移到 localhost .

从工作站访问数据库

你就快到了。您已经有了 db 的端口暴露定义。在你的docker-compose.yml

version: "3.3"
services:
db:
ports:
- "3306:3306"

但是,您无法从外部通过容器名称访问该容器。端口暴露定义port告诉 docker 转发您的主机收到的任何流量 3306db港口容器3306 。也就是说,您可以访问 db使用您的主机 IP 或主机名从您的主机上,因为您已经在运行容器的计算机上,所以您可以简单地使用 localhost127.0.0.1在您的迁移中。

您需要更改用于迁移的 ormconfig.ts。特别是host输入值来自 dblocalhost .

{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "test",
"password": "test",
"database": "test"
}

这应该可以解决您的问题。

<小时/>

奖金

1) 为什么我无法为图像分配 IP

镜像未运行,因此没有 IP 分配。
但是,您可以在 docker-compose.yml 中为容器指定固定 IP,如下所示

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 时被使用。并且不能再次分配。

关于mysql - 如何使用 Dockerfile 更改 MySQL 上的默认 IP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59639845/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com