NET Core+MySql+Nginx 容器化部署
1. 引言
上兩節我們通過簡單的demo
學習了docker
的基本操作。這一節我們來一個進階學習,完成ASP.NET Core + MySql + Nginx
的容器化部署。
本文是基於CentOS 7.4
環境進行演示,示例專案可以訪問Docker.NetCore.MySql進行下載。
2. Hello MySQL
同樣我們還是以循序漸進的方式來展開。首先來基於Docker
來試玩一下MySQL
。
2.1. 建立MySql
例項
//拉取mysql映象
docker pull mysql
$ docker images$
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/mysql latest 7d83a47ab2d2 13 days ago 408.2 MB
//建立一個mysql例項
$ docker run --name hello.mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e21bbd84e0b5 mysql "docker-entrypoint.sh" 3 minutes ago Up 3 minutes 3306/tcp hello.mysql
下面我們直接在容器中連線到我們剛剛建立的mysql
資料庫:
$ docker exec -it hello.mysql \
> mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.20 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
2.2. 掛載資料卷
上面建立的mysql
例項其資料都在容器內部儲存,這樣就暴露了一個問題,如果容器銷燬,那麼對應的資料庫資料就會丟失。那如何持久化儲存容器內資料呢?我們可以通過掛載資料卷的方式來解決這一問題。
//建立資料卷
$ docker volume create --name hello.db
hello.db
//檢視資料卷資訊
$ docker volume inspect hello.db
[
{
"Name": "hello.db",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/hello.db/_data",
"Labels": {},
"Scope": "local"
}
]
// 掛載資料卷啟動MySql例項
$ docker run --name hello.mysql \
> -v hello.db:/var/lib/mysql \
> -e MYSQL_ROOT_PASSWORD=123456 -d mysql
上面是使用使用了docker volume create
命令建立了一個資料卷,當然我們也可以自行掛載某個目錄作為資料卷。
3. 準備.NET Core+EFCore+MySql專案
為了演示方便,我準備了一個ASP.NET Core+EFCore+MySql
的示例專案。其結構如下所示:
是基於.NET Core Mvc
模板專案,其中定義了一個Product
實體,並通過ProductsController
暴露WebApi
介面。核心程式碼如下:
Product
實體類:
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public int StockQty { get; set; }
}
DbContext
類:
public class MySqlDbContext : DbContext
{
public MySqlDbContext (DbContextOptions<MySqlDbContext> options)
: base(options)
{
}
public DbSet<Product> Products { get; set; }
}
資料庫初始化類:
public class DbInitializer
{
public static void Initialize(MySqlDbContext context)
{
context.Database.EnsureCreated();
if (context.Products.Any())
{
return;
}
var products = new Product[]
{
new Product{Name="iphone 6",Price=5000,StockQty=10 },
new Product{Name="iphone 7",Price=6000,StockQty=10 },
new Product{Name="iphone 7 plus",Price=7000,StockQty=10 },
new Product{Name="iphone x",Price=8000,StockQty=10 }
};
context.Products.AddRange(products);
context.SaveChanges();
}
}
該資料庫初始化類會在專案啟動時執行。詳細程式碼可參考Docker.NetCore.MySql
。
4. 基於示例專案進行實操演練
4.1 安裝Git
並Clone
示例專案
$ yum install git
$ git --version
git version 1.8.3.1
$ cd ~/demo
$ git clone https://github.com/yanshengjie/Docker.NetCore.MySql.git
Cloning into 'Docker.NetCore.MySql'...
remote: Counting objects: 155, done.
remote: Compressing objects: 100% (125/125), done.
remote: Total 155 (delta 42), reused 123 (delta 25), pack-reused 0
Receiving objects: 100% (155/155), 534.30 KiB | 333.00 KiB/s, done.
Resolving deltas: 100% (42/42), done.
4.2. 構建映象
細心的你會發現,專案中已經定義了Dockerfile
,所以我們可以直接使用docker build
構建映象。
# cd Docker.NetCore.MySql
[root@iZ288a3qazlZ Docker.NetCore.MySql]# ls
appsettings.Development.json docker-compose.yml Program.cs Views
appsettings.json Dockerfile proxy.conf wwwroot
bundleconfig.json Docker.NetCore.MySql.csproj README.md
Controllers LICENSE ScaffoldingReadMe.txt
Data Models Startup.cs
//構建映象
# docker build -t docker.netcore.mysql .
Sending build context to Docker daemon 3.045 MB
Step 1 : FROM microsoft/dotnet:latest
---> 7d4dc5c258eb
Step 2 : WORKDIR /app
---> Using cache
---> 98d48a4e278c
Step 3 : COPY . /app
---> 6b1bf8bb5261
Removing intermediate container b86460477977
Step 4 : RUN dotnet restore
---> Running in 4e0a46f762bb
Restoring packages for /app/Docker.NetCore.MySql.csproj...
Installing Microsoft.CodeAnalysis.Razor 2.0.0.
.....
Restore completed in 216.83 ms for /app/Docker.NetCore.MySql.csproj.
---> 4df70c77916e
Removing intermediate container 4e0a46f762bb
Step 5 : EXPOSE 5000
---> Running in 11b421b3bd3e
---> 3506253060fe
Removing intermediate container 11b421b3bd3e
Step 6 : ENV ASPNETCORE_URLS http://*:5000
---> Running in 201aabbab72c
---> 7f29963a8d96
Removing intermediate container 201aabbab72c
Step 7 : ENTRYPOINT dotnet run
---> Running in c79f73cba162
---> 9d1fb6ee46cb
Removing intermediate container c79f73cba162
Successfully built 9d1fb6ee46cb
[root@iZ288a3qazlZ Docker.NetCore.MySql]# docker images docker.netcore.mysql
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.netcore.mysql latest 9d1fb6ee46cb 13 seconds ago 1.756 GB
4.3. 啟動映象並連線到指定資料庫
docker
提供了--link
引數用於在容器之間建立連線。下面我們例項化建立的映象docker.netcore.mysql
並命名容器名為hello.netcore.mysql
,並使用--link
引數與我們文章開頭建立的hello.mysql
容器建立連線。
# docker run --name hello.netcore.mysql --link hello.mysql:db -d -p 5000:5000
docker.netcore.mysql
這裡需要特別注意一下
--link=hello.mysql:db
,這個引數就是告訴Docker
容器需要使用hello.mysql
容器,並將其別名命名為db
,這樣在hello.netcore.mysql
這個容器中就可以使用db來作為提供mysql資料庫服務的伺服器。這也就是為什麼我們.NET Core
專案中連線字串設定為server=db;
的原因。
"ConnectionStrings": { "MySql": "server=db;database=MySqlDbContext;uid=root;pwd=123456;" }
//檢視執行中容器列表
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5cbfd27ebe2a docker.netcore.mysql "dotnet run" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp hello.netcore.mysql
4dfa4159b669 mysql "docker-entrypoint.sh" About an hour ago Up About an hour 3306/tcp hello.mysql
//訪問api/products
[root@iZ288a3qazlZ Docker.NetCore.MySql]# curl http://localhost:5000/api/products
[{"productId":1,"name":"iphone 6","price":5000.0000000000000000000000000,"stockQty":10},{"productId":2,"name":"iphone 7","price":6000.0000000000000000000000000,"stockQty":10},{"productId":3,"name":"iphone 7 plus","price":7000.0000000000000000000000000,"stockQty":10},{"productId":4,"name":"iphone x","price":8000.000000000000000000000000,"stockQty":10}]
從上圖可知,我們完成了.NET Core
與MySql
的連線。
5. ASP.NET Core + MySql + Nginx
結合上一篇文章.NET Core
容器化之多容器應用部署@Docker-Compose,我們來使用docker-compose
完成asp.net core + mysql + nginx
的多容器部署。
5.1. 定義 docker-compose.yml
version: '2'
services:
db:
container_name: hello.db
environment:
MYSQL_ROOT_PASSWORD: 123456
volumes:
- ./mysql:/var/lib/mysql
web:
container_name: hello.web
build: .
depends_on:
- db
links:
- db
reverse-proxy:
container_name: hello.proxy
image: nginx
depends_on:
- web
ports:
- "9090:8080"
volumes:
- ./proxy.conf:/etc/nginx/conf.d/default.conf
其中定義了三個服務:
db
:使用mysql
映象,並掛載當前專案下的mysql
資料夾來持久化儲存。web
:基於當前專案構建的容器服務,依賴於db
服務。reverse-proxy
:使用nginx
定義反向代理服務,其中掛載了當前專案下的proxy.conf
檔案作為反向代理配置檔案。其中proxy.conf
的配置如下(注意proxy_pass
指定的url
為http://web:5000
):
server {
listen 8080;
location / {
proxy_pass http://web:5000;
}
}
5.2. 啟動Compose
在啟動Compose
之前,建議清空上面建立的容器。也可以使用docker rm $(docker ps -qa)
清除所有容器。
//啟動compose
[root@iZ288a3qazlZ Docker.NetCore.MySql]# docker-compose up -d
Creating network "dockernetcoremysql_default" with the default driver
Building web
Step 1 : FROM microsoft/dotnet:latest
---> 7d4dc5c258eb
Step 2 : WORKDIR /app
---> Using cache
---> 98d48a4e278c
Step 3 : COPY . /app
---> d41b32323c0f
Removing intermediate container 1259f5fb82bc
Step 4 : RUN dotnet restore
---> Running in d482e355de77
Restoring packages for /app/Docker.NetCore.MySql.csproj...
Installing Microsoft.CodeAnalysis.Razor 2.0.0.
.....
Restore completed in 216.83 ms for /app/Docker.NetCore.MySql.csproj.
---> a0658008f161
Removing intermediate container d482e355de77
Step 5 : EXPOSE 5000
---> Running in dc6eeb29fd5e
---> a419314ece08
Removing intermediate container dc6eeb29fd5e
Step 6 : ENV ASPNETCORE_URLS http://*:5000
---> Running in c1d1474b14a0
---> 9cc13c549042
Removing intermediate container c1d1474b14a0
Step 7 : ENTRYPOINT dotnet run
---> Running in efdf0e857a84
---> 830ac11428cf
Removing intermediate container efdf0e857a84
Successfully built 830ac11428cf
Creating hello.db ... done
Creating hello.web ... done
Creating hello.proxy ... done
Creating hello.web ...
Creating hello.proxy ...
[root@iZ288a3qazlZ Docker.NetCore.MySql]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6253bf85682e nginx "nginx -g 'daemon off" 33 seconds ago Up 28 seconds 80/tcp, 0.0.0.0:9090->8080/tcp hello.proxy
ea553a9e22f2 dockernetcoremysql_web "dotnet run" 37 seconds ago Up 32 seconds 5000/tcp hello.web
a1f5aa981bfb mysql "docker-entrypoint.sh" 38 seconds ago Up 36 seconds 3306/tcp hello.db
[root@iZ288a3qazlZ Docker.NetCore.MySql]# docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------
hello.db docker-entrypoint.sh mysqld Up 3306/tcp
hello.proxy nginx -g daemon off; Up 80/tcp, 0.0.0.0:9090->8080/tcp
hello.web dotnet run Up 5000/tcp
[root@iZ288a3qazlZ Docker.NetCore.MySql]# curl http://localhost:9090/api/products
[{"productId":1,"name":"iphone 6","price":5000.0000000000000000000000000,"stockQty":10},{"productId":2,"name":"iphone 7","price":6000.0000000000000000000000000,"stockQty":10},{"productId":3,"name":"iphone 7 plus","price":7000.0000000000000000000000000,"stockQty":10},{"productId":4,"name":"iphone x","price":8000.000000000000000000000000,"stockQty":10}]
上面的執行結果顯示,我們已經成功完成了ASP.NET Core+MySql+Nginx
的多容器應用部署。通過瀏覽器訪問http:<ipaddress>:9090/api/products
即可訪問我們暴露的api
。
5.3. 資料庫驗證
我們來驗證一下資料庫是否成功建立:
[root@iZ288a3qazlZ Docker.NetCore.MySql]# ls mysql
auto.cnf client-key.pem ib_logfile0 performance_schema server-key.pem
ca-key.pem MySqlDbContext ib_logfile1 private_key.pem sys
ca.pem ib_buffer_pool ibtmp1 public_key.pem
client-cert.pem ibdata1 mysql server-cert.pem
[root@iZ288a3qazlZ Docker.NetCore.MySql]# docker exec -it hello.db mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.20 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+-----------------------+
| Database |
+-----------------------+
| information_schema |
| MySqlDbContext |
| mysql |
| performance_schema |
| sys |
+-----------------------+
5 rows in set (0.00 sec)
mysql> use MySqlDbContext;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+---------------------------------+
| Tables_in_MySqlDbContext |
+---------------------------------+
| Products |
+---------------------------------+
1 row in set (0.00 sec)
mysql> select * from Products;
+-----------+---------------+-------------------------------------+----------+
| ProductId | Name | Price | StockQty |
+-----------+---------------+-------------------------------------+----------+
| 1 | iphone 6 | 5000.000000000000000000000000000000 | 10 |
| 2 | iphone 7 | 6000.000000000000000000000000000000 | 10 |
| 3 | iphone 7 plus | 7000.000000000000000000000000000000 | 10 |
| 4 | iphone x | 8000.000000000000000000000000000000 | 10 |
+-----------+---------------+-------------------------------------+----------+
4 rows in set (0.00 sec)
從上面的執行結果可知,我們成功將專案資料夾下的mysql
資料夾掛載到容器內部進行資料持久化。
6. 最後
本文通過先介紹如何基於Docker
例項化MySQL
容器,再介紹如何通過掛載資料捲來持久化MySQL
資料,以及如何使用--Link
引數進行容器之間的連線,完成了.NET Core
連線MySQL
資料庫。
最後,使用Docker-Compose
綜合ASP.NET Core+MySQL+Nginx
完成了容器化部署。
下一節我們來介紹下如何使用Docker-Swarm
進行叢集部署。
相關文章
- .NET Core+MySql+Nginx 容器化部署MySqlNginx
- .NET Core容器化之多容器應用部署(Docker-Compose)Docker
- .NET Core容器化之多容器應用部署@Docker-ComposeDocker
- 容器化 | 在 Kubernetes 上部署 RadonDB MySQL 叢集MySql
- Asp.Net Core Blazor之容器部署ASP.NETBlazor
- .NET Core容器化(Docker)Docker
- .NET Core容器化@DockerDocker
- docker容器化.NET程式Docker
- 如何快速部署容器化應用
- 容器化部署實踐之Django應用部署(二)Django
- Docker容器化部署Python應用DockerPython
- 容器化部署GVM掃漏系統
- Docker容器化部署嘗試——多容器通訊(node + mongoDB + nginx)DockerMongoDBNginx
- 給小白的 PG 容器化部署教程(下)
- 給小白的 PostgreSQL 容器化部署教程(上)SQL
- 容器化 | 在 KubeSphere 中部署 MySQL 叢集MySql
- Vue.js應用程式容器化部署Vue.js
- 使用Docker容器化部署實踐之Django應用部署(一)DockerDjango
- Docker容器與虛擬化技術:OpenEuler 部署 docker容器應用Docker
- Nginx反向代理負載均衡的容器化部署Nginx負載
- .NET網站自動化部署網站
- Ubuntu_amd64容器化部署chromedriver的過程UbuntuChrome
- Taiga容器部署AI
- Kubernetes 部署 PHP-fpm 與 nginx 多容器應用PHPNginx
- docker4dotnet #2 容器化主機Docker
- 自動化整合:Kubernetes容器引擎詳解
- 容器化|自建 MySQL 叢集遷移到 KubernetesMySql
- K8s微服務自動化部署容器(Rancher流水線)K8S微服務
- 容器化部署目前最新版本的Elasticsearch--8.15.1Elasticsearch
- 利用Kubernetes實現容器的持久化儲存持久化
- Docker容器學習梳理 - 應用程式容器環境部署Docker
- 淺談surging服務引擎中的rabbitmq元件和容器化部署MQ元件
- BI系統打包Docker映象及容器化部署的具體實現Docker
- Jenkins + Docker + ASP.NET Core自動化部署JenkinsDockerASP.NET
- 使用Portainer部署Docker容器實踐AIDocker
- 談談surging引擎的tcp、http、ws協議和如何容器化部署TCPHTTP協議
- 容器化 | 在 K8s 上部署 RadonDB MySQL Operator 和叢集K8SMySql
- Gogs+Jenkins+Docker 自動化部署.NetCoreGoJenkinsDockerNetCore