日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx

發(fā)布時(shí)間:2023/12/4 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、前言

  在之前的文章(ASP.NET Core 實(shí)戰(zhàn):Linux 小白的 .NET Core 部署之路)中,我介紹了如何在 Linux 環(huán)境中安裝 .NET Core SDK / .NET Core Runtime、Nginx、MySQL,以及如何將我們的 ASP.NET Core MVC 程序部署到 Linux 上,同時(shí),使用 supervisor??守護(hù)程序守護(hù)我們的 .NET Core 程序。如果,你有看過(guò)那篇文章,并且和我一樣是個(gè) Linux 小白用戶的話,可能第一感覺(jué)就是,把 .NET Core 項(xiàng)目部署在 IIS?上也挺好。

  將 .NET Core 項(xiàng)目部署到 Linux 上如此復(fù)雜,就沒(méi)有簡(jiǎn)單的部署方式嗎?

  你好,有的,Docker 了解一下~~~

  PS:這里的示例代碼還是采用之前的畢業(yè)設(shè)計(jì)項(xiàng)目,在這篇文章發(fā)布的時(shí)候,我已經(jīng)在程序的倉(cāng)庫(kù)中添加了對(duì)于 Docker 的支持,你可以下載下來(lái),自己嘗試一下,畢竟,實(shí)踐出真知。

  ?代碼倉(cāng)儲(chǔ):https://github.com/Lanesra712/Danvic.PSU

?二、Step by Step

  1、安裝 Docker & Docker Compose

  在代碼交付的過(guò)程中,偶爾會(huì)遇到這樣的問(wèn)題,在本地測(cè)試是好的,但是部署到測(cè)試環(huán)境、生產(chǎn)環(huán)境時(shí)就出這樣那樣的問(wèn)題,同時(shí),因?yàn)楸镜嘏c測(cè)試環(huán)境、生產(chǎn)環(huán)境之間存在差異,我們可能無(wú)法在本地復(fù)現(xiàn)這些問(wèn)題,那么,有沒(méi)有一種工具可以很好的解決這一問(wèn)題呢?隨著歷史的車輪不斷前行,容器技術(shù)誕生了。

  Docker,作為最近幾年興起的一種虛擬化容器技術(shù),他可以將我們的運(yùn)行程序與操作系統(tǒng)做一個(gè)隔離,例如這里我們需要運(yùn)行 .NET Core 程序,我們不再需要關(guān)心底層的操作系統(tǒng)是什么,不需要在每臺(tái)需要需要運(yùn)行程序的機(jī)器上安裝程序運(yùn)行的各種依賴,我們可以通過(guò)程序打包成鏡像的方式,將應(yīng)用程序和該程序的依賴全部置于一個(gè)鏡像文件中,這時(shí),只要?jiǎng)e的機(jī)器上有安裝 Docker,就可以通過(guò)我們打包的這個(gè)鏡像來(lái)運(yùn)行這個(gè)程序。

  1.1、卸載 Docker

  在安裝 Docker 之前,我們應(yīng)該確定當(dāng)前的機(jī)器上是否已經(jīng)安裝好了 Docker,為了防止與現(xiàn)在安裝的 Docker CE 發(fā)生沖突,這里我們先卸載掉以前版本的 Docker,如果你確定你的機(jī)器上并沒(méi)有安裝 Docker 的話此步可以跳過(guò)。

  在 Linux 中可以使用 \ 加 Enter 在輸入很長(zhǎng)很長(zhǎng)的語(yǔ)句時(shí)進(jìn)行換行,這里和后面的命令都是采用這樣的方式。

sudo yum remove docker \
docker
-client \
docker
-client-latest \
docker
-common \
docker
-latest \
docker
-latest-logrotate \
docker
-logrotate \
docker
-engine

  1.2、添加 yum 源

  在安裝 Docker CE 的方式上,我是采用將 Docker CE 的源添加到 yum 源中,之后我們就可以直接使用 yum install 安裝 Docker CE,整個(gè)的安裝過(guò)程如下。

# 安裝工具包從而可以讓我們?cè)?yum 中添加別的倉(cāng)儲(chǔ)源
sudo yum install -y yum-utils \
device
-mapper-persistent-data \
lvm2

# 設(shè)置 docker ce 的穩(wěn)定庫(kù)地址
sudo yum-config-manager \
--add-repo \
https:
//download.docker.com/linux/centos/docker-ce.repo

