Windows 10 docker
环境配置
开发笔记
推荐链接
启动容器或者镜像出现错误
重启windows前务必先关闭容器
打开Docker Desktop.exe 文件时候一直处于加载中,导致无法进入
windows+R键盘,输入PowerShell,
运行netsh winsock reset 后,
重启电脑之后再次启动Docker
打开docker,启动容器时候报错
遇见下面类似的错误,先检查是否端口占用,如果不是端口占用可以使用下面的命令
windows+R键盘,输入cmd,
//停止 Windows 的网络地址转换(NAT)服务。在某些情况下,NAT服务可能会干扰 Docker 容器的端口映射。通过停止该服务,可以尝试解决端口不可用的问题
net stop winnat
//重新启动 Windows 的网络地址转换(NAT)服务。在尝试完端口映射之后,你可以运行该命令来重新启动 NAT 服务,以确保网络功能正常。
net start winnat
打开docker容器,启动redis时候报错
Error invoking remote method 'docker-start-container': Error: (HTTP code 500) server error - Ports are not available: exposing port TCP 0.0.0.0:6379 -> 0.0.0.0:0: listen tcp 0.0.0.0:6379: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
windows+R键盘,输入cmd,
输入docker restart 镜像名称,
例如: docker restart redis
docker在(WSL2) 中运行
WSL相关命令
//查看你安装的版本
wsl --list
wsl -l -v
//启动ubuntu(命令行)
wsl -d <安装的版本>
//当前用户没有足够的权限,需要在前面加上sudo
sudo docker ps
sudo docker images
//当前用户加入到docker用户组就可以不用加sudo了。关闭当前窗口,重新进入ubuntu命令行才会生效!
sudo usermod -aG docker ${USER}
WSL的docker
Docker是跑在 WSL2 里的,虽说 WSL2 相比 WSL1 更先进,但在跨系统文件读写性能方面是比 WSL1 差的,因此,跑在 WSL2 里的docker想要跨系统访问Windows系统上的代码文件的话,性能是很差的。
所以我不再把代码存储在Windows系统上,改为存储在 WSL2 上。
首先要安装一个WSL系统,我选择的是Ubuntu子系统具体参考我写的Ubuntu相关文档
(Ubuntu)
安装完成后如下图在docker里面开启相关功能,并且重启docker
注意:如果不勾选docker的ubuntu按钮,那么使用docker命令会报错
将项目移动到 \wsl$\Ubuntu-xxxx 里面 选择自己需要的文件夹,不存在就新建 我选择的是 /var/www/html,并且执行sudo chmod -R 777 /var/www/
构建容器产生的问题
//根据上面的项目路径重新构建一个新的容器
//使用 mnt 目录访问 Windows 文件系统。在 WSL 中,Windows 文件系统通常被挂载在 /mnt 目录下。
//cd /mnt/d/wamp64/www/blog/blog 这个是windows下面的目录
//这个是wsl的目录
'注意:如果想要挂载到wsl目录必须要在wsl下面执行docker相关命令,不然会挂载成功,但是因为权限等问题导致看不了项目等文件夹'
docker run -p 8081:80 -v /var/www/html:/var/www/html --name php8.1 php8.1:latest
WSL的Git
//WSL下Phpstorm出现Git代码文件颜色异常
git config --global core.autocrlf true
//注意:WSL 中的 Ubuntu 系统通常会预装 Git。这也取决于你的具体安装和配置。
//查看具体版本
git --version
//查看安装git的具体位置
which git
//注意;PHPstrom下面设置了git的可执行路径,那么项目切换到wsl则git必须要同步切换到wsl子系统ubuntu下面的git
Git可执行文件路径:\\wsl$\Ubuntu\usr\bin\git
Windows 10 docker 暴露在外的IP地址
//??? 填容器名称 或者 容器ID
docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ???
Windows 10 docker 在不删除容器的情况下添加新端口映射的方法与步骤
路径
\wsl$\docker-desktop-data\data\docker\containers里面的很长的字符串就是容器的ID,确定自己需要修改那个容器,进入文件夹修改其中的 config.v2.json 和 hostconfig.json 。
config.v2.json
/*
如果你想让容器的 9501 端口映射到宿主机的 9999 端口,你需要在这两个文件中添加相应的配置。
在 config.v2.json 文件中,你需要在 "ExposedPorts" 和 "Ports" 部分添加如下设置,注意,原本这里面应该是有一个80端口的,直接往后面添加就行了,我这个是为了更容易复制所以删除了其他端口
*/
/*
*具体来说,"ExposedPorts"是Dockerfile或Docker镜像中的一个关键字,用于指定容器内部开放的端口。在这个例子中,"9501/tcp"是容器内的端口号,表示容器内部开放了9501端口。通过这个配置,其他容器可以在网络层级上访问到这个端口,但是在宿主机上无法直接访问。如果需要在宿主机上访问容器内的端口,需要使用端口映射或端口绑定等方式。
需要注意的是,"ExposedPorts"只是声明容器内部开放了哪些端口,并不会实际开放端口或进行端口映射。要实现端口映射或端口绑定,仍需要在容器启动时使用"-p"或"-P"选项进行设置。
*
*/
"ExposedPorts": {
"9501/tcp": {}
},
/**
*这段代码是Docker容器的端口绑定配置,它指定了将容器内部的9501端口绑定到宿主机的9999端口。
具体来说,"PortBindings"是Docker API中的一个关键字,用于设置端口绑定。在这个例子中,"9501/tcp"是容器内的端口号,"HostIp"指定了将容器内的端口绑定到哪个IP地址,在这里是空字符串"",表示使用默认的IP地址,"HostPort"指定了将容器内的端口绑定到哪个宿主机的端口号,在这里是9999。这意味着,当Docker容器运行时,可以通过访问宿主机的9999端口来访问容器内的9501端口提供的服务。
需要注意的是,如果宿主机上的9999端口已经被其他应用程序占用,Docker将无法使用该端口进行绑定。此外,如果容器内没有运行9501端口提供的服务,那么访问宿主机的9999端口将无法获得任何响应。与端口映射不同的是,端口绑定只能将容器内部的端口绑定到宿主机上的一个固定端口,而不能将容器内部的端口随机映射到宿主机上的任意一个可用端口。
*/
"Ports": {
"9501/tcp": [{"HostIp": "0.0.0.0", "HostPort": "9999"}]
}
hostconfig.json
/**
*
这段代码是Docker容器的端口绑定配置,它指定了将容器内部的9501端口绑定到宿主机的9999端口。
具体来说,"PortBindings"是Docker API中的一个关键字,用于设置端口绑定。在这个例子中,"9501/tcp"是容器内的端口号,"HostIp"指定了将容器内的端口绑定到哪个IP地址,在这里是空字符串"",表示使用默认的IP地址,"HostPort"指定了将容器内的端口绑定到哪个宿主机的端口号,在这里是9999。这意味着,当Docker容器运行时,可以通过访问宿主机的9999端口来访问容器内的9501端口提供的服务。
*/
"PortBindings": {
"9501/tcp": [{"HostIp": "", "HostPort": "9999"}]
}
重启docker
打开PowerShell执行下面命令
将HOST_PORT替换为你要测试的宿主机端口号,比如9501。
Test-NetConnection -ComputerName localhost -Port HOST_PORT
Windows 10 docker 在不删除容器的情况下进行挂载的方法与步骤
路径
\wsl$\docker-desktop-data\data\docker\containers
里面的很长的字符串就是容器的ID,确定自己需要修改那个容器,进入文件夹修改其中的 config.v2.json 和 hostconfig.json 。
在这里有一个注意点就是在windwos中路径问题(推荐先用一个镜像创建一个挂载了相同路径的容器,然后在将config.v2.json 和 hostconfig.json的部分内容给复制到需要的容器中,这样就万无一失了)
我需要将d/wamp64/www/blog这个路径下面的文件挂载到var/www/html中
config.v2.json
// 在文件中查找MountPoints这个单词,如果容器没有挂载任何目录的话,则 应该是这样的
"MountPoints":{}
//替换代码
"MountPoints": {
"/var/www/html": {
"Source": "/run/desktop/mnt/host/d/wamp64/www/blog",
"Destination": "/var/www/html",
"RW": true,
"Name": "",
"Driver": "",
"Type": "bind",
"Propagation": "rprivate",
"Spec": {
"Type": "bind",
"Source": "/run/desktop/mnt/host/d/wamp64/www/blog",
"Target": "/var/www/html"
},
"SkipMountpointCreation": false
}
},
"Source":指定宿主机上的源目录路径
"Destination":指定容器内的目标目录路径
"RW":表示挂载点的读写权限。设置为 true 表示挂载点可读可写。设置为 false,表示挂载点是只读的,即容器只能读取宿主机上的目录内容,而不能对其进行写入操作。
"Name":挂载点的名称,可以为空。
"Driver":指定用于挂载的驱动程序
"Type":指定挂载的类型,在这里是 "bind",表示使用绑定挂载。绑定挂载是将宿主机上的目录直接映射到容器的一种方式。
"Propagation":指定挂载点的传播方式,这里是 "rprivate"(只读私有传播):这意味着容器对挂载点的更改只会在容器内部可见,不会传播到宿主机或其他容器。"rshared"(只读共享传播):表示容器内的更改会传播到其他容器和宿主机上的挂载点。"rslave"(只读从属传播):容器对挂载点的更改会传播到其他容器和宿主机,但其他容器和宿主机对挂载点的更改不会传播到当前容器。
"Spec":描述挂载点的详细规范。其中包含 "Type"、"Source" 和 "Target" 字段,与前面的参数含义相同。
"SkipMountpointCreation":指定是否跳过挂载点的创建,默认为 false。当设置为 true 时,Docker 将不会自动创建挂载点。这意味着容器启动后,如果挂载点所指定的路径在容器内部不存在,Docker 将不会自动创建该目录。
hostconfig.json
// 在文件中查找Binds这个单词,如果容器没有挂载任何目录的话,则 应该是这样的
"Binds":null
//替换代码
"Binds": [
"/run/desktop/mnt/host/d/wamp64/www/blog:/var/www/html"
],
"Binds":[<宿主机路径>:<映射到docker容器的路径>]
重启docker,启动容器
Windows 10 docker 访问windows宿主机数据库
这里是链接数据库方式(这个要多试试,切换不同的方法)
默认情况下,MySQL 不允许 ‘root’ 用户从远程主机进行连接
默认情况下,并不认识或允许 host.docker.internal 主机连接
$dsn = "mysql:host=<宿主机IP地址>;dbname=<数据库名>;charset=utf8";
//$dsn = "mysql:host=192.168.1.109;dbname=test;charset=utf8";
//$dsn = "mysql:host=host.docker.internal;dbname=test;charset=utf8";
$username = '<用户名>';
$password = '<密码>';
$conn = new PDO($dsn, $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT * FROM tb_user";
$stmt = $conn->query($sql);
// 获取查询结果
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 处理查询结果
foreach ($result as $row) {
echo "ID: " . $row['id'] . ", Name: " . $row['name'] . "<br>";
}
可能会产生的问题
docker能访问到宿主机
//Ping 宿主机
在 Docker 容器中执行 ping 命令,尝试使用宿主机的 IP 地址来 ping 宿主机。如果能够成功收到响应,说明容器可以与宿主机进行网络通信。示例命令:ping <宿主机IP地址>
//安装ping
sudo apt-get update
sudo apt-get install iputils-ping
//宿主机中执行网络相关命令
ifconfig(Linux)或 ipconfig(Windows)来查看容器内部的网络配置信息,确认容器所在的网络环境和网关设置。
//如果成功ping通了,但是访问数据库还是失败则可能是权限问题
//将 `'your_username'` 替换为你的数据库用户名,`'your_database'` 替换为你要连接的数据库名,`'your_password'` 替换为数据库用户的密码。
//查看用户权限
SHOW GRANTS FOR 'your_username'@'宿主机IP地址';
//新增一个用户(这里用软件进行图形化操作更加方便)
GRANT ALL PRIVILEGES ON *.* TO 'your_username'@'宿主机IP地址' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;
//使用以下命令为用户 'lh' 授予访问数据库 'test' 的权限
GRANT ALL PRIVILEGES ON `test`.* TO 'lh'@'host.docker.internal' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;
查看数据库下面有多少个用户
MySQL
SELECT user FROM mysql.user;
PostgreSQL
SELECT usename FROM pg_user;
Microsoft SQL Server
SELECT name FROM sys.sql_logins;
Oracle
SELECT username FROM dba_users;
Windows 10 docker 中PHP的相关问题
Swoole
本机swoole版本5.0.3。
//清除终端内容
clear
//查看swoole当前版本
php -r 'echo phpversion("swoole"); echo PHP_EOL;'
//获取本机 CPU 核数。
php -r "echo swoole_cpu_num(); echo PHP_EOL;"
PHP在docker 中的相关路径
#php.ini
cd /usr/local/etc/php
//php.ini-development:这个文件提供了开发环境下的示例配置选项。它通常包含更多的调试和错误报告设置,以方便开发和调试PHP应用程序。在开发环境中,您可以使用这个示例配置文件作为基础,并根据需求进行自定义配置。
//php.ini-production:这个文件提供了生产环境下的示例配置选项。它通常包含更多的安全和性能优化设置,以确保PHP应用程序在生产环境中运行时更加安全和高效。在部署到生产环境之前,您可以使用这个示例配置文件作为基础,并根据需求进行自定义配置。
#扩展(后面的no-debug-non-zts-20210902有可能不同,但是前面一般都一样)
cd /usr/local/lib/php/extensions/no-debug-non-zts-20210902
#apahce服务器的路径(windows和linux中的apache文件不同属于正常)
#apache2.conf
cd /etc/apache2/
docker容器里面Composer相关命令
//这将下载 Composer 安装脚本并将其安装到 /usr/local/bin 目录下,以便在容器内全局使用 composer 命令。
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php --install-dir=/usr/local/bin --filename=composer
php -r "unlink('composer-setup.php');"
//安装过程中有可能报错
//缺少PHP的一些扩展,请手动安装 如缺少 zip,unzip扩展
apt-get update
apt-get install php-zip
apt-get install unzip
//如果安装时候显示 类似 E: Package 'php-zip' has no installation candidate 这样的错误,则可以使用下面的命令进行操作
docker-php-ext-install zip
//安装大部分完成了,但是由于网络或者目录权限等原因导致一部分依赖没有成功安装,则可以考虑手动安装(将 vendor/package 替换为相应的依赖项名称)
composer require vendor/package
//清除 Composer 的缓存文件,包括已下载的依赖项和元数据等信息。
composer clear-cache
//进入项目目录
composer install
//不使用缓存重新安装依赖项
composer install --no-cache
执行PHP文件时候显示无法使用当前页面
查询 Apache 是否安装到容器,并且是否正在运行
检查暴露端口情况,默认情况下,Apache服务器的监听端口是80
apache2 -v
//查看是否正在运行
service apache2 status
//重新启动Apache服务器
service apache2 restart
//启动apache服务命令
service apache2 start
//关闭apache服务命令
service apache2 stop
//检查 Apache 的监听端口
netstat -tuln | grep 80
检查端口映射
(不要过于相信图形化界面,必须要用对应命令来测试监听端口)
Windows系统进入宿主机的 PowerShell(管理员界面)执行对应命令
netstat -ano | findstr "端口名称"(docker映射到宿主机的端口)
如果执行后没有数据出来,那证明端口没有被监听,服务没有运行
端口映射问题
如果没有其他好办法,可以使用phpstrom里面的docker里面有重新构建的功能,用这个进行重新构建,大概率不会照成数据丢失
检查php.ini 文件
/usr/local/etc/php
目录下的 conf.d 子目录和 php.ini-development 以及 php.ini-production 是正确的文件。
conf.d 目录通常包含一些 PHP 扩展的配置文件,可以在其中启用或禁用扩展。这些文件以 .ini 扩展名结尾,例如 xdebug.ini。
php.ini-development 是一个示例性的 PHP 配置文件,其中包含了许多常见的配置选项的注释和默认值。你可以根据需要将其复制并重命名为 php.ini 来作为基础配置,并根据你的应用程序需求进行自定义。
php.ini-production 也是一个示例性的 PHP 配置文件,类似于 php.ini-development,但其中的一些配置选项可能已经被调整为适合生产环境的值。
cd /usr/local/etc/php
最后解决办法
手动删除容器,然后如果是使用docker-compose.yml构建的则执行下面命令进行重新构建
docker-compose up -d
扩展相关问题
#显示警告信息
PHP Warning: Module "curl" is already loaded in Unknown on line 0
#先确保curl已经在PHP里面了
php -m | grep curl
#查看是否有curl.so 文件,如果没有暂时不管它,如果有需要可以通过docker-php-ext-install curl 进行添加
cd /usr/local/lib/php/extensions/no-debug-non-zts-20210902
#注释自己本地的php.ini文件的 ;extension=curl 就可以消除这个警告。
#这个是个docker的特性,目前无法解决。
Windows 10 docker 中Mysql的相关问题
laravel链接不上mysql
SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for mysql failed: Temporary failure in name resolution
// docker 暴露在外的IP地址
//??? 填容器名称 或者 容器ID
docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ???
// 修改laravel 的env 里面的值
#DB_HOST=127.0.0.1 这里用的是本地的mysql,改成下面的是因为用了docker
#DB_HOST=mysql,原本访问的挺好的,就是更新到新版本就直接报错了
DB_CONNECTION=mysql
DB_HOST=(输入容器暴露出来的IP)
DB_PORT=3306
DB_DATABASE=test
DB_USERNAME=root
DB_PASSWORD=root
Windows 10 docker 中Redis的相关问题
laravel链接不上redis
// docker 暴露在外的IP地址
//??? 填容器名称 或者 容器ID
docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" ???
// 修改laravel 的env 里面的值
#这里必须这样加,因为我不是通过PHP原生redis安装方式,而是通过laravel文档的安装方式所以必须要符合config/database.php 下面的redis
REDIS_CLIENT=predis
#REDIS_HOST=127.0.0.1 这里用的是本地的reids,改成下面的是因为用了docker
#原本使用REDIS_HOST=redis挺好,应该是更新版本导致的
REDIS_HOST=(输入容器暴露出来的IP)
REDIS_PASSWORD=null
REDIS_PORT=6379
更多推荐
所有评论(0)