前言

最近在docker部署了几个容器需要用到数据库的,但是又不想用host模式,所以查了一些相关资料,做个记录。

容器设置

一般用docker-compose安装,通用的格式见下代码

version: '3'
services:
  容器:
    image: 地址
    restart: always
    network_mode: "bridge"
    ports:
      - 本地端口:容器端口
    environment:
      DATABASE_TYPE: mysql
      DATABASE_URL: mysql://username:secret@172.17.0.1:3306/数据库名称
      APP_SECRET: replace-me-with-a-random-string
    container_name: 容器名称

数据库地址

这里需要注意的是network_mode我们选择bridge。之前查了很多资料,基本上说的是通过开放数据库端口到公网,然后通过公网ip:端口号的模式访问。但是这个方式暴露数据库到公网了,很不安全。这里讲一种方法,可以直接通过访问桥接网络的网关来访问宿主机的服务。所以这里数据库的地址就变成"172.17.0.1",这个地址是”bridge“的网关。每个容器的网关地址不同,可以通过以下指令查看:

docker inspect 容器名称

一般网络这一项是在最下面,"Gateway"这一项:

数据库权限

数据库的访问权限要设置一下,不然一般是只能本地ip地址访问。

  1. 登录MySQL控制台

    mysql -u root -p    // -u表示用户,-p表示需要密码,root可以改成其他用户
    Enter password:        // 输入密码
    use mysql            // 切换到数据库

  2. 查看下每个数据库的访问权限

    SELECT user, host FROM mysql.user WHERE user='用户名';    // 注意分号';'

    右边host显示的可以访问的ip,这里可以看到只有"localhost",也就是只能本地访问。我们需要增加一个上面提到的容器网关地址对应的网段,这里是"172.17.0.%",'%'表示只匹配前面三个。

  3. 删除用户的原有主机权限

    只有一个本地访问的可以跳过这一步

    REVOKE ALL PRIVILEGES ON *.* FROM '用户名'@'原有主机地址';
    FLUSH PRIVILEGES;
  4. 增加访问ip权限

    // 注意密码是你下次访问的密码,建议设置成之前一样
    GRANT ALL PRIVILEGES ON *.* TO '用户名'@'新主机地址' IDENTIFIED BY '密码';
    FLUSH PRIVILEGES;

最后

到这里容器就可以连接到宿主数据库了