# 安裝 docker ce
sudo yum install docker-ce docker-ce-cli containerd.io

  當(dāng)我們安裝好 Docker 之后,我們就可以使用 docker 命令驗(yàn)證我們是否在機(jī)器上成功安裝了 Docker,同時(shí),也可以使用 docker --version 命令查看我們安裝的 Docker CE 版本。

  1.3、設(shè)置開(kāi)機(jī)自啟

  當(dāng) Docker 已經(jīng)在我們的機(jī)器上安裝完成后,我們就可以將 Docker 設(shè)置成機(jī)器的自啟服務(wù),這樣,如果出現(xiàn)服務(wù)器重啟的情況下,我們的 Docker 也可以隨服務(wù)器的重啟自動(dòng)啟動(dòng) Docker 服務(wù)。

# 啟動(dòng) Docker 服務(wù)并允許開(kāi)機(jī)自啟
sudo systemctl start docker

# 查看當(dāng)前 dokcer 的運(yùn)行情況
sudo systemctl status docker

  1.4、Hello World

  就像我們?cè)趯W(xué)習(xí)一門新的語(yǔ)言時(shí),運(yùn)行的第一句代碼,幾乎都是打印出 Hello World,而在 Docker Hub 中,也有這么一個(gè)鏡像,在無(wú)數(shù)的 Docker 教程中,安裝完 Docker 后,第一件事就是拉取這個(gè)鏡像文件,“告訴” Docker,我來(lái)了。

  Docker Hub 是存放鏡像的倉(cāng)庫(kù),里面包含了許多的鏡像文件,因?yàn)榉?wù)器在國(guó)外的原因,下載的速度可能不理想,像國(guó)內(nèi)的阿里云、騰訊云也有提供對(duì)于 Docker 鏡像的加速器服務(wù),你可以按需使用,當(dāng)然,你也可以創(chuàng)建屬于你的私有鏡像倉(cāng)庫(kù)。

  docker run 命令,它會(huì)在我們的本地鏡像庫(kù)中先尋找這個(gè)鏡像,然后運(yùn)行。如果在本地沒(méi)有找到的話,則會(huì)自動(dòng)使用 docker pull 從 Docker Hub 中尋找,能找到的話,則會(huì)自動(dòng)下載到本地,然后運(yùn)行,找不到的話,這條命令也就運(yùn)行失敗了。

  1.5、安裝 Docker Compose

  在實(shí)際的項(xiàng)目開(kāi)發(fā)中,我們可能會(huì)有多個(gè)應(yīng)用鏡像,例如在本篇文章的示例中,為了在 Docker 中運(yùn)行我們的程序,我們需要三個(gè)鏡像:應(yīng)用程序自身鏡像、MySQL Server 鏡像、以及 Nginx 鏡像,為了將我們的程序啟動(dòng)起來(lái),我們需要手敲各個(gè)容器的啟動(dòng)參數(shù),環(huán)境變量,容器命名,指定不同容器的鏈接參數(shù)等等一系列的操作,又多又煩,可能某一步操作失敗后程序就無(wú)法正常運(yùn)行。而當(dāng)我們使用了 Docker Compose 之后,我們就可以把這些命令一次性寫在 docker-compose.yml 配置文件中,以后每次啟動(dòng)我們的應(yīng)用程序時(shí),只需要通過(guò) docker compose 命令就可以自動(dòng)幫我們完成這些操作。

# 從 github 下載 docker compose 二進(jìn)制文件
sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 對(duì)下載的二進(jìn)制文件應(yīng)用可執(zhí)行權(quán)限
sudo chmod +x /usr/local/bin/docker-compose

