从0-1的docker镜像服务构建

文章目录

摘要

由于项目服务器要从centos 6升级到centos 7,但是在升级过程中,发现web项目的php在加载自行编写的C扩展时,运行在centos 7总是崩溃,但是直接改C扩展预计要花比较长的时间,可能会延误服务器升级,遂计划基于centos 6,将php构造成docker 镜像来运行。正所谓当翻越山峰耗时,那么绕过去不失为一个办法,最终目的都是抵达终点。

于是有了本篇文章,从docker安装、镜像构建,到docker-compose管理容器,最后基于systemctl管理docker-compose异常重启。

一、环境准备

1、docker安装

1)yum安装

bash 复制代码
 yum install -y yum-utils vim  // 安装基础工具
 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo //添加软件源信息
 yum -y install docker-ce
 systemctl enable docker --now  //启动docker并设置为开机自启
 

2)二进制安装(推荐,更加灵活)

  1. 下载安装
bash 复制代码
wget https://download.docker.com/linux/static/stable/x86_64/docker-20.10.21.tgz
tar -zxvf docker-20.10.21.tgz
mkdir -p /usr/local/docker-20.10.21
mv docker/* /usr/local/docker-20.10.21
  1. 创建软连接
bash 复制代码
ln -sv /usr/local/docker-20.10.21/* /usr/bin/
  1. 创建docker组,docker启动需要
bash 复制代码
groupadd -r docker
  1. systemctl配置
bash 复制代码
[root@ali ~]# cat /usr/lib/systemd/system/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd --config-file=/etc/docker/daemon.json
ExecReload=/bin/kill -s HUP $MAINPID
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
# Uncomment TasksMax if your systemd version supports it.
# Only systemd 226 and above support this version.
#TasksMax=infinity
TimeoutStartSec=0
# set delegate yes so that systemd does not reset the cgroups of docker containers
Delegate=yes
# kill only the docker process, not all processes in the cgroup
KillMode=process
# restart the docker process if it exits prematurely
Restart=on-failure
RestartSec=3s
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
  1. docker配置
bash 复制代码
[root@ali ~]# cat /etc/docker/daemon.json
{
  "data-root": "/home/docker/data-root",
  "pidfile": "/home/docker/run/docker.pid",
  "log-level": "info",
  "registry-mirrors": ["http://hub-mirror.c.163.com","https://registry.docker-cn.com"]   #docker镜像源
}
  1. 开机自启动
bash 复制代码
systemctl enable docker --now
  1. 启动
bash 复制代码
systemctl restart docker

docker配置相关
docker命令

2、docker-compose安装

docker-compose 是用于定义和运行多容器 Docker 应用程序的工具,通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。这样就可以替代复杂的shell脚本来管理多个容器。

二进制文件获取

linux下载

bash 复制代码
curl -L https://github.com/docker/compose/releases/download/2.14.2/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose

二、镜像制作

2.1、编写Dockerfile文件

指令说明

2.1.1、熟悉常用Dockerfile命令
  • FROM #基础镜像,我们要制作的镜像常常是依赖某个基础镜像来实现的,这些基础镜像常见的如centos,ubatu,alpine,harbox,debian等,其中alpine很小,安全。

    这些镜像到docker官方仓库搜索即可,选择相应的版本,如:FROM centos:6.6 。

  • COPY #从上下文目录中复制文件或者目录到容器里指定路径。如:COPY ./package/usr/lib64/phpmath.so /usr/lib64/phpmath.so。

  • RUN #用于在基础镜像中执行后面跟着的命令行命令。如:RUN mkdir -p /usr/local/php/ 。

  • CMD #类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:1)CMD 在docker run 时运行;2)RUN 是在 docker build。如果有多条仅最后一条生效。该指令所启动的程序即容器的主进程,其退出容器也会退出,所以该指令的命令应当是常驻进程。

2.1.2、制作php镜像案例
yaml 复制代码
FROM centos:6.6

COPY ./package/usr/lib64/phpmath.so /usr/lib64/phpmath.so
COPY ./package/usr/lib64/libserialize.so /usr/lib64/libserialize.so
COPY ./package/usr/lib64/protocolbuffers.so /usr/lib64/protocolbuffers.so
COPY ./package/usr/lib64/redis.so /usr/lib64/redis.so
COPY ./package/usr/lib64/mysqli.so /usr/lib64/mysqli.so

COPY ./package/php5 /usr/local/
COPY ./dockerphp5/usr/local/php/etc/php-fpm.conf /usr/local/php/etc/php-fpm.conf

RUN mkdir -p /home/php/fpm/  #fpm 日志目录

RUN mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
COPY ./dockerphp5/etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo
RUN yum clean all && yum makecache
RUN yum -y install vixie-cron
RUN yum -y install crontabs

#一些定时脚本
COPY ./dockerphp5/etc/crontab /etc/crontab
RUN mkdir -p /etc/cron.minutely/
COPY ./dockerphp5/etc/cron.minutely/* /etc/cron.minutely/
RUN mkdir -p /etc/cron.hourly/
COPY ./dockerphp5/etc/cron.hourly/* /etc/cron.hourly/
RUN mkdir -p /etc/cron.daily/
COPY ./dockerphp5/etc/cron.daily/* /etc/cron.daily/

EXPOSE 9000

CMD ["/usr/bin/phpfpmd.sh"]   #/usr/bin/phpfpmd.sh有多条命令,仅最后一条是常驻的
bash 复制代码
[root@ali ~]# cat /usr/bin/phpfpmd.sh
#!bin/bash
/etc/init.d/crond restart
/usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm.conf -g /usr/local/php/var/run/php-fpm.pid

2.2、build镜像

bash 复制代码
docker build -t php:5.4.7 -f ./dockerphp5/Dockerfile .  #其中-t指定镜像名称和tag(版本)

如果顺利执行完,就可以看到镜像了

bash 复制代码
[root@ali ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
php      5.4.7     360997ecc130   3 weeks ago   852MB
centos       6.6       368c96d786ae   3 years ago   203MB

三、docker-compose管理容器

3.1、编写docker-compose.ymal配置文件

指令说明

bash 复制代码
version: '3'
services:
  php5:                        
    image: "php:5.4.7"                                 #指定镜像
    ports:
      - "127.0.0.1:9000:9000"
    volumes:                                           #指定目录挂载
      - "/usr/local/web:/usr/local/web"                #项目代码目录
      - "/home/web:/home/web"                          #项目日志等目录 
      - "/etc/docker/cron.minutely:/etc/cron.minutely"
      - "/etc/docker/cron.hourly:/etc/cron.hourly"
      - "/etc/docker/cron.daily:/etc/cron.daily"
      - "/etc/localtime:/etc/localtime"                #时间与宿主机一致
    extra_hosts:                                       #向容器/etc/hosts添加域名
      - "redis.link.cn:200.200.172.106"
      - "mysql.link.cn:200.200.172.108"
    container_name: "phpfpmd"                         #容器名称
    

此时可以通过/usr/bin/docker-compose -f /etc/docker/docker-compose.yml up 来启动容器了,相比较docker run -itd -p 9000:9000 -v xxx:xxx --add-host xxx:xxx --name phpfpmd php:5.4.7 简洁多了,特别是容器多的时候,但是无法解决开机自启动,没有看门狗的问题,这个可以利用systemctl来解决

3.2、编写systemctl配置

指令说明

yaml 复制代码
[Unit]
Description=php-fpm
#Documentation=nothing
After=network-online.target docker.service
Wants=network-online.target
Requires=docker.service  

[Service]
#service type
Type=simple          #服务类型,1)simple(默认值):ExecStart字段启动的进程为主进程 2)forking:ExecStart字段将以fork()方式启动,此时父进程将会退出,子进程将成为主进程

#3)oneshot:类似于simple,但只执行一次,Systemd 会等它执行完,才启动其他服务 4)dbus:类似于simple,但会等待 D-Bus 信号后启动

#5)notify:类似于simple,启动结束后会发出通知信号,然后 Systemd 再启动其他服务,fixme:这种需要启动程序实现sd_notify 6)idle:类似于simple,但是要等到其他任务都执行完,才会启动该服务。一种使用场合是为让该服务的输出,不与其他服务的输出相混合

# for php-fpm container control,
ExecStart=/usr/bin/docker-compose -f /etc/docker/docker-compose.yml up 
#ExecReload=
ExecStop=/usr/bin/docker-compose -f /etc/docker/docker-compose.yml stop

# kill only the docker process, only exec ExecStop
KillMode=none
# softdog :restart the php-fpm process if it exit
Restart=on-failure  #异常时会重启
RestartSec=3s       #每3s检查一次
StartLimitBurst=3
StartLimitInterval=60s   

[Install]
WantedBy=multi-user.target

编写完成放到/usr/lib/systemd/system/目录下,即/usr/lib/systemd/system/phpfpmd.service

  1. 刷新
bash 复制代码
systemctl daemon-reload
  1. 开启自启动
bash 复制代码
systemctl enable phpfpmd
  1. 启动容器
bash 复制代码
systemctl restart phpfpmd

至此一个完整的docker容器就完成了

相关推荐
青年vs阳光1 小时前
win10把c盘docker虚拟硬盘映射迁移到别的磁盘
运维·docker·容器
土豆沒加3 小时前
ubuntu22.04使用minikube安装k8s
云原生·容器·kubernetes
猫吃了源码4 小时前
KubeKey一键安装部署k8s集群和KubeSphere详细教程
云原生·容器·kubernetes
你可以叫我仔哥呀4 小时前
k8s学习记录:环境搭建(基于Kubeadmin)
学习·容器·kubernetes
容器魔方5 小时前
KubeEdge社区2025年需求征集
云原生·容器·云计算
Abdullah al-Sa6 小时前
Docker教程(喂饭级!)
c++·人工智能·docker·容器
web2u6 小时前
Docker入门及基本概念
java·运维·服务器·spring·docker·容器
笑虾6 小时前
Docker 自制镜像:Ubuntu 安装 samba+Webmin
ubuntu·docker·samba
元气满满的热码式7 小时前
Docker实战-使用docker compose搭建博客
运维·docker·容器
哥是黑大帅11 小时前
Docker基于Ollama本地部署大语言模型
python·docker·语言模型