格物躬行博客(基于 WordPress 平台)迁移到 Docker 容器下的 Nginx + PHP-FPM + MySQL 从入门到踩坑之路

0.背景

Docker 容器的灵活与强大,尤其是在保持轻量化的同时能进行项目整体打包移植,简直是它脑门上熠熠生辉的金字招牌!格物躬行博客搭建在租用的 VPS 上,随时都有主动或被动卷铺盖走人的可能性,也梦想着格物躬行博客能越来越好越来越流行,时刻准备着扩展扩展展展展展……总而言之,需要方便的扩展和搬家。Docker 容器大红大紫之时就注意到它了,一直也就是知道而已,直到最近入门探索了一下,前前后后折腾了近一个月,掉了不少坑,真想过算了吧放弃这个稀烂的东西,哈哈O(∩_∩)O~,最后,终于修得正果从坑里成功的爬出来了。
网上很多教程,都是用 Docker 容器做练手的,从头开始的,没有涉及实际生产运行环境和数据的迁移,可谓是白纸一张随便画,而格物躬行博客运行好几年了(就是人气忒低迷~~忧伤!),有一点点数据的积累,不能从头开始,需要考虑顾及很多方面,否则立马死给你看,HTTP 403、HTTP 404、HTTP 500、HTTP 503……还有数据库连不上等等问题。另外,格物躬行博客是构建在 WordPress 上的个人小站,安装的 Wordfence WAF 插件也让我在迁移至 Docker 时推我入坑了一次!

1.原理解析

首先,直接利用 Docker 库中最新的 Nginx、PHP-FPM、MySQL 搭建好 WordPress 运行的必备环境 LNMP 环境;然后,将需要迁移的网站的全部文件打包搬运或者用 Rsync 同步, 再将网站数据库文件及全部文件打包搬运或者用 Rsync 同步;再然后,运行 Docker 容器进行容器目录与实际使用目录之间的映射挂载。最后,按需修改并映射挂载自己定制的配置文件。

2.行动指南—— Docker