# 查看 docker compose 版本
docker
-compose --version

  2、構(gòu)建程序鏡像

  當(dāng)我們?cè)诜?wù)器上安裝好 docker 和 docker compose 之后,就可以開(kāi)始構(gòu)建我們的程序鏡像了。首先我們需要對(duì)我們的運(yùn)行程序添加對(duì)于 Docker 的支持。你可以自己手動(dòng)在 MVC 項(xiàng)目中添加 Dockerfile 文件,或是通過(guò)右鍵添加 Docker 支持。

  Dockerfile 就像一個(gè)執(zhí)行的清單,它告訴 Docker,我們這個(gè)鏡像在構(gòu)建和運(yùn)行時(shí)需要按照什么樣的命令運(yùn)行。打開(kāi) VS 為我們自動(dòng)創(chuàng)建的 Dockerfile,可以看到清晰的分成了四塊的內(nèi)容。

  我們知道,.NET Core 程序的運(yùn)行需要依賴于 .NET Core Runtime(CoreCLR),因此,為了使我們的程序可以運(yùn)行起來(lái),我們需要從 hub 中拉取 runtime ,并在 此基礎(chǔ)上構(gòu)建我們的應(yīng)用鏡像。同時(shí),為了避免因?yàn)榛A(chǔ)的環(huán)境的不同造成對(duì)程序的影響,這里的 Runtime 需要同程序開(kāi)發(fā)時(shí)的 .NET Core SDK 版本保持一致,所以這里我使用的是 .NET Core 2.1 Runtime。

  一個(gè)鏡像中包含了應(yīng)用程序及其所有的依賴,與虛擬機(jī)不同的是,容器中的每個(gè)鏡像最終是共享了宿主機(jī)的操作系統(tǒng)資源,容器作為用戶空間中的獨(dú)立進(jìn)程運(yùn)行在主機(jī)操作系統(tǒng)上。

  PS:圖片版權(quán)歸屬于微軟的技術(shù)文檔,如有侵權(quán),請(qǐng)聯(lián)系我刪除,源文件地址:什么是 Docker?

  鏡像可以看成一個(gè)個(gè)小型的“虛擬主機(jī)”,這里我們?cè)阽R像中創(chuàng)建了一個(gè) /app 路徑作為我們程序在鏡像中的工作目錄,同時(shí),將 80 端口暴露給 Docker,從而可以使我們?cè)阽R像外面通過(guò)端口訪問(wèn)到當(dāng)前鏡像中的運(yùn)行的程序。

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

  因?yàn)槲覀兊膽?yīng)用是一個(gè)多層架構(gòu)的單體應(yīng)用,最終的 MVC 項(xiàng)目依賴于解決方案中的各個(gè)類庫(kù)以及我們從 Nuget 中下載的各種第三方組件,在部署時(shí),需要將這些組件打包成 dll 引用。所以,這里我們需要使用 .NET Core SDK 中包含的 .NET Core CLI 進(jìn)行還原和構(gòu)建。

  就像在下面的代碼中,我們?cè)阽R像的內(nèi)部創(chuàng)建了一個(gè) /src 的路徑,將當(dāng)前解決方案下的類庫(kù)都復(fù)制到這個(gè)目錄下,之后通過(guò) dotnet restore 命令還原我們的主程序所依賴的各個(gè)組件。當(dāng)我們還原好依賴的組件后,就可以使用 dotnet build 命令生成 Release版本的 dll 文件,同時(shí)輸出到之前創(chuàng)建的 /app 路徑下。

FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY ["PSU.Site/PSU.Site.csproj", "PSU.Site/"]
COPY ["03_Logic/PSU.Domain/PSU.Domain.csproj", "03_Logic/PSU.Domain/"]
COPY ["03_Logic/PSU.Repository/PSU.Repository.csproj", "03_Logic/PSU.Repository/"]
COPY ["01_Entity/PSU.Entity/PSU.Entity.csproj", "01_Entity/PSU.Entity/"]
COPY ["02_Infrastructure/PSU.Utility/PSU.Utility.csproj", "02_Infrastructure/PSU.Utility/"]
COPY ["04_Rule/PSU.Model/PSU.Model.csproj", "04_Rule/PSU.Model/"]
COPY ["02_Infrastructure/PSU.EFCore/PSU.EFCore.csproj", "02_Infrastructure/PSU.EFCore/"]
COPY ["04_Rule/PSU.IService/PSU.IService.csproj", "04_Rule/PSU.IService/"]
COPY ["Controllers.PSU/Controllers.PSU.csproj", "Controllers.PSU/"]
RUN dotnet restore "PSU.Site/PSU.Site.csproj"
COPY . .
WORKDIR "/src/PSU.Site"
RUN dotnet build "PSU.Site.csproj" -c Release -o /app

  上面一步可以看成我們?cè)谑褂?VS 生成 Release 版本的解決方案,當(dāng)生成沒(méi)有出錯(cuò)之后,我們就可以進(jìn)行程序的發(fā)布。

FROM build AS publish
RUN dotnet publish "PSU.Site.csproj" -c Release -o /app

  當(dāng)已經(jīng)生成發(fā)布文件之后,按照我們平時(shí)部署在 Windows 上的過(guò)程,這時(shí)就可以通過(guò) IIS 部署運(yùn)行了,因此,構(gòu)建我們應(yīng)用鏡像的最后一步就是通過(guò) dotnet 命令執(zhí)行我們的程序。

FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "PSU.Site.dll"]

  似乎到這一步構(gòu)建程序鏡像就結(jié)束了,按照這樣流程做的話,就需要我們將整個(gè)的解決方案上傳到服務(wù)器上了,可是,很多時(shí)候,我們僅僅是把我們?cè)诒镜匕l(fā)布好的項(xiàng)目上傳到服務(wù)器上,這與我們現(xiàn)在的構(gòu)建流程具有很大的不同,所以這里我們來(lái)修改 Dockerfile 文件,從而符合我們的發(fā)布流程。

  從上面分析 Dockerfile 的過(guò)程中不難看出,在服務(wù)器上構(gòu)建鏡像的第二步、第三步就是我們現(xiàn)在在開(kāi)發(fā)環(huán)境中手動(dòng)完成的部分,所以這里,我們只需要對(duì)這部分進(jìn)行刪除即可,修改后的 Dockerfile 如下。

FROM microsoft/dotnet:2.1-aspnetcore-runtime
WORKDIR /app
COPY . /app
EXPOSE 80
ENTRYPOINT ["dotnet","PSU.Site.dll"]

  在修改后的 Dockerfile 中,可以看到,我們刪去了 build 和 release 的過(guò)程,選擇直接將我們 Dockerfile 路徑下的文件拷貝到鏡像中的 /app 路徑下,然后直接執(zhí)行 dotnet 命令,運(yùn)行我們的程序。

  為了確保 Dockerfile 與發(fā)布后的文件處于同一路徑下,這里我們需要使用 VS 修改 Dockerfile 的屬性值,確保會(huì)復(fù)制到輸出的目錄下,這里選擇如果較新則復(fù)制即可。

  3、編寫 docker-compose.yml

  當(dāng)我們構(gòu)建好應(yīng)用的鏡像,對(duì)于 Nginx 和 MySQL 我們完全可以從 hub 中拉取下來(lái),再執(zhí)行一些配置即可。所以,我們現(xiàn)在就可以編寫 docker compose 文件,來(lái)定義我們的應(yīng)用鏡像運(yùn)行時(shí)需要包含的依賴以及每個(gè)鏡像的啟動(dòng)順序。

  右鍵選中 MVC 項(xiàng)目,添加一個(gè) docker-compose.yml 文件,同樣的,需要修改該文件的屬性,以便于該文件可以復(fù)制到輸出目錄下。注意,這里的文件名和上文的 Dockerfile 都是特定的,你不能做任何的修改。如果你的電腦上已經(jīng)安裝了 Docker for Windows,你也可以使用 VS,右鍵添加,選中容器業(yè)務(wù)流程協(xié)調(diào)程序支持自動(dòng)對(duì) docker compose 進(jìn)行配置。

  在 yml 文件中,我定義了三個(gè)鏡像:psu.site、docker.mysql、docker.nginx。三個(gè)鏡像的定義中有許多相同的地方,都設(shè)置了自動(dòng)重啟(restart),以及都處于同一個(gè)橋接網(wǎng)絡(luò)下(psu-net)從而達(dá)到鏡像間的通信。

  docker.mysql 是 MySQL 的鏡像,我們通過(guò)環(huán)境變量 MYSQL_ROOT_PASSWORD 設(shè)置了 MySQL 的數(shù)據(jù)庫(kù)連接密碼,并通過(guò)掛載卷的方式將鏡像中的數(shù)據(jù)庫(kù)文件持久化到我們的服務(wù)器本地路徑中。同時(shí),將鏡像的 3306 端口映射到服務(wù)器的 3306 端口上。

  psu.site 則是我們的程序鏡像,采用位于 /usr/wwwroot/psu/ 路徑下的 Dockerfile 文件進(jìn)行構(gòu)建的,因?yàn)橹鞒绦虻倪\(yùn)行需要依賴于數(shù)據(jù)庫(kù),所以這里采用 depends_on 屬性,使我們的應(yīng)用鏡像依賴于 docker.mysql 鏡像,即,在 docker.mysql 啟動(dòng)后才會(huì)啟動(dòng)應(yīng)用鏡像。

  docker.nginx 則是我們的 nginx 鏡像,這里將鏡像中的 80 端口和 443 端口都映射到服務(wù)器 IP 上,因?yàn)槲覀冃枰渲?Nginx 從而監(jiān)聽(tīng)我們的程序,所以通過(guò)掛載卷的方式,將本地的 nginx.conf 配置文件用配置映射到鏡像中。同時(shí),因?yàn)槲覀冊(cè)跇?gòu)建應(yīng)用鏡像的 Dockerfile 文件時(shí),對(duì)外暴露了 80 端口,所以這里就可以通過(guò) links 屬性進(jìn)行監(jiān)聽(tīng)(如果構(gòu)建時(shí)未暴露端口,你可以在 docker compose 文件中通過(guò) Expose 屬性暴露鏡像中的端口)。

  Nginx 的配置文件如下,這里特別需要注意文件的格式,縮進(jìn),一點(diǎn)小錯(cuò)誤都可能導(dǎo)致鏡像無(wú)法正常運(yùn)行。如果你和我一樣將 nginx.conf 放到程序運(yùn)行路徑下的,別忘了修改文件的屬性。

