基于Ubuntu镜像构建运行MySQL的Dockerfile问题求助
基于Ubuntu镜像构建MySQL服务器的Dockerfile解决方案
重构后的Dockerfile
FROM ubuntu:latest EXPOSE 3306 VOLUME ["/var/lib/mysql"] ENV MYSQL_ROOT_PASSWORD=secret ENV MYSQL_DATABASE=wordpress RUN apt update && \ apt install -y mysql-server gosu && \ rm -rf /var/lib/apt/lists/* RUN mkdir -p /docker-entrypoint-initdb.d COPY ./wordpress.sql /docker-entrypoint-initdb.d/ COPY ./docker-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/docker-entrypoint.sh ENTRYPOINT ["docker-entrypoint.sh"] CMD ["mysqld"]
关键改动说明
- 移除冗余的
entrypoint.sh复制:只需要一个入口脚本即可完成初始化和启动流程 - 删除对SQL脚本添加执行权限的操作:SQL是数据文件,不需要执行权限,原操作完全多余
- 增加APT缓存清理:安装完成后删除
/var/lib/apt/lists/*,大幅减小镜像体积 - 显式创建初始化脚本目录:避免因目录不存在导致SQL脚本复制失败
- 新增
MYSQL_DATABASE环境变量:方便初始化时自动创建目标数据库,无需手动修改脚本
配套的docker-entrypoint.sh脚本
这个脚本负责处理首次启动的数据库初始化、权限配置,以及以非root用户启动MySQL服务:
#!/bin/bash set -eo pipefail # 首次启动时初始化数据库 if [ ! -d "/var/lib/mysql/mysql" ]; then # 初始化MySQL数据目录(无密码临时启动) mysqld --initialize-insecure --user=mysql # 启动临时MySQL服务 mysqld --user=mysql & PID="$!" # 等待MySQL服务完全启动 until mysqladmin ping -h localhost --silent; do sleep 1 done # 设置root密码并创建指定数据库 mysql -u root <<EOF ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT_PASSWORD'; CREATE DATABASE IF NOT EXISTS $MYSQL_DATABASE; EOF # 执行所有初始化SQL脚本 for f in /docker-entrypoint-initdb.d/*.sql; do mysql -u root -p"$MYSQL_ROOT_PASSWORD" $MYSQL_DATABASE < "$f" done # 停止临时服务,准备启动正式服务 mysqladmin -u root -p"$MYSQL_ROOT_PASSWORD" shutdown fi # 切换到mysql用户启动正式服务,确保信号能正确传递 exec gosu mysql "$@"
构建与运行命令
# 构建镜像 docker build -t sql_img . # 运行容器(映射端口方便外部连接) docker run --name sql_cont -v sql_vol:/var/lib/mysql -p 3306:3306 sql_img
核心注意事项
- 使用
gosu而非su或sudo切换用户:避免权限继承问题,确保MySQL以安全的mysql用户运行 - 初始化时启动临时服务:确保SQL脚本执行时MySQL已经就绪,避免连接失败
- 用
exec启动最终的mysqld:让mysqld成为容器的PID 1进程,保证容器能响应停止信号(如docker stop)
内容的提问来源于stack exchange,提问作者lazlomeli
相关产品推荐
相关产品推荐