首先,安装 Docker 容器服务程序,yum 或者 apt-get 等据实各取所需吧,然后是从 Docker 容器官方仓库拉取镜像( image ),最后运行容器。

  1. #安装一些必要的系统工具:
  2. # yum-utils 提供了 yum-config-manager 实用程序,用于设置yum源
  3. # 可选: device mapper 存储驱动需要用到的 device-mapper-persistent-data 和 lvm2 
  4. sudo yum install -y yum-utils device-mapper-persistent-data lvm2
  5. #设置容器 Docker 使用的官方 Yum 源
  6. sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  7. sudo yum makecache fast
  8. sudo yum update -y
  9. sudo yum install docker-ce -y 
  10.  
  11. sudo systemctl start docker   
  12. #安装好之后,记得启动 docker 服务的守护进程,否则报错,如Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
  13. #因为 Docker 是 服务器----客户端架构,命令行运行 docker 命令的时候,需要本机有已经启动的 Docker 服务。
  14.  
  15. #查找查看 xxx 镜像( image ),然后下载(即 pull )下来
  16. sudo docker search nginx  # OFFICIAL 列" [OK] "标识的是官方的,否则为第三方上传的,建议优先选择官方 ,或者选择" STARS " 比较多的。
  17.  
  18. sudo docker pull nginx                     #默认拉取的是最新最靠前的官方镜像( image )
  19. sudo docker pull bitnami/php-fpm           #这里拉取的是第三方 php-fpm 镜像,比较小巧玲珑,适合于 Nginx 搭配
  20. sudo docker pull mysql
  21.  
  22. sudo docker rmi -f bitnami/php-fpm         #清除 php-fpm 镜像  !!! PS:先清除,在 pull 可以用来进行镜像的升级噢 !!!
  23.  
  24. # 列出所有已经拉取到本地的镜像( image )
  25. sudo docker images         #或者 sudo docker image ls  #注意: images 或者 image ls  
  26.  
  27. #有了镜像( image ),就好比有了一个特定功能的模具,从模具到实际物品就是从 镜像 到 容器 了
  28. #所以,我们真正能使用的是:容器( docker ),也意味着,由一个镜像 image 可以创建多个容器 docker 
  29.  
  30. sudo docker run --name mynginx -d nginx
  31. #使用 nginx 的镜像,创建一个容器,并且( --name 参数)是人为的指定这个容器的名为 mynginx ,由镜像生成容器时,指定容器名不能重名。
  32. # -d 参数是指后台运行,否则会自动退出
  33.  
  34. sudo docker run -it nginx /bin/bash  
  35. #使用 nginx 的镜像,创建一个容器,并进入在容器内,以交互式方式执行容器内的 /bin/bash 命令,即产生一个 shell  终端。
  36. # -i  参数是以交互模式运行容器,通常与 -t 同时使用;-t 参数是为容器重新分配一个伪输入终端,通常与 -i 同时使用。
  37. #这里省略了创建的容器名称即 --name 参数,会使用无规律的随机字母组合生成容器名。
  38.  
  39. sudo docker ps -a # 查看所有的容器的命令
  40.  
  41. #如果需要使用已经存在的容器,而不是创新新的容器,就应该使用如下命令了
  42. sudo docker start <容器 ID、容器名>     
  43. sudo docker stop <容器 ID、容器名>       
  44. sudo docker restart <容器 ID、容器名>   
  45.  
  46. # 容器启动后,用 exec 命令交互式执行容器内命令,如果从这个容器退出,不会导致容器的自动停止。
  47. sudo docker exec -it  <容器 ID、容器名>  [COMMAND] 
  48.  
  49. sudo docker logs -f  <容器 ID、容器名>      #查看容器 Docker 的运行日志,排查故障时很有用的
  50. sudo docker inspect  <容器 ID、容器名>      #查看容器 Docker 的底层信息,返回一个 JSON 文件记录着 Docker 容器的配置、状态等等信息,很详细
  51. sudo docker network ls                      #查看容器 Docker 的网络信息 
  52.  
  53. #删除容器  或者 清理掉所有处于终止状态的容器
  54. sudo docker rm -f  <容器 ID>    #或者    sudo docker rm -f  <容器名>
  55. sudo docker container prune
  56.  
  57. #从容器内复制文件到宿主机
  58. sudo docker cp containerr-name:container_path host_path
  59.  
  60. #从宿主机复制文件到容器内
  61. sudo docker cp host_path container-name:container_path
  62.  
  63. #最后,我们来看一下实际中使用的完整命令
  64.  sudo docker run --privileged=true --name nginx-dk -p 80:80 -p 443:443 -v /wwwroot:/usr/share/nginx/html -v /wwwlogs:/var/log/nginx -v /docker/conf/nginx:/etc/nginx:ro -d nginx
  65.  #上面的这条命令是:以 nginx 镜像创建一个指定名字的叫 nginx-dk 的容器," --privileged=true "参数是 容器 nignx-dk 获取宿主机root权限
  66.  # -p 参数是进行端口映射,如" -p 80:80 "将容器内的 80 端口与宿主机的 80 端口进行绑定
  67.  # -v 参数用于宿主机与容器之间的文件目录映射,如" -v /wwwlogs:/var/log/nginx "是指 nginx-dk 容器里面的" /var/log/nginx "将对应到宿主机的" /wwwlogs " 目录
  68.  # " -v /docker/conf/nginx:/etc/nginx:ro "是配置文件存放位置," :ro "表示该映射目录只读
  69.  #目录和端口的映射非常有用,相当于是打通了 容器 docker 与 宿主机之间的通道,让两者之间既有必有的隔离(方便打包迁移)又有必要的联系(如配置文件的一致性)

这种一条条命令的方式,比较适合早期调试或者单一功能部件测试,因为要一条条是输入,一条条的修改测试,显然会造成日后批量部署或者迁移时的不方便,除非将需要用到的各个命令做一个脚本文件。而且,尤其是各个容器之间有相互关联时,这种方式就非常不方便了,也不能体现各关联容器之间的逻辑关系,如 Nginx 调用 PHP 解析器处理 PHP 脚本,PHP 又要调用 MySQL 数据库时。有问题不可怕,因为有解决办法就行,所以下面该 Docker Compose 出场了!!!

3.行动指南—— Docker Compose

