Docker 学习总结
一、容器生命周期与前台运行
-
Docker 容器的生命周期与其主进程绑定:
- 主进程运行 → 容器运行
- 主进程退出 → 容器停止
-
为什么服务要前台运行?
- 后台启动(如
systemctl start nginx)会导致主进程立即结束,容器随即退出。 - 前台运行(如
nginx -g "daemon off;"或httpd -D FOREGROUND)使服务成为主进程,保持容器活跃。
- 后台启动(如
-
优点:
- 日志直接输出到标准输出,便于
docker logs查看 - 符合“一个容器只运行一个应用”的设计原则
- 日志直接输出到标准输出,便于
二、自定义镜像构建(Commit 方式)
- 启动并配置容器(如安装 Apache)
- 使用
docker commit将容器保存为新镜像:docker commit httpd2 httpd_image - 基于新镜像启动容器,并映射端口:
docker run -d -p 8001:80 --name=httpd3 httpd_image /usr/sbin/httpd -D FOREGROUND
✅ 生产中可将此镜像
push到私有/公有镜像仓库。
三、数据卷挂载(实现数据持久化)
目的
- 保留容器内配置、数据、日志
- 支持多容器共享数据
- 避免容器删除导致数据丢失
操作步骤
- 在宿主机创建目录并准备数据:
mkdir /docker_www echo "daniel" > /docker_www/index.html - 启动容器时挂载数据卷:
docker run -d -p 8002:80 -v /docker_www/:/www --name=httpd4 httpd_image /usr/sbin/httpd -D FOREGROUND - 修改宿主机文件,网页内容实时更新。
其他常见挂载示例
docker run -d --name httpd1 -p 8000:80 \-v /httpd_www:/www \-v /test/httpd.conf:/etc/httpd/conf/httpd.conf \httpd_image /usr/sbin/httpd -DFOREGROUND
⚠️ 注意:配置文件需提前准备,且家目录路径需匹配(如设为
/www)
四、时区问题解决
- 官方 CentOS 镜像默认使用 UTC 时区(比中国晚 8 小时)
- 解决方法:挂载宿主机时区文件
docker run -it -v /etc/localtime:/etc/localtime centos /bin/bash - 进阶:在自定义镜像中固化时区设置,避免每次挂载
五、Dockerfile 构建镜像
示例:构建 Tomcat 镜像
FROM cf-workers-docker-io-38g.pages.dev/dokken/centos-stream-9
LABEL maintainer="daniel <daniel@itcast.cn>"
ENV JAVA_HOME=/usr/local/jdk1.8.0_191# 方法1:COPY + RUN 解压
COPY jdk-8u191-linux-x64.tar.gz .
COPY apache-tomcat-9.0.14.tar.gz .
RUN tar xf jdk-8u191-linux-x64.tar.gz -C /usr/local && \tar xf apache-tomcat-9.0.14.tar.gz -C /usr/local && \mv /usr/local/apache-tomcat-9.0.14 /usr/local/tomcatEXPOSE 8080
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]
改进版(使用 ADD 自动解压)
ADD jdk1.8.0_191 /usr/local/jdk1.8.0_191
ADD tomcat /usr/local/tomcat
六、Dockerfile 构建 MariaDB 镜像
初始化脚本 mariadb.sh
#!/bin/bash
mysql_install_db --datadir=/var/lib/mysql/ --user=mysql
sleep 3
mysqld_safe --defaults-file=/etc/my.cnf &
sleep 3
mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123';"
mysql -e "grant all privileges on *.* to 'abc'@'%' identified by '123';"
mysql -e "flush privileges;"
Dockerfile
FROM cf-workers-docker-io-38g.pages.dev/dokken/centos-stream-9
LABEL maintainer="daniel <daniel@itcast.cn>"
RUN yum install -y mariadb-server mariadb
COPY mariadb.sh .
RUN sh mariadb.sh
EXPOSE 3306
CMD ["mysqld_safe", "--defaults-file=/etc/my.cnf"]
💡 说明:因
RUN不支持后台进程(&),故用脚本初始化。
七、Dockerfile 最佳实践
- 合并 RUN 指令:减少镜像层数
- 利用缓存:变化少的指令放前面
- 最小化安装:只装必要依赖
- 避免
latest标签:使用明确版本 - 多阶段构建:分离构建与运行环境
- 非 root 用户运行:提升安全性
- 合理排序:先装依赖,再 COPY 代码
- 使用
.dockerignore:排除无关文件 - 定期更新基础镜像:修复安全漏洞
八、镜像管理
拉取镜像
docker pull centos-stream-9
# 或使用国内加速源
docker pull cf-workers-docker-io-38g.pages.dev/library/centos-stream-9
配置镜像加速器(/etc/docker/daemon.json)
{"registry-mirrors": ["https://mirror.aliyuncs.com","https://docker.mirrors.ustc.edu.cn","https://hub.rat.dev","https://docker.nju.edu.cn","https://atomhub.openatom.cn"]
}
导出与导入镜像
# 导出
docker save centos -o /root/dockerimage_centos.latest# 导入
docker load < /root/dockerimage_centos.latest
删除镜像
docker rmi centos:latest
九、Docker Web 管理平台(图形化)
推荐工具
- Portainer(最流行)
- DockerUI
- Shipyard
DockerUI 示例
# 拉取镜像
docker pull uifd/ui-for-docker# 启动(需挂载 docker.sock)
docker run -d --name dockerui -p 9000:9000 \-v /var/run/docker.sock:/var/run/docker.sock \uifd/ui-for-docker
🌐 访问
http://宿主机IP:9000即可管理 Docker
十、附录:常见官方镜像(CentOS 系列)
| 镜像名称 | 描述 |
|---|---|
centos/httpd-24-centos7 |
Apache 2.4 |
centos/nginx-116-centos7 |
Nginx 1.16 |
centos/mariadb-103-centos8 |
MariaDB 10.3 |
centos/mysql-57-centos7 |
MySQL 5.7 |
centos/redis-5-centos7 |
Redis 5 |
centos/php-56-centos7 |
PHP 5.6 |
centos/python-35-centos7 |
Python 3.5 |
📝 提示:实际使用中建议优先使用官方镜像(如
httpd,nginx,mysql),或基于稳定基础镜像自定义构建。