手动制作Docker镜像

手动制作 Docker 镜像

前言

a. 本文主要为 Docker的视频教程 笔记。
b. 环境为 CentOS 7.0 云服务器(用来用去感觉 Windows 的 Docker 出各种问题,比如使用 --privileged/usr/sbin/init 会直接出错暂停,因此还是使用 Linxu 操作系统的云服务器了,不过之前的内容在 Linux 下也都适用)
c. 上一篇:Docker命令注意点
d. 过了N久以后突然想到,在 Docker 容器里面直接安装数据库的情况似乎并不多见,而是更倾向于直接使用数据库的容器。因为整个服务平台需要的是一套数据库而不是每个容器搞一套。本文仅作为使用容器技术的演示,作为生产环境的部署方案是极不合适的。本例中安装 mysql 就当是自己的一些尝试吧(还有踩坑,擦)

1. 下载运行操作系统的容器

docker pull centos:7 # 可以查看 Docker Hub 官方以取得名称
docker run -it --name centos7 centos:7

2. 换源并安装对应软件

此处换为阿里云的源(同时更换 yum 和 epel)

curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

此处安装 mysql 和 httpd

使用命令 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 修改时区为东八区

3. 将容器保存为镜像

docker commit <CONTAINER_ID> <CUSTOM_CONTAINER_NAME>

最后运行该镜像(启动对应服务的命令,并阻塞),如:

docker run -d -p 81:80 <名称> nginx -g 'daemon off;'

apache 为 httpd -D FOREGROUND

如果一次需要执行多个命令,可以写成一个脚本并执行脚本,如:

#!/bin/bash

mysqld --user root &	# 此命令不阻塞
httpd -D FOREGROUND

额外内容 - 原先的启动 CentOS7 的 Docker 镜像方式(坑)

我原先的启动命令为:

docker run -it --privileged --name centos7 centos:7 /usr/sbin/init

因为启动时如果不加 --privileged/usr/sbin/init,则无法使用 systemctl 命令来启动和停止服务。而使用此方式后,会调用 /usr/sbin/init 来加载镜像,当前窗口会直接无法操作,如下:

而保存该容器为镜像后,如果启动时不加这两个参数,则会报错:

然而比较奇怪的是,以此种方式启动的容器,安装 mysql 时不需要执行其它操作,yum install mysql 安装后就可以正常使用;且修改密码时有密码强度的验证。猜测是 mysql 安装时需要调用系统的命令执行一些服务,而不加 --privileged 和 /usr/sbin/init 无法正常使用系统服务。

因此正确的方式应为:安装软件后,使用软件本身的程序启动而不是使用 systemctl 启动(如文章开头所述)

参考:

apache 前台启动命令:
https://blog.csdn.net/weixin_44419597/article/details/104425504

CentOS换源
https://www.cnblogs.com/Chan94/p/10658756.html

后记

原本本篇的内容里还有如何在容器中安装 mysql 的内容,但感觉内容太长,耦合性太高(doge),而且这篇主要的内容是怎么把容器提交为镜像,还是拆到了另一篇博客中。这也算是有点启发吧:调用栈再长,还是要回到主函数上!

原文地址:https://www.cnblogs.com/battor/p/build_docker_image_by_manual.html