Docker Compose 是用于定义、运行和管理多个容器 Docker 的应用程序,用过不恰当比喻就像“xxx电脑管家”,管理着电脑里面的各种软件。Docker Compose 使用的是 YML 文件来定义和配置容器 Docker ,最后,使用相对简洁的命令就可以对容器进行统一的、批量的管理了,有点类似使用 Shell 脚本运行管理容器的感觉,但是它有着自己专属的指令,比 Shell 脚本使用起来方便。

  1. # docke-compose 不能直接用 yum 安装,需要使用 pip ;还可以在 GitHub 上下载脚本后安装。
  2. sudo yum install epel-release
  3. sudo yum -y install python-pip
  4.  
  5. #升级一下 pip ,否则在使用时会提示:...You should consider upgrading via the 'pip install --upgrade pip' command.
  6. sudo pip install --upgrade pip   
  7.  
  8. sudo pip install docker-compose
  9.  
  10. #如果报错:ERROR: jsonschema 3.2.0 has requirement six>=1.11.0, but you'll have six 1.9.0 w                                    hich is incompatible.
  11. sudo pip install six --user -U
  12.  
  13. #构建容器,默认使用当前目录下的 docker-compose.yml, docker-compose.yaml,否则需指明  yml 文件路径
  14. sudo docker-compose build   
  15. #构建容器,需要提前拉取 pull  准备好需要使用的 镜像 image
  16.  
  17. # Docker Compose 将所管理的容器分为三层,分别是工程(project)、服务(service)、容器(container)
  18. # Docker Compose 运行目录下的所有文件(docker-compose.yml)组成一个工程,一个工程包含多个服务,
  19. #每个服务中定义了容器运行的镜像、参数、依赖,一个服务可包括多个容器实例
  20.  
  21. sudo docker-compose up      #构建、启动容器,需要在 yml 文件路径下或指明 yml 文件路径,前台启动,会输出很多信息,方便进行调试
  22. sudo docker-compose up -d   #需要容器在后台启动并运行所有的容器,使用 -d 参数
  23. sudo docker-compose start   #启动一个已经存在的容器工程或指定的服务,需要在 yml 文件路径下或指明 yml 文件路径
  24. sudo docker-compose stop    #启动一个已经存在的容器工程或指定的服务,需要在 yml 文件路径下或指明 yml 文件路径
  25. sudo docker-compose ps      #列出所有运行的容器工程,需要在 yml 文件路径下或指明 yml 文件路径
  26. sudo docker-compose logs    #查看服务日志输出,需要在 yml 文件路径下或指明 yml 文件路径
  27.  
  28. sudo docker-compose rm      #删除一个容器工程或指定的服务,需要在 yml 文件路径下或指明 yml 文件路径
  29. sudo docker-compose kill    #通过发送 SIGKILL 信号来停止一个容器服务,需要在 yml 文件路径下或指明 yml 文件路径

