我有一个Nginx在码头集装箱里运行。我在主机系统上运行了MySql。我想从我的容器中连接到MySql。MySql仅绑定到本地主机设备。
是否有任何方法可以从这个docker容器连接到这个MySql或本地主机上的任何其他程序?
这个问题与“如何从docker容器中获取docker主机的IP地址”不同,因为docker主机IP地址可以是网络中的公共IP或私有IP,而这些IP可能在docker容器内无法访问(如果托管在AWS或其他地方,我指的是公共IP)。即使你有docker主机的IP地址,这并不意味着你可以从容器内连接到docker主机,因为你的docker网络可能是overlay、host、bridge、macvlan、none等,这限制了该IP地址的可达性。
要使一切正常工作,您需要为服务器(caddy,nginx)创建一个配置,其中主域将为“docker.for.mac.localhost”http://localhost/api“在”http://docker.for.mac.localhost/api"
码头组合.yml
backend:
restart: always
image: backend
build:
dockerfile: backend.Dockerfile
context: .
environment:
# add django setting.py os.getenv("var") to bd config and ALLOWED_HOSTS CORS_ORIGIN_WHITELIST
DJANGO_ALLOWED_PROTOCOL: http
DJANGO_ALLOWED_HOSTS: docker.for.mac.localhost
POSTGRES_PASSWORD: 123456
POSTGRES_USER: user
POSTGRES_DB: bd_name
WAITDB: "1"
volumes:
- backend_static:/app/static
- backend_media:/app/media
depends_on:
- db
frontend:
restart: always
build:
dockerfile: frontend.Dockerfile
context: .
image: frontend
environment:
# replace baseURL for axios
API_URL: http://docker.for.mac.localhost/b/api
API_URL_BROWSER: http://docker.for.mac.localhost/b/api
NUXT_HOST: 0.0.0.0
depends_on:
- backend
caddy:
image: abiosoft/caddy
restart: always
volumes:
- $HOME/.caddy:/root/.caddy
- ./Caddyfile.local:/etc/Caddyfile
- backend_static:/static
- backend_media:/media
ports:
- 80:80
depends_on:
- frontend
- backend
- db
Caddyfile.local(Caddyfile.local)
http://docker.for.mac.localhost {
proxy /b backend:5000 {
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}
}
proxy / frontend:3000 {
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}
}
root /
log stdout
errors stdout
gzip
}
http://docker.for.mac.localhost/static {
root /static
}
http://docker.for.mac.localhost/media {
root /media
}
django设置.py
ALLOWED_HOSTS = [os.getenv("DJANGO_ALLOWED_HOSTS")]
CORS_ORIGIN_WHITELIST = [f'{os.getenv("DJANGO_ALLOWED_PROTOCOL")}://{os.getenv("DJANGO_ALLOWED_HOSTS")}']
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": os.getenv("POSTGRES_DB"),
"USER": os.getenv("POSTGRES_USER"),
"PASSWORD": os.getenv("POSTGRES_PASSWORD"),
"HOST": "db",
"PORT": "5432",
}
}
nuxt.config.js(baseURL变量将覆盖环境的API_URL)
axios: {
baseURL: 'http://127.0.0.1:8000/b/api'
},
我通过在MySQL中为容器的ip创建一个用户来解决这个问题:
$ sudo mysql<br>
mysql> create user 'username'@'172.17.0.2' identified by 'password';<br>
Query OK, 0 rows affected (0.00 sec)
mysql> grant all privileges on database_name.* to 'username'@'172.17.0.2' with grant option;<br>
Query OK, 0 rows affected (0.00 sec)
$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
<br>bind-address = 172.17.0.1
$ sudo systemctl restart mysql.service
然后在容器上:jdbc:mysql://<b>172.17.0.1</b>:3306/database_name
要使一切正常工作,您需要为服务器(caddy,nginx)创建一个配置,其中主域将为“docker.for.mac.localhost”http://localhost/api“在”http://docker.for.mac.localhost/api"
码头组合.yml
backend:
restart: always
image: backend
build:
dockerfile: backend.Dockerfile
context: .
environment:
# add django setting.py os.getenv("var") to bd config and ALLOWED_HOSTS CORS_ORIGIN_WHITELIST
DJANGO_ALLOWED_PROTOCOL: http
DJANGO_ALLOWED_HOSTS: docker.for.mac.localhost
POSTGRES_PASSWORD: 123456
POSTGRES_USER: user
POSTGRES_DB: bd_name
WAITDB: "1"
volumes:
- backend_static:/app/static
- backend_media:/app/media
depends_on:
- db
frontend:
restart: always
build:
dockerfile: frontend.Dockerfile
context: .
image: frontend
environment:
# replace baseURL for axios
API_URL: http://docker.for.mac.localhost/b/api
API_URL_BROWSER: http://docker.for.mac.localhost/b/api
NUXT_HOST: 0.0.0.0
depends_on:
- backend
caddy:
image: abiosoft/caddy
restart: always
volumes:
- $HOME/.caddy:/root/.caddy
- ./Caddyfile.local:/etc/Caddyfile
- backend_static:/static
- backend_media:/media
ports:
- 80:80
depends_on:
- frontend
- backend
- db
Caddyfile.local(Caddyfile.local)
http://docker.for.mac.localhost {
proxy /b backend:5000 {
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}
}
proxy / frontend:3000 {
header_upstream Host {host}
header_upstream X-Real-IP {remote}
header_upstream X-Forwarded-For {remote}
header_upstream X-Forwarded-Port {server_port}
header_upstream X-Forwarded-Proto {scheme}
}
root /
log stdout
errors stdout
gzip
}
http://docker.for.mac.localhost/static {
root /static
}
http://docker.for.mac.localhost/media {
root /media
}
django设置.py
ALLOWED_HOSTS = [os.getenv("DJANGO_ALLOWED_HOSTS")]
CORS_ORIGIN_WHITELIST = [f'{os.getenv("DJANGO_ALLOWED_PROTOCOL")}://{os.getenv("DJANGO_ALLOWED_HOSTS")}']
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": os.getenv("POSTGRES_DB"),
"USER": os.getenv("POSTGRES_USER"),
"PASSWORD": os.getenv("POSTGRES_PASSWORD"),
"HOST": "db",
"PORT": "5432",
}
}
nuxt.config.js(baseURL变量将覆盖环境的API_URL)
axios: {
baseURL: 'http://127.0.0.1:8000/b/api'
},
我做了一个类似于上述帖子的黑客,获取本地IP以映射到容器中的别名(DNS)。主要问题是使用一个在Linux和OSX中都有效的简单脚本动态获取主机IP地址。我在两种环境中都使用了这个脚本(即使在配置了“$LANG”!=“en_*”的Linux发行版中也是如此):
ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1
因此,使用Docker Compose,完整的配置将是:
启动脚本(docker run.sh):
export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up
docker-compose.yml文件:
myapp:
build: .
ports:
- "80:80"
extra_hosts:
- "dockerhost:$DOCKERHOST"
然后改变http://localhost到http://dockerhost在您的代码中。
有关如何定制DOCKERHOST脚本的更高级指南,请阅读本文并解释其工作原理。