创建项目docker bridge网络,用来整个项目容器之间相互访问
#创建桥接网络
sudo docker network create metaverse.app 或docker network create --driver bridge metaverse.app
#查看创建的网络是否存在
sudo docker network ls
#将已存在容器加入网络或者重新运行新容器加入网络
sudo docker network connect metaverse.app --alias app-test app-test
#把webapi容器移除自定义网络
sudo docker network disconnect app app-test
#如果要修改容器启动项,则可以使用 docker update
sudo docker update app-test --restart always #这表示设置容器随着docker启动自动启动
#查看网络中有那些容器加入
sudo docker network inspect metaverse.app
数据库sqlserver2022(sqlserver2022运行到容器教程)
#将sqlserver2022容器加入到项目网络中或在运行的时候加入到网络
sudo docker network connect metaverse.app --alias sqlserver2022 sqlserver2022
或
sudo docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Suixin@123" -e "MSSQL_PID=Enterprise" -e "MSSQL_COLLATION=Chinese_PRC_BIN" \
--network metaverse.app --network-alias sqlserver2022 \
-p 1433:1433 --name sqlserver2022 \
-d --restart=always \
-v /opt/mssql2022:/var/opt/mssql \
-v /opt/mssql2022_backup:/opt/mssql2022_backup \
-e TZ=Asia/Shanghai \
mcr.microsoft.com/mssql/server:2022-latest
#查看容器是否加入成功
sudo docker inspect sqlserver2022
#查看网络中容器是否加入成功
sudo docker network inspect metaverse.app
发布程序并复制到服务器上
这里我以NET6为例(System.Drawing.Common类库,Linux下Ubuntu会报Gdip错误解决建议)
dokcer 部署 使用 SixLabors.Fonts 库遇到SystemFonts.Families默认字体为空问题,解决方式加载自定义路径字体或者拷贝字体到 “/usr/local/share/fonts/”, “/usr/share/fonts/”, 等路径下
以下Dockerfile
#如果使用了System.Drawing.Common类库,Linux下Ubuntu会报Gdip错误,如果安装不生效的话,直接用官方建议的替代库吧
#这里我发布到服务器未生效,服务器我已用ImageSharp库了
#The type initializer for 'Gdip' threw an exception.
#---> System.PlatformNotSupportedException: System.Drawing.Common is not supported on non-Windows #platforms. See https://aka.ms/systemdrawingnonwindows for more information.
#在.NET 5 和早期版本中需要安装libgdiplus类库来解决,在 .NET 6 及更高版本中需要使用替代库来解决
apt-get install libgdiplus
cd /usr/lib
ln -s libgdiplus.so gdiplus.dll
#添加docker支持Dockerfile文件
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
#注意注意注意 如何程序里有使用 "Urls": [ "http://*:8000" ]或指定监听端口,导出的EXPOSE 80 端口要一致
#否则会出现容器正常运行,却无法访问问题
EXPOSE 80
FROM base AS final
#-------------开始(如果镜像源是国内的,则可以不需要)-----------------------
#RUN cd /etc/apt
#WORKDIR /etc/apt
# 备份
#RUN mkdir sources.list.bak
#RUN cp sources.list ./sources.list.bak
# 以覆盖+追加的方式替换掉sources.list文件
#我ubuntu版本为20.04,镜像源需要根据自己的系统版本来更换
#使用lsb_release -c 能查看到系统的发行版本号名称 focal
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse'>>sources.list
#RUN cat sources.list
#-----------结束(如果镜像源是国内的,则可以不需要)-----------------------
#-----------如果使用了 ImageSharp 等跨平台库替代了System.Drawing.Common则不需要执行--------
#在.NET 5 和早期版本中需要安装libgdiplus类库来解决,在 .NET 6 及更高版本中需要使用替代库来解决
RUN apt-get update -y
RUN apt-get install -y libgdiplus
# RUN cd /usr/lib
WORKDIR /usr/lib
#添加软链接
RUN ln -s libgdiplus.so gdiplus.dll
#-----------如果使用了 SixLabors.ImageSharp跨平台库替代了System.Drawing.Common则不需要执行--------
#进入容器目录
WORKDIR /app
#将发布文件复制到容器目录
COPY . /app
ENTRYPOINT ["dotnet", "Metaverse.Api.dll"]
#或直接打包一个空壳容器,然后挂载发布程序目录
#不执行复制发布程序到容器 需要挂载 发布程序目录 到/app 目录下
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
#注意注意注意 如何程序里有使用 "Urls": [ "http://*:8000" ]或指定监听端口,导出的EXPOSE 80 端口要一致
#否则会出现容器正常运行,却无法访问问题
EXPOSE 80
FROM base AS final
#-------------开始(如果镜像源是国内的,则可以不需要)-----------------------
#RUN cd /etc/apt
#WORKDIR /etc/apt
# 备份
#RUN mkdir sources.list.bak
#RUN cp sources.list ./sources.list.bak
# 以覆盖+追加的方式替换掉sources.list文件
#我ubuntu版本为20.04,镜像源需要根据自己的系统版本来更换
#使用lsb_release -c 能查看到系统的发行版本号名称 focal
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse'>>sources.list
#RUN echo 'deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse'>>sources.list
#RUN echo 'deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse'>>sources.list
#RUN cat sources.list
#-----------结束(如果镜像源是国内的,则可以不需要)-----------------------
#-----------如果使用了ImageSharp跨平台库替代了System.Drawing.Common则不需要执行--------
#在.NET 5 和早期版本中需要安装libgdiplus类库来解决,在 .NET 6 及更高版本中需要使用替代库来解决
RUN apt-get update -y
RUN apt-get install -y libgdiplus
# RUN cd /usr/lib
WORKDIR /usr/lib
#添加软链接
RUN ln -s libgdiplus.so gdiplus.dll
#-----------如果使用了 SixLabors.ImageSharp跨平台库替代了System.Drawing.Common则不需要执行--------
WORKDIR /app
#将发布文件复制到容器目录
#COPY . /app
ENTRYPOINT ["dotnet", "Metaverse.Api.dll"]
#打包发布程序,运行目标选择为可移植
#把所有的发布文件打包成压缩包zip,上传到ubuntu系统中
#安装解压工具
sudo apt-get install unzip
#解压发布文件zip
unzip publish.zip -d publish
把解压完成的发布文件打包成docker镜像
#打包成镜像文件
#进入到publish
cd ~/publish
#执行打包命令
sudo docker build -t metaverse.api:0.0.3 -f Dockerfile .
#或 --no-cache 设置构建时不使用缓存:tag latest
sudo docker build --no-cache -t metaverse.api:latest -f Dockerfile .
#查看打包的镜像
sudo docker images
docker运行webapi容器
#创建外部挂载目录,挂载Configs的原因是因为更新的时候不需要每次都去更改一遍配置文件
sudo mkdir -p /metaverseapi/Configs
#运行容器并加入到网络,或把现有的容器加入到网络
sudo docker run -d --restart=always \
--network metaverse.app --network-alias metaverse.api \
-p 5001:80 --name metaverse.api \
-v /metaverseapi/Configs:/app/Configs \
-e TZ=Asia/Shanghai \
metaverse.api:0.0.3
或
sudo docker network connect metaverse.app --alias metaverse.api metaverse.api
#查看容器网络
sudo docker inspect metaverse.api
#查看网络中有那些容器加入
sudo docker network inspect metaverse.app
docker运行nginx容器(Nginx官方文档)+certbot免费ssl证书((cerbot官网))
#拉取nginx镜像
sudo docker pull nginx:latest
#批量创建nginx 外部挂载目录
sudo mkdir -p \
/nginx/html \
/nginx/conf \
/nginx/log \
/nginx/certbot/www \
/nginx/certbot/ssl \
/nginx/certbot/logs \
/nginx/certbot/cron
#运行一个临时nginx容器并把相关文件复制到挂载目录下
sudo docker run --name tempnginx -p 8000:80 -d nginx
#复制相关配置文档到挂载目录
#复制nginx.conf
sudo docker cp tempnginx:/etc/nginx/nginx.conf /nginx/conf/nginx.conf
#复制conf.d
sudo docker cp tempnginx:/etc/nginx/conf.d /nginx/conf/conf.d
#复制html
sudo docker cp tempnginx:/usr/share/nginx/html /nginx/
#移除临时nginx容器
sudo docker rm -f tempnginx
#重新运行一个新的nginx并加入到网络
#/nginx/certbot/www 与certbot容器共用,http验证目录
#/nginx/certbot/ssl 与certbot容器共用,证书位置
sudo docker run -d --restart=always \
-p 80:80 -p 443:443 \
--name nginx --network metaverse.app --network-alias nginx \
-v /nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /nginx/conf/conf.d:/etc/nginx/conf.d \
-v /nginx/log:/var/log/nginx \
-v /nginx/html:/usr/share/nginx/html \
-v /nginx/cert:/etc/nginx/cert \
-v /nginx/certbot/www:/usr/share/certbot/www \
-v /nginx/certbot/ssl:/usr/share/certbot/ssl \
-e LANG=C.UTF-8 -e LC_ALL=C.UTF-8 -e TZ=Asia/Shanghai \
nginx:latest
#或容器运行成功后加入桥接网络metaverse.app
sudo docker network connect metaverse.app --alias nginx nginx
#查看网络中有那些容器加入
sudo docker network inspect metaverse.app
#回车确认,看到sqlserver api nginx 都在同一个桥接网络了
certbot免费ssl证书生成
#拉取cerbot镜像
sudo docker pull certbot/certbot
#运行容器测试生成证书 --dry-run 表示模拟运行,不进行实际的证书生成,正式运行去掉模拟运行指令就可以了
sudo docker run -it --rm \
-v /nginx/certbot/www:/data/letsencrypt \
-v /nginx/certbot/ssl:/etc/letsencrypt \
-v /nginx/certbot/logs:/var/log/letsencrypt \
certbot/certbot certonly -n --webroot --webroot-path=/data/letsencrypt -m xxx@qq.com --dry-run --agree-tos -d www.xxx.com
#正式运行生成ssl证书
sudo docker run -it --rm \
-v /nginx/certbot/www:/data/letsencrypt \
-v /nginx/certbot/ssl:/etc/letsencrypt \
-v /nginx/certbot/logs:/var/log/letsencrypt \
certbot/certbot certonly -n --webroot --webroot-path=/data/letsencrypt -m xxx@qq.com --agree-tos -d www.xxx.com
#免费的ssl证书一般只有60-90天时间,所以需要定时计划任务执行 renew 自动续期
#这里直接使用系统的cron任务
#查看crontab 服务是否启用,如果提示Unit cron.service could not be found.则需要安装服务
sudo systemctl status cron
#安装cron服务
sudo apt update
sudo apt install cron
#安装完成记得启动,然后添加到开机自启动
sudo systemctl enable cron
#进入之前创建的/nginx/certbot/cron 目录
cd /nginx/certbot/cron
#创建sh文件
sudo touch certbot_renew.sh
#添加文件权限 r=4 x=1 w=2
sudo chmod 776 certbot_renew.sh
#添加计划任务脚本
<<EOT cat>> certbot_renew.sh
#!/bin/bash
sudo docker run -it --rm \
-v /nginx/certbot/www:/data/letsencrypt \
-v /nginx/certbot/ssl:/etc/letsencrypt \
-v /nginx/certbot/logs:/var/log/letsencrypt \
certbot/certbot renew
EOT
#编辑crontab任务
crontab -e
#添加一行 * * * * * 分 时 日 月 星期,这里我先每天晚上1点30执行,先看看计划任务情况,也可以设置为0 0 1,15 * * 每月的1号和15号执行
30 1 * * * /nginx/certbot/cron/certbot_renew.sh
#列出crontab 任务
crontab -l
#查看执行日志,实时日志
sudo tail -f /var/log/syslog | grep -i cron
#查看历史日志
sudo grep -i cron /var/log/syslog | grep -i 'certbot_renew'
打包web vue项目
#打包web并把打包成功dist目录压缩zip压缩包
#压缩包上传到服务器,解压压缩包到nginx html目录下 unzpi -o 表示覆盖现有目录
sudo unzip ~/dist.zip -d /nginx/html/metaverse_web
#修改nginx config.d目录下的default.conf
server {
listen 80;
listen 443 ssl;
server_name localhost; # 修改为docker服务宿主机的域名
server_tokens off; #隐藏错误信息nginx 显示的版本号
ssl_certificate /usr/share/certbot/ssl/live/localhost/fullchain.pem; #证书文件
ssl_certificate_key /usr/share/certbot/ssl/live/localhost/privkey.pem; #证书密钥文件
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on; #配置http验证可访问
location ~/.well-known/acme-challenge/ {
#nginx 挂载的http验证目录,与certbot容器中命令--webroot-path指定目录一致
root /usr/share/certbot/www;
}
location / {
root /usr/share/nginx/html/metaverse_web;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
error_page 405 =200 $uri;
}
# 进行路径匹配,匹配到api代理
location /api/ {
proxy_pass http://metaverse.api:5001;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
#设置最大上传大小,如果超出50M,会出现413 实体请求过大错误
client_max_body_size 50m;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
#访问是否生效
curl http://127.0.0.1
最后附上成功图
公众号“点滴分享技术猿”