我们再来看看 docker-compose.yml 文件吧,这个文件编写上也有很大要注意的地方。下面是我自己使用的。

  1. version: "3"          # version 关键字指定 docker-compose.yml 文件的格式,注意每行的结尾要加“ 空格  ”,建议加2个!double 双倍空格噢!
  2.                       #空行,里面也要有“ 空格 ”,不要直接回车换行,坑!坑!坑!
  3. networks:             # networks 是关键字,指定一个网络,便于实现网络隔离,否则,容器启动后,都会被加入 app_default网络中
  4.    lnmp-subnet:       #自己指定的网络名称
  5.      driver: bridge   #指定创建的网络类型是: bridge  即桥接类型,
  6. 	                  #在自定义的桥接网络中,容器之间可以通过名字会别名互相访问,否则只能是IP,而每次容器启动时 IP 可能会变化。
  7. services:             # services 关键字定义具体的容器 Docker 服务了    
  8.  
  9.    phpfpm-dk:         #创建的 php-fpm 这个容器的服务名称为 phpfpm-dk (这个拍脑袋随便取的,自己好记理解就行)
  10.      image: 'bitnami/php-fpm:latest'      #指明使用的镜像文件
  11.      networks:                            #指明使用的网络,这个是前面定义好的
  12.        - lnmp-subnet
  13.      volumes:                             #volumes 关键字是进行卷映射,可以理解成目录级的映射;devices 关键字可以用来构建设备映射
  14.       - /docker/conf/php/php.ini:/opt/bitnami/php/etc/php.ini:ro    #对 PHP 的配置文件进行映射,这里是对具体的单个文件进行映射,有时候又会映射失败,文件变目录
  15.       # php.ini 不适合直接映射,因为附加组件如 opcache 等在 docker 内,建议:附加组件依然使用容器内的路径及文件 ,或者用 custom.ini 重载
  16.       - /docker/conf/php/conf.d/custom.ini:/opt/bitnami/php/etc/conf.d/custom.ini:ro  #如很方便的开启或关闭 显示错误详细信息(display_errors = On 、Off)
  17.  
  18.       - /docker/conf/php/php-fpm.conf:/opt/bitnami/php/etc/php-fpm.conf:ro 
  19.       - /docker/conf/php/php-fpm.d/www.conf:/opt/bitnami/php/etc/www.conf:ro
  20. #      - /docker/conf/php/php-fpm.d/*.conf:/opt/bitnami/php/etc/php-fpm.d/*.conf:ro     #这种是错误的写法,不能用通配符进行文件映射
  21.  
  22.       - /phplogs:/opt/bitnami/php/logs:rw     #这个就是日志目录的映射了
  23.       - /wwwroot/default:/app/default:rw      #这个就是网站默认目录的映射,这里有坑,后面会详细说明一下的,坑了我很久很久很久.....
  24.       - /wwwroot/go2do.net:/app/go2do.net:rw  #这个就是网站特定目录的映射,这里有坑,后面会详细说明一下的,坑了我很久很久很久.....
  25.      links:                                   # links 关键字将指定容器连接到当前连接,可以设置别名,避免ip方式导致的容器重启动态改变的无法连接情况
  26.       - mysql-dk                              #服务之间可以使用服务名称相互访问,links 还允许定义一个别名,从而使用该别名访问其它服务
  27.      privileged: true                         #允许容器获取宿主机root权限,主要为了解决文件的权限问题
  28.      restart: always                          #容器停止后,自动重启
  29.  
  30.    nginx-dk: 
  31.      image: 'nginx:latest'
  32.      depends_on:            #设置依赖关系,会先启动 phpfpm-dk 这个容器,再启动 nginx-dk 容器
  33.        - phpfpm-dk
  34.      networks: 
  35.        - lnmp-subnet
  36.      ports:                 # ports 关键字设置容器服务程序对外提供的服务端口
  37.        - "80:80"            #指宿主机的" 80 "即 WEB 服务端口与容器的" 80 "端口直接关联
  38.        - "443:443"
  39.      volumes: 
  40.        - /docker/conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro  
  41.        - /docker/conf/nginx/fastcgi.conf:/etc/nginx/fastcgi.conf:ro 
  42.        - /docker/conf/nginx/vhost:/etc/nginx/vhost:ro       
  43.        - /docker/conf/nginx/rewrite:/etc/nginx/rewrite:ro  
  44.        - /docker/conf/nginx/htpassword:/etc/nginx/htpassword:ro   
  45.        - /docker/conf/nginx/htpassword1:/etc/nginx/htpassword1:ro   
  46.  
  47.        - /var/run/nginx:/var/run:rw 
  48.        - /wwwlogs:/var/log/nginx:rw 
  49.  
  50.        - /wwwroot/default:/usr/share/nginx/html/default:rw  
  51.        - /wwwroot/go2do.net:/usr/share/nginx/html/go2do:rw  
  52.        - /wwwroot/go2do.net/cdn:/usr/share/nginx/html/go2do.net/cdn:rw  
  53.        - /wwwroot/go2do.net/link:/usr/share/nginx/html/go2do.net/link:ro  
  54.      privileged: true 
  55.      restart: always  
  56.  
  57.    mysql-dk:  
  58.      image: 'mysql:latest'   
  59.      networks:  
  60.        - lnmp-subnet   
  61.      ports:  
  62.        - "3306:3306"   
  63.      environment:          # environment 关键字用于传递参数,如下面的数据库的启动用户及密码,与 environment 关联的还有个 env_file 参数,这里没用到就不说了
  64.        MYSQL_ROOT_PASSWORD: '123'  
  65.        MYSQL_USER: 'root'   
  66.        MYSQL_PASS: '123'  
  67.      volumes:   
  68.        - /docker/conf/mysql/my.cnf:/etc/my.cnf:ro 
  69.  
  70. #       - /var/run/mysqld:/var/run/mysqld:rw  
  71.        - /mysql:/var/lib/mysql:rw  
  72.      privileged: true  
  73.      restart: always  
  74.  
  75.  
  76. ##!!! 编写这个文件时,特别要注意文件的格式,包括上面的对齐方式所呈现出的层次关系,否则就是各种折腾闹心( ⊙ o ⊙ )啊!!!##