server {
listen 80;

location / {
proxy_pass http://psu.site;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $http_host;
proxy_cache_bypass $http_upgrade;
}
}

  一個(gè)完整的 docker compose 文件如下,包含了三個(gè)鏡像以及一個(gè)橋接網(wǎng)絡(luò)。

version: '3.7'

services:
docker.mysql:
image: mysql
ports:
- "3306:3306"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=123456@sql
volumes:
- /usr/mysql:/var/lib/mysql
networks:
- psu-net

psu.site:
build: /usr/wwwroot/psu/
restart: always
depends_on:
- docker.mysql
networks:
- psu-net

docker.nginx:
image: nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
links:
- psu.site
networks:
- psu-net

networks:
psu-net:
driver: bridge

  這里需要注意,所有有用到鏡像間的通信的地方,我們都需要使用鏡像名進(jìn)行指代,例如上面的 nginx 的配置文件中,我們需要將監(jiān)聽(tīng)的地址改為鏡像名稱,以及,我們需要修改程序的數(shù)據(jù)庫(kù)訪問(wèn)字符串的服務(wù)器地址,修改后的數(shù)據(jù)庫(kù)連接字符串如下所示。

"ConnectionStrings": {
"SQLConnection": "server=docker.mysql;database=PSU.Site;user=root;password=123456@sql;port=3306;persistsecurityinfo=True;"
}

  4、發(fā)布部署程序

  當(dāng)我們構(gòu)建好 docker compose 文件后就可以把整個(gè)文件上傳到服務(wù)器上進(jìn)行構(gòu)建 docker 鏡像了。這里我將所有的部署文件放在服務(wù)器的 /usr/wwwroot/psu/ 路徑下,這時(shí)我們就可以通過(guò) docker compose 命令進(jìn)行鏡像構(gòu)建。

  定位到部署文件在的位置,我們可以直接使用下面的命令進(jìn)行鏡像的(重新)構(gòu)建,啟動(dòng),并鏈接一個(gè)服務(wù)相關(guān)的容器,整個(gè)過(guò)程都會(huì)在后臺(tái)運(yùn)行,如果你希望看到整個(gè)過(guò)程的話,你可以去掉 -d 參數(shù)。

# 執(zhí)行鏡像構(gòu)建,啟動(dòng)
docker-compose up -d

  當(dāng) up 命令執(zhí)行完成后,我們就可以通過(guò) ps 命令查看正在運(yùn)行的容器,若有的容器并沒(méi)有運(yùn)行起來(lái),則可以使用 logs 查看容器的運(yùn)行日志從而進(jìn)行排錯(cuò)。

# 查看所有正在運(yùn)行的容器
docker-compose ps

# 顯示容器運(yùn)行日志
docker-compose logs

?三、總結(jié)

?  ?本章主要是介紹了如何通過(guò) docker 容器,完整的部署一個(gè)可實(shí)際使用的 .NET Core 的單體應(yīng)用,相比于之前通過(guò) Linux 部署 .NET Core 應(yīng)用,可以看到整個(gè)步驟少了很多,也簡(jiǎn)單很多。文中涉及到了一些 docker 的命令,如果你之前并沒(méi)有接觸過(guò) docker 的話,可能需要你進(jìn)一步的了解。當(dāng)我們將程序打包成一個(gè)鏡像之后,你完全可以將鏡像上傳到私有鏡像倉(cāng)庫(kù)中,或是直接打包成鏡像的壓縮文件,這樣,當(dāng)需要切換部署環(huán)境時(shí),只需要獲取到這個(gè)鏡像之后即可快速完成部署,相比之前,極大的方便了我們的工作。


總結(jié)

以上是生活随笔為你收集整理的ASP.NET Core 实战:使用 Docker 容器化部署 ASP.NET Core + MySQL + Nginx的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。