ubuntu2404 docker安装mysql8
先拉镜像
docker pull mysql:8.0
创建 MySQL 数据目录(防止容器删除数据丢失)
mkdir -p ~/docker/mysql8/data
mkdir -p ~/docker/mysql8/conf
mkdir -p ~/docker/mysql8/logs
创建 MySQL 配置文件(关键!!)
cd ~/docker/mysql8/conf
vim my.cnf
写入:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
# 允许远程访问
bind-address=0.0.0.0
# 解决 Navicat 连接失败
default-authentication-plugin=mysql_native_password
运行 MySQL8 容器
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v ~/docker/mysql8/data:/var/lib/mysql \
-v ~/docker/mysql8/conf:/etc/mysql/conf.d \
-v ~/docker/mysql8/logs:/logs \
--restart always \
mysql:8.0
说明:
参数含义
-p 3306:3306 映射端口(Windows 才能访问)
MYSQL_ROOT_PASSWORD root密码
-v 数据持久化
–restart always 开机自动启动
查看是否成功:
docker ps
看到:
mysql8 mysql:8.0 Up (healthy)
进入 MySQL 测试
docker exec -it mysql8 mysql -uroot -p
输入密码即可进入mysql
允许远程访问(Windows Navicat 能连的关键)
在 mysql 里执行:
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
然后退出:
exit;
异常问题处理
错误1:
执行下面的语句时 docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=123456 \ -v ~/docker/mysql8/data:/var/lib/mysql \ -v ~/docker/mysql8/conf:/etc/mysql/conf.d \ -v ~/docker/mysql8/logs:/logs \ --restart always \ mysql:8.0 出现了如下错误提示
docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint mysql8 (db046c0d78855840cc051ffd10ae9acf3dcd87970b308fcc1a647f1c022dcf15): failed to bind host port 0.0.0.0:3306/tcp: address already in use
解决办法
这个错误其实非常典型,而且不是 Docker 问题,是你的 Ubuntu 已经有人在占用 3306 端口了 👇
failed to bind host port 0.0.0.0:3306: address already in use
含义:
Docker 想把「宿主机的 3306」映射给容器,但宿主机本身已经有程序在监听 3306,所以 Docker 绑定失败。
也就是说:
你的 Ubuntu 里已经装过 MySQL / MariaDB(系统自带的最常见)
Ubuntu 24.04 安装某些软件(如 php、mariadb-client、lamp、甚至某些桌面组件)时,会自动带一个数据库服务。
第一步:确认谁占用了 3306
执行:
sudo ss -lntp | grep 3306
你大概率会看到类似:
LISTEN 0 70 127.0.0.1:3306 0.0.0.0:* users:(("mysqld",pid=1234,fd=22))
或者:
("mariadbd",pid=xxxx)
这就说明 ——
系统自带 MySQL/MariaDB 正在运行
(这也是为什么 Docker MySQL 起不来)
第二步(推荐做法):彻底关闭并卸载系统 MySQL ⭐⭐⭐
我们既然用 Docker,就不要系统 MySQL,否则你以后一定混乱(端口、数据目录、权限、socket 全冲突)。
1)先停止服务
sudo systemctl stop mysql
sudo systemctl stop mariadb
再确认:
sudo ss -lntp | grep 3306
如果没输出,说明端口已释放。
2)禁用开机启动
sudo systemctl disable mysql
sudo systemctl disable mariadb
3)彻底卸载(强烈建议)
sudo apt purge -y mysql-server mysql-client mysql-common mariadb-server mariadb-client mariadb-common
清理残留数据库(很关键):
sudo rm -rf /var/lib/mysql
sudo rm -rf /etc/mysql
自动清理依赖:
sudo apt autoremove -y
sudo apt autoclean
再次确认端口:
sudo ss -lntp | grep 3306
现在必须没有任何输出。
第三步:重新启动 Docker MySQL
现在重新执行你刚才那条命令:
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v ~/docker/mysql8/data:/var/lib/mysql \
-v ~/docker/mysql8/conf:/etc/mysql/conf.d \
-v ~/docker/mysql8/logs:/logs \
--restart always \
mysql:8.0
然后:
docker ps
如果看到:
mysql8 mysql:8.0 Up xx seconds
说明容器已经成功启动 🎉
如果你不想卸载(不推荐)
可以改端口,例如:
-p 3307:3306
那 Windows Navicat 就要连:
IP: 192.168.x.x
Port: 3307
但我非常不建议,因为以后你一定会忘记哪个是系统 MySQL,哪个是 Docker MySQL,开发会很痛苦。
下一步(很重要)
容器启动后,立刻测试:
docker logs mysql8
如果看到:
ready for connections
port: 3306
再进行 Navicat 连接,否则先别连(很多人这一步没做导致误判)。
把 ss -lntp | grep 3306 的输出贴给我,我可以直接帮你判断你机器现在的状态。
错误2
qwer@qwer-virtual-machine:~/docker/mysql8/conf$ docker run -d
–name mysql8
-p 3306:3306
-e MYSQL_ROOT_PASSWORD=123456
-v ~/docker/mysql8/data:/var/lib/mysql
-v ~/docker/mysql8/conf:/etc/mysql/conf.d
-v ~/docker/mysql8/logs:/logs
–restart always
mysql:8.0
docker: Error response from daemon: Conflict. The container name “/mysql8” is already in use by container “2a17c33aec952a078df8f2a165b81576a5c9312875520586ccee6e63ab1a512d”. You have to remove (or rename) that container to be able to reuse that name.
Run ‘docker run --help’ for more information
很好 👍
这个状态已经把问题完全暴露出来了:
STATUS: Created
注意这不是 Exited,也不是 Up。
这在 Docker 里是一个非常关键的状态:
Created= 容器对象已经创建成功,但容器一次都没有真正启动成功过(mysqld 甚至还没来得及运行)
也就是说:
你第一次因为 3306 端口冲突 失败时,Docker 只创建了容器外壳,MySQL 初始化没有完成,所以现在它卡死了。
这也是 Docker MySQL 新手最常见卡点。
必须做的三步(顺序不能错)
① 强制删除这个“半死不活”的容器
直接删:
docker rm -f mysql8
再确认:
docker ps -a
现在应该没有 mysql8。
② 清空 MySQL 数据目录(这是关键!!!)
因为你挂载了:
-v ~/docker/mysql8/data:/var/lib/mysql
MySQL 初始化失败时,已经往里面写了残缺数据库。
如果不清空,MySQL会永远启动失败(而且日志会非常迷惑)。
执行:
rm -rf ~/docker/mysql8/data/*
(不是删目录,是删里面的内容)
你可以确认一下:
ls ~/docker/mysql8/data
应该是空的。
③ 再次运行容器(但这次要盯日志)
重新执行:
docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-v ~/docker/mysql8/data:/var/lib/mysql \
-v ~/docker/mysql8/conf:/etc/mysql/conf.d \
-v ~/docker/mysql8/logs:/logs \
--restart always \
mysql:8.0
马上执行:
docker logs -f mysql8
这一步非常关键,第一次初始化需要 20~60 秒,很多人以为失败其实是在初始化 InnoDB。
正确的日志应该长这样
你会看到一大堆:
Initializing database
InnoDB initialization has started
InnoDB initialization has ended
最后必须出现这一句:
mysqld: ready for connections.
port: 3306
只要这句出现,数据库就真的活了 ✔
然后验证
docker ps
应该看到:
Up xx seconds (healthy)
接着:
docker exec -it mysql8 mysql -uroot -p
密码:
123456
能进入 mysql> 提示符,就成功了。
问题3:
Error response from daemon: Get “https://registry-1.docker.io/v2/”: context deadline exceeded
出现类似上面的网络问题,可能是两个原因
(1)docker镜像有问题
cd /etc/docker
修改daemon.json配置如下:
{
"registry-mirrors" : [
"https://docker.1ms.run"
]
}
docker镜像可能经常失效,需要去查找可用的镜像,然后重启docker服务
sudo systemctl daemon-reload
sudo systemctl restart docker
(2)dns解析问题
cat /etc/resolv.conf
如果 DNS 是 127.0.0.53 可能解析有问题。
可以改成下面的dns
nameserver 8.8.8.8
nameserver 114.114.114.114
保存后, sudo reboot
更多推荐
所有评论(0)