PS1:links 用法是链接到其它服务中的容器, 该选项是 容器 docker 遗留的历史选项, 目前已经可以被 aliases 网络别名标签功能代替,并且如果service在同一个network中,即使不用links也可以通过容器服务名称进行通信。

4.掉坑指南了—— 泪流满面( 〒▽〒 )

再来聊聊踩坑之旅吧,哎,一把辛酸泪,坑得我恨不得把电脑都砸个稀烂了。

4.1 用户名、用户组及权限问题

就拿 Nginx 来说吧,它有 Master 和 worker 两种进程,Master 进程用于管理 worker 进程,worker 进程用于 WEB 服务,一般情况下,我们用 root 权限启动的是 Nginx 的 Master 进程,worker 进程依据 nginx.conf 文件中的” user nobody; “或者” user nginx; “或者” user www-data; “这个配置而定,在非容器环境时,这个参数是我们自己设定,因此我们明确的知道这个用户名是什么,可以按需创建用户和设定用户。但是,在容器里面这个用户什么,就不得而知了,如果在对 Nginx 的 nginx.conf 这个配置文件进行映射时,宿主机里该文件中的用户名、用户组与容器里面的不一致,会导致 Nginx 的启动失败或者文件无法读取等问题。所以,在现有项目工程的容器化迁移时,需要注意这类问题。
解决办法:我用方法是用” sudo docker exec -it <容器 ID、容器名> … “进入容器内,查看容器内的默认配置文件、shadow、group等文件,然后在宿主机中创建相同的用户及用户组。

4.2 Nginx 与 PHP-FPM 搭配后的路径传递问题

出现这种问题的典型症状就是:访问 html 类的静态文件时是正常的,访问 PHP 动态文件不正常,报 404 错误(指文件或资源未找到),这就让人很懵逼了,因为文件明明在那里,html 类文件可以找到,凭什么 PHP 文件就找不到啊啊啊啊O(≧口≦)O 对!就是这个问题快把我搞疯了疯了风疯疯癫癫了,哈哈O(∩_∩)O~
造成这个问题的原因是:Nginx 不直接解析 PHP 文件,需要传递给 FastCGI 接口后面的 PHP-FPM ,Nginx在传递这个待解析的 PHP 文件时,不是 把这个文件直接当一串数据发送给 PHP-FPM ,不然遇到超大 PHP 文件岂不是把 Nginx 累死了。那么怎么传递呢?实际是借助 fastcgi.conf 或 fastcgi_params 这二者之一作为规则文件,传递待解析的 PHP 文件路径和需要解析的参数。因为在宿主机里直接安装 Nginx 和 PHP 时宿主机的任何路径对它们来说是一样的,但是,在容器里面,容器的这种隔离的特性使得它们的路径是虚拟的、各自独立互不影响的,所以 Nginx 传递的文件路径只能是 PHP 容器里面有的目录(否则就坑爹的 404 了),然后通过在 PHP 容器服务创建时对该目录的映射后,使该目录指向宿主机的实际存放了 PHP 文件的路径。

  1. # 这是我的 nginx.conf 文件中关于 PHP-FPM 的配置
  2.  
  3.  
  4. # pass the PHP scripts to FastCGI server listening on xxx:9000  
  5.     location ~ \.php$ {                         # Nginx 正则匹配 PHP 文件
  6.         fastcgi_pass   phpfpm-dk:9000;      # fastcgi 接口是 phpfpm-dk 的容器监听的 9000 端口
  7. 	    root /app/default;                  # php 文件的目录是 /app/default  ,这个 " /app "目录只是 phpfpm-dk 容器里面的目录,在宿主机、Nginx 容器上都不存在
  8.         fastcgi_index  index.php;
  9.         include fastcgi.conf;               # fastcgi.conf 是接口的规则文件
  10.  
  11.      #  fastcgi_param  SCRIPT_FILENAME /app/default/$fastcgi_script_name;    #如果规则文件是 fastcgi_params ,就按这个方法传递参数了
  12.      #  include        fastcgi_params;    
  13.  
  14.     }

4.3 wp-config.php 的小坑

因为我的博客使用的是 WordPress 所以配置文件 wp-config.php 中也有需要修改迁移进行“容器化”的地方。如下

  1. #配置文件 wp-config.php 的“容器化”迁移
  2. /** MySQL主机 */
  3. #define( 'DB_HOST', 'localhost' );    #这是修正之前的
  4.  
  5. define('DB_HOST', 'mysql-dk');        #这是“容器化”修改之后

4.4 Wordfence WAF 的小坑

Wordfence WAF 是我博客上使用的一个安全工具,安装时会在 网站目录下生成一个” .user.ini “的配置文件,主要作用是在 WordPress 之前自动 Wordfence WAF 。该配置文件内容如下:

  1.  
  2.  
  3. ; Wordfence WAF
  4. ;auto_prepend_file = '/wwwroot/go2do.net/wordfence-waf.php'    #没用容器时的配置项
  5. auto_prepend_file = '/app/go2do.net/wordfence-waf.php'         #使用容器后,需要按这种方式修改,原因见 4.2 条
  6. ; END Wordfence WAF
  7.  
  8.  
  9. # Wordfence WAF  还有个 wordfence-waf.php 也要做类似的修改
  10.  
  11. <?php
  12. // Before removing this file, please verify the PHP ini setting `auto_prepend_file` does not point to this.
  13.  
  14. //if (file_exists('/wwwroot/go2do.net/wp-content/plugins/wordfence/waf/bootstrap.php')) {
  15. //	define("WFWAF_LOG_PATH", '/wwwroot/go2do.net/wp-content/wflogs/');
  16. //	include_once '/wwwroot/go2do.net/wp-content/plugins/wordfence/waf/bootstrap.php';
  17.  
  18.  
  19. if (file_exists('/app/go2do.net/wp-content/plugins/wordfence/waf/bootstrap.php')) {
  20. 	define("WFWAF_LOG_PATH", '/app/go2do.net/wp-content/wflogs/');
  21. 	include_once '/app/go2do.net/wp-content/plugins/wordfence/waf/bootstrap.php';
  22.  
  23. }
  24. ?>

4.5 关于 MySQL 的小坑

关于 MySQL 的简单说一下吧,主要就是 MySQL 的目录权限不足,导致不能生成 mysql.sock 而导致的” Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ “等类似问题;还有就是 MySQL 的” localhost与127.0.0.1 “的区别造成的不能登录的问题。MySQL 的故障好在不与容器的特性联紧密,相对容易排查解决。

欢迎投稿、分享转载,转载请保留如下信息:格物躬行博客[https://www.go2do.net]

本文由 [go2do] 原创,本文链接: https://www.go2do.net/vps/how-migrate-wordpress-base-docker-nginx-phpfpm-mysql.html



You may also like...

4 Responses

  1. 格物躬行说道:


    php-fpm(bitnami)的配置文件:" www.conf "比非容器下的" www.conf "配置文件多2行如下内容:

    include=/opt/bitnami/php/etc/environment.conf
    include=/opt/bitnami/php/etc/common.conf

    所以,映射外部自定义的 www.conf 时注意修改。

    • 格物躬行说道:

      再次提醒:被映射的 配置文件里涉及到的各种路径,都应该是容器内的路径,不是宿主机的路径,那怕这个文件真的只存在于在宿主机中,使用时也是通过对配置文件进行映射,再对配置文件里面涉及的路径进行映射!

  2. 格物躬行说道:

    MySQL 排错技巧:在使用 docker-compose 无法启动 MySQL 时,可以先停止并删除所有的容器(sudo docker ps -a 命令查看所有容器),再使用" sudo docker run --privileged --name mysql-dk -e MYSQL_ROOT_PASSWORD=123456 -d mysql "创建一个临时的 MySQL 容器,通过" logs -f <容器 ID、容器名> " 查看日志信息。注意了,创建时一定要有 " -e "参数及参数值。

    • 格物躬行说道:

      连接容器中 MySQL 时,若宿主机安装了 MySQL 客户端,则可以通过在宿主机命令行 执行" mysql -uroot -p -h 127.0.0.1 "进行连接,注意,必须要添加上-h,因为宿主机连接 MySQL 容器需要通过 tcp,而宿主机连接宿主机本地的 MySQL 如果使用的 socket 连接就不需要了。如果宿主机没有安装 MySQL 客户端,则可通过如下命令连接 MySQL 容器中 MySQL server :

      docker exec -it <容器 ID、容器名> bash -c "mysql -uroot -p"

发表评论

电子邮件地址不会被公开。

本页共执行150次数据库查询,耗时0.334秒,使用内存 1.78 MB