本文介绍从一个空白的裸机CentOS自己构造检验允许的docker环境。来达到运行环境的高度定制,而不是只能依赖VS或者微软或者数据库厂商提供的镜像当做基础制作。更容易理解基础原理。最终输出产物为lisnew.tar,一个开箱即用的lis运行环境。
制作的整个过程的Shell日志
由于微软提供的docker镜像是debian系统的,俺不想用,加上我想试试自己从裸机做镜像
#先查看可用的centos镜像
[root@localhost zlzdocker]# docker search centos
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
centos DEPRECATED; The official build of CentOS. 7614 [OK]
kasmweb/centos-7-desktop CentOS 7 desktop for Kasm Workspaces 38
bitnami/centos-base-buildpack Centos base compilation image 0 [OK]
couchbase/centos7-systemd centos7-systemd images with additional debug… 8 [OK]
continuumio/centos5_gcc5_base 3
datadog/centos-i386 0
dokken/centos-7 CentOS 7 image for kitchen-dokken 5
dokken/centos-8 CentOS 8 image for kitchen-dokken 3
spack/centos7 CentOS 7 with Spack preinstalled 1
dokken/centos-6 EOL: CentOS 6 image for kitchen-dokken 0
atlas/centos7-atlasos ATLAS CentOS 7 Software Development OS 0
couchbase/centos-72-java-sdk 0
spack/centos6 CentOS 6 with Spack preinstalled 1
couchbase/centos-72-jenkins-core 0
ustclug/centos Official CentOS Image with USTC Mirror 0
couchbase/centos-70-sdk-build 0
couchbase/centos-69-sdk-build 0
couchbase/centos-69-sdk-nodevtoolset-build 0
dokken/centos-stream-8 4
eclipse/centos_jdk8 CentOS, JDK8, Maven 3, git, curl, nmap, mc, … 5 [OK]
adoptopenjdk/centos7_build_image 1
corpusops/centos-bare https://github.com/corpusops/docker-images/ 0
dokken/centos-stream-9 6
corpusops/centos centos corpusops baseimage 0
adoptopenjdk/centos6_build_image 0
然后拉取最新的centos镜像
[root@localhost zlzdocker]# docker pull centos
Using default tag: latest
latest: Pulling from library/centos
Digest: sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177
Status: Downloaded newer image for centos:latest
docker.io/library/centos:latest
然后用centos镜像创建一个容器叫lis
[root@localhost zlzdocker]# docker run -idt -p 5002:5002 -p 8081:8081 --name=lis -v /dthealth/app/dthis/imedicallis:/dthealth/app/dthis/imedicallis centos
fc99e3ba248f97cc833e57dcb91ad90c973a6f32d609b4ae3ff48ecdf6b55eea
docker: Error response from daemon: driver failed programming external connectivity on endpoint lis (2b338616934b737a9aff8cfab4637bf5425f6357cb4600a058f780bec9c1788b): Bind for 0.0.0.0:8081 failed: port is already allocated.
[root@localhost zlzdocker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fc99e3ba248f centos "/bin/bash" 11 seconds ago Created lis
7806efbc0a25 imedicallis:9.0 "dotnet /dthealth/ap…" About an hour ago Up About an hour 0.0.0.0:5002->5002/tcp, :::5002->5002/tcp, 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp imedicallis
f87c5bb32393 nginx "/docker-entrypoint.…" 3 hours ago Exited (0) 3 hours ago nginx3
6e55d8e750ca nginx "/docker-entrypoint.…" 4 hours ago Exited (0) 3 hours ago nginx1
61208409f5ca nginx "/docker-entrypoint.…" 4 hours ago Exited (0) 3 hours ago
然后进入容器安装环境发现无法使用yum仓库
[root@localhost zlzdocker]# docker exec -it lis /bin/bash
[root@fc99e3ba248f /]#
[root@fc99e3ba248f /]#
[root@fc99e3ba248f /]#
[root@fc99e3ba248f /]#
[root@fc99e3ba248f /]#
[root@fc99e3ba248f /]# ls
bin dev dthealth etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@fc99e3ba248f /]# yum install dotnet-sdk-6.0
Failed to set locale, defaulting to C.UTF-8
解决yum源的问题,wget这些没有,也没法安装,我通过共享目录拷的阿里云的yum源文件操作的
[root@fc99e3ba248f /]# wget -O /etc/yum.repos.d/CentOS-Linux-BaseOS.repo http://mirrors.aliyun.com/repo/Centos-8.repo
bash: wget: command not found
[root@fc99e3ba248f /]# mv /dthealth/app/dthis/imedicallis/CentOS-Linux-BaseOS.repo /etc/yum.repos.d/
mv: overwrite '/etc/yum.repos.d/CentOS-Linux-BaseOS.repo'? y
[root@fc99e3ba248f /]# yum makecache
Failed to set locale, defaulting to C.UTF-8
Repository extras is listed more than once in the configuration
CentOS Linux 8 - AppStream 81 B/s | 38 B 00:00
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
[root@fc99e3ba248f /]# cat /etc/yum.repos.d/CentOS-Linux-BaseOS.repo
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/BaseOS/$basearch/os/
http://mirrors.aliyuncs.com/centos/$releasever/BaseOS/$basearch/os/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/BaseOS/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/os/
http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/os/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/os/
http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/os/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/os/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
[PowerTools]
name=CentOS-$releasever - PowerTools - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/PowerTools/$basearch/os/
http://mirrors.aliyuncs.com/centos/$releasever/PowerTools/$basearch/os/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/PowerTools/$basearch/os/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
[AppStream]
name=CentOS-$releasever - AppStream - mirrors.aliyun.com
#failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/AppStream/$basearch/os/
http://mirrors.aliyuncs.com/centos/$releasever/AppStream/$basearch/os/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/AppStream/$basearch/os/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-Official
[root@fc99e3ba248f /]# yum repolist
Failed to set locale, defaulting to C.UTF-8
Repository extras is listed more than once in the configuration
repo id repo name
AppStream CentOS-8 - AppStream - mirrors.aliyun.com
appstream CentOS Linux 8 - AppStream
base CentOS-8 - Base - mirrors.aliyun.com
extras CentOS-8 - Extras - mirrors.aliyun.com
[root@fc99e3ba248f /]# yum makecache
Failed to set locale, defaulting to C.UTF-8
Repository extras is listed more than once in the configuration
CentOS Linux 8 - AppStream 85 B/s | 38 B 00:00
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist
[root@fc99e3ba248f /]# cd /etc/yum.repos.d/
[root@fc99e3ba248f yum.repos.d]# sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
[root@fc99e3ba248f yum.repos.d]# sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
[root@fc99e3ba248f yum.repos.d]# yum update
Failed to set locale, defaulting to C.UTF-8
Repository extras is listed more than once in the configuration
CentOS Linux 8 - AppStream 628 kB/s | 8.4 MB 00:13
CentOS-8 - Base - mirrors.aliyun.com 1.1 MB/s | 4.6 MB 00:04
CentOS-8 - Extras - mirrors.aliyun.com 72 kB/s | 10 kB 00:00
CentOS-8 - AppStream - mirrors.aliyun.com 802 kB/s | 8.4 MB 00:10
Dependencies resolved.
================================================================================================================================================================================================================================
Package Architecture Version Repository Size
================================================================================================================================================================================================================================
Upgrading:
bash x86_64 4.4.20-2.el8 base 1.5 M
bind-export-libs x86_64 32:9.11.26-6.el8 base 1.1 M
binutils x86_64 2.30-108.el8_5.1 base 5.8 M
ca-certificates noarch 2021.2.50-80.0.el8_4 base 390 k
centos-gpg-keys noarch 1:8-3.el8 base 12 k
centos-linux-release noarch 8.5-1.2111.el8 base 22 k
centos-linux-repos
解决完了就可以用yum安装.net运行时了,也能安装C++那些编译环境了,和Linux一样编译libgdiplus包,细节参照红帽8.5编译libgdiplus。依赖的dotnet环境和libgdiplus都搞好后准备制作镜像文件。
[root@fc99e3ba248f testdraw]# dotnet lisdrawtest.dll
此程序为imedicallis提供用于测试linux下dotnetcore绘图环境
创建位图
创建画笔
填充白色
创建Pen
画一条竖线
画一条横线
创建字体
创建画刷
绘制字符串
测试.jpg
测试.bmp
测试.gif
保存文件到:/testdraw/lisdrawtest.bmp
保存文件到:/testdraw/lisdrawtest.jpg
保存文件到:/testdraw/lisdrawtest.jpg
测试完成,如果成功生成图片那么环境可用
[root@fc99e3ba248f testdraw]# cp /dthealth/app/dthis/imedicallis/tool/imedicallis /usr/bin
提交容器修改到镜像,就多了一个centos:latest的镜像,然后改名为lis:9.0
[root@localhost zlzdocker]# docker commit -a "zhanglianzhu" -m "lis9.0" lis centos
sha256:d506d0783711c47869758d132dd0ff05ab1e5b121248cc4ed5d00a8b97dbad09
[root@localhost zlzdocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest d506d0783711 18 seconds ago 1.67GB
imedicallis 9.1 149406465334 2 hours ago 208MB
zlznginx 1.0 448f5d1d8e1a 6 hours ago 187MB
imedicallis 9.0 edd4d70c03a3 8 days ago 208MB
nginx latest 021283c8eb95 2 weeks ago 187MB
centos <none> 5d0da3dc9764 22 months ago 231MB
[root@localhost zlzdocker]# docker tag centos:latest lis:9.0
[root@localhost zlzdocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest d506d0783711 6 minutes ago 1.67GB
lis 9.0 d506d0783711 6 minutes ago 1.67GB
imedicallis 9.1 149406465334 2 hours ago 208MB
zlznginx 1.0 448f5d1d8e1a 6 hours ago 187MB
imedicallis 9.0 edd4d70c03a3 8 days ago 208MB
nginx latest 021283c8eb95 2 weeks ago 187MB
centos <none> 5d0da3dc9764 22 months ago 231MB
把镜像保存为文件
[root@localhost zlzdocker]# docker save -o lis.tar lis
[END] 2023/7/20 15:27:26
由于这是我搞的centos原生的镜像,所以没有ENTRYPOINT指定启动名称,需要我再处理一次加了启动指令
制作基于lis:9.0的Dockerfile文件
#构造imedicallis的docker镜像
#基础镜像
FROM lis:9.0 AS base
#MAINTAINER 维护者信息
MAINTAINER zhanglianzhu
#工作路径
WORKDIR /
#对外端口
EXPOSE 5002
EXPOSE 8081
#映射路径
VOLUME ["/dthealth/app/dthis/imedicallis"]
#启动容器执行的命令
ENTRYPOINT ["dotnet", "/dthealth/app/dthis/imedicallis/iMedicalLIS.dll","--urls","https://*:5002"]
载入镜像文件lis.tar,然后基于上面的Dockerfile创建新的镜像lisnew,并且创建容器测试站点
[root@localhost zlzdocker]#
[root@localhost zlzdocker]#
[root@localhost zlzdocker]# docker load -i /zlzdocker/lis.tar
Loaded image: lis:9.0
[root@localhost zlzdocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
lis 9.0 d506d0783711 40 minutes ago 1.67GB
nginx latest 021283c8eb95 2 weeks ago 187MB
centos <none> 5d0da3dc9764 22 months ago 231MB
[root@localhost zlzdocker]# docker build -t lisnew:9.0 .
[+] Building 2.7s (5/5) FINISHED docker:default
=> [internal] load .dockerignore 0.4s
=> => transferring context: 2B 0.0s
=> [internal] load build definition from Dockerfile 0.5s
=> => transferring dockerfile: 486B 0.1s
=> [internal] load metadata for docker.io/library/lis:9.0 0.0s
=> CACHED [1/2] FROM docker.io/library/lis:9.0 0.0s
=> exporting to image 0.3s
=> => exporting layers 0.0s
=> => writing image sha256:4d0e66e949d13b9101d2bb0fc9bfe70a6eda8f9130ae96b13c7592a2591bd393 0.1s
=> => naming to docker.io/library/lisnew:9.0 0.2s
[root@localhost zlzdocker]# cat Dockerfile
#构造imedicallis的docker镜像
#基础镜像
FROM lis:9.0 AS base
#MAINTAINER 维护者信息
MAINTAINER zhanglianzhu
#工作路径
WORKDIR /
#对外端口
EXPOSE 5002
EXPOSE 8081
#映射路径
VOLUME ["/dthealth/app/dthis/imedicallis"]
#启动容器执行的命令
ENTRYPOINT ["dotnet", "/dthealth/app/dthis/imedicallis/iMedicalLIS.dll","--urls","https://*:5002"][root@localhost zlzdocker]#
[root@localhost zlzdocker]#
[root@localhost zlzdocker]#
[root@localhost zlzdocker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
lis 9.0 d506d0783711 40 minutes ago 1.67GB
lisnew 9.0 4d0e66e949d1 40 minutes ago 1.67GB
nginx latest 021283c8eb95 2 weeks ago 187MB
centos <none> 5d0da3dc9764 22 months ago 231MB
[root@localhost zlzdocker]# docker run -idt -p 5002:5002 -p 8081:8081 --name=lisnew -v /dthealth/app/dthis/imedicallis:/dthealth/app/dthis/imedicallis lisnew:9.0
2f99295c04fd45774cdb597818f07eb8aafe13401a4bf6617234834818e21c78
[root@localhost zlzdocker]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2f99295c04fd lisnew:9.0 "dotnet /dthealth/ap…" 8 seconds ago Up 5 seconds 0.0.0.0:5002->5002/tcp, :::5002->5002/tcp, 0.0.0.0:8081->8081/tcp, :::8081->8081/tcp lisnew
[root@localhost zlzdocker]#
然后把新的lisnew镜像打包成文件,以后别人拿到lisnew.tar镜像文件后就只需要load和创建容器即可
[root@localhost zlzdocker]# docker save -o lisnew.tar lisnew
最终部署时候如果有docker环境的话只需要执行下面两个命令即可得到全部的lis运行环境运行。在宿主机器映射的目录放网站文件即可。这样不同组对dotnet版本要求不同,对其他环境依赖不同就可以隔离了,以后发版只要发布lisnew.tar即可,宿主可以是任意安装docker的Linux
docker load -i /zlzdocker/lisnew.tar
docker run -idt -p 5002:5002 -p 8081:8081 --name=lisnew -v /dthealth/app/dthis/imedicallis:/dthealth/app/dthis/imedicallis lisnew:9.0
压缩导出和导入
#压缩导出
docker save lisdocker:latest | gzip > lisdocker.tar.gz
#压缩导入
gunzip -c lisdocker.tar.gz | docker load