使用docker部署.net core3.1时的Dockerfile写法(持续补充)
对于docker的安装和基本命令,在此不多做解释。本文主要针对的是创建容器时的一些坑,以及一些问题的分享,希望大家一起探讨解决。
首先是dockerfile的一些基本内容
#引入镜像,低版本 docker 去掉 AS base #换成别人做的阿里镜像 #FROM registry.cn-hangzhou.aliyuncs.com/newbe36524 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base #配置工作目录 相当于cd WORKDIR /app #暴露容器端口,此端口与程序运行路径一致,可 EXPOSE 80 #复制文件到工作目录 COPY . . #ENV :配置系统环境变量,比如程序环境环境等在这里配置(开发、预发、线上环境) #这里是配置程序运行端口 如果程序不使用默认的80端口这里一定要设置(程序运行端口) ENV ASPNETCORE_URLS http://+:80 #启动程序 ENTRYPOINT ["dotnet", "你的启动项目名称.dll"]
这个是从一位博主那儿摘来的,原文地址为:https://www.cnblogs.com/yiting/p/13388155.html
不过我现在粘贴的这部分,也是有做一些修改的。
然后接下来的内容,就是基于这个为原型,进行的添加。
注意这个dockerfile指的是,针对在vs中,用网站发布的方式生成的一系列文件后用的。并不是那种,使用git在linux系统某个文件夹里直接拉一整个项目,然后直接构建部署。vs默认给的dockerfile文件,就属于这种。
1、dockerfile中的第一条:FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base,aspnet:3.1-buster-slim镜像速度拉取非常慢的问题。
这个问题我到现在都是记忆犹新。那时候刚上手.net core,准备用docker发布一个试试的时候,就被这一句无情卡住。拉镜像的时候速度非常非常慢,而且那个时候不知道这一句的意思其实拉镜像,弄得百度都不知道怎么百。
这里我给第一次使用docker发布.net core的小伙伴解释一下这个东西。
a、关于这个镜像,他是只需要下载一次就够了的,并不是每一次docker build都要重新下载。并且下完之后,你还能通过docker images命令找到这个镜像的记录。
b、如何加速?
关于这个,小伙伴可以自行百度,搜索 aspnet:3.1-buster-slim国内镜像
当然,这里我也给出一个方案。
就是上面这个dockerfile里面的from改成别人做的阿里的镜像(这个镜像地址来源于https://www.newbe.pro/Mirrors/Mirrors-NetCore/)
这个制作方式,其实就是别人下载好了之后,上传到自己的仓库,然后把地址给出来,让别人下载,所以这里我也无法保证地址的有效性。
2、docker 容器内的时区问题
容器内部的时间是按照美国来的,所以会存在一个时区问题。
解决办法:
#设置时间为中国上海 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
将这三行加入到dockerfile中,然后重新构建image。
关于这三行命令该加在哪个位置,其实这个只要是放在 FROM 命令的下面,大致上都是不会有什么问题的。
3、docker容器中没有vim / vi
在使用 docker exec -it [容器ID] /bin/bash 进入容器之后,会发现没有了vim / vi
关于这个的话,百度很容易找到答案。
但是百度的答案前篇一律。先使用 docker exec -it [容器id] /bin/bash 命令进入容器后
apt-get update apt-get install -y vim
然后就成功安装好了vim了(安装vi 使用 apt-get install -y vi)
但是他们的都是进入容器后的操作,但我觉得这东西应该是在创建容器的时候,容器内部的debian系统,就直接就按照我的要求,装好我要的东西。
所以关于这种需求,接下来则是需要在dockerfile中,加一句内容。
RUN apt-get update && apt-get install -y vim
实现方式还是很简单的,添加一个RUN命令,然后update和install变成一句,使用 && 将两个命令连成一句。
但是实际构建镜像的时候,其实问题还是蛮多的。
在build的时候,你就会发现apt-get update这个命令奇慢无比,所以在这个时候,就是要将debian系统的源,指定为国内的源。
这个问题我也是花了几天时间,试了好多好多别人给的源后,终于得出的结果(这一句命令,要放在 RUN apt-get update .... 之前)。
RUN sed -i 's#http://deb.debian.org#https://mirrors.aliyun.com#g' /etc/apt/sources.list
这一句命令来自于 https://blog.hidove.cn/post/750
我给大家分享一下,我解决这个问题的整个流程(如果上面这个命令对你无效的话,可以参考我的解决方式,自行寻找其他途径)。
a、首先刚开始的时候,我也是按照正常思维来解决,就是直接百度 apt-get update速度慢,然后得出一大堆ubuntu系统的解决方案。
b、然后是注意到在容器里面执行apt-get update的时候,无意中看到了debian 字样,然后我才知道,容器里面是debian系统。
c、接着就是想办法知道debian系统的版本。(在容器内使用 cat /etc/issue ,可查看系统版本。 命令来源 https://blog.csdn.net/c461522756/article/details/70822234)
d、我这边查到的debian 10,所以通过这个,去找的对应的国内源。
4、docker容器中安装一些包
以安装一个 system.drawing 命名空间下的方法要用到的 GDI+ 为例:
假设已经存在容器,则直接是 docker exec -it [容器id] /bin/bash 进入容器内部。如果容器创建之后从来没有执行过 apt-get update ,则需要先执行 apt-get update ,然后再执行安装命令。
apt-get install -y libgdiplus
当然,这个也是可以直接写入到dockerfile 中,在每一次构建的时候,都直接装好。
RUN apt-get update && apt-get install -y libgdiplus
5、环境变量的设置,出现关键字冲突
正常情况下,如果我们想在容器里配置环境变量,都是会在Dockerfile中使用ENV进行设置,例如:
#设置环境为开发环境
ENV ASPNETCORE_ENVIRONMENT=Development
里面一共是两种书写格式:
上面两张图,是来自编译器的提示。
加入我想要设置一个环境变量,里面存储的是mysql数据库的连接字符串
ENV MysqlDb="Data Source=xxx.xxx.xxx.xxx;Database=test;User ID=root;Password=123456&;pooling=true;port=3306;sslMode=None;CharSet=utf8;"
则需要用双引号把内容引起来,因为里面出现了 “=”
再接着,这里面还有一个问题,就是连接字符串里面的Password
里面有个字符 “&”
这个也是关键字,需要避免掉,否则你生成出来的docker容器里面。上面一句话,会让你出现好几个环境变量。
上面几个问题解决完之后,最终的dockerfile文件为
#引入镜像,低版本 docker 去掉 AS base #换成别人做的阿里镜像 #FROM registry.cn-hangzhou.aliyuncs.com/newbe36524 FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base #配置工作目录 相当于cd WORKDIR /app #暴露容器端口,此端口与程序运行路径一致,可 EXPOSE 80 #复制文件到工作目录 COPY . . #ENV :配置系统环境变量,比如程序环境环境等在这里配置(开发、预发、线上环境) #这里是配置程序运行端口 如果程序不使用默认的80端口这里一定要设置(程序运行端口) ENV ASPNETCORE_URLS http://+:80 #设置时间为中国上海 ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone #设置debian系统 RUN sed -i 's#http://deb.debian.org#https://mirrors.aliyun.com#g' /etc/apt/sources.list RUN apt-get update && apt-get install -y vim && apt-get install -y libgdiplus #启动程序
ENTRYPOINT ["dotnet", "你的启动项目名称.dll"]