mkdir /home/console cd /home/console dotnet new console dotnet restore
vim /home/console/Dockerfile # ------ FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /app COPY . /app RUN dotnet run
構建鏡像mysql
docker build -t wyt/console:dev .
dotnet run --name console-dev wyt/console
mkdir /home/console cd /home/console dotnet new console dotnet restore
using System; using System.Threading; namespace console { class Program { static void Main(string[] args) { Console.WriteLine("Hello World from docker!"); Thread.Sleep(Timeout.Infinite); } } }
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /code COPY *.csproj /code RUN dotnet restore COPY . /code RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime WORKDIR /app COPY --from=build /code/out /app ENTRYPOINT ["dotnet", "console.dll"]
docker build -t wyt/console:prod .
docker run --name=console-prod wyt/console:prod
docker images REPOSITORY TAG IMAGE ID CREATED SIZE wyt/console prod d2c683338197 3 minutes ago 260MB wyt/console dev 93b346366bc5 20 minutes ago 1.74GB mcr.microsoft.com/dotnet/core/sdk 2.2 155911c343f3 11 days ago 1.74GB mcr.microsoft.com/dotnet/core/aspnet 2.2 c56aab97bc42 11 days ago 260MB
Install-Package MySql.Data.EntityFrameworkCore
namespace User.API.Models { public class AppUser { public int Id { get; set; } public string Name { get; set; } public string Company { get; set; } public string Title { get; set; } } }
新建 UserContext.cs git
namespace User.API.Data { public class UserContext:DbContext { public UserContext(DbContextOptions<UserContext> options) : base(options) { } public DbSet<AppUser> Users { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<AppUser>().ToTable(nameof(Users)).HasKey(t => t.Id); base.OnModelCreating(modelBuilder); } } }
namespace User.API { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext<UserContext>(options => { options.UseMySQL(Configuration.GetConnectionString("MysqlUser")); }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); InitDatabase(app); } public void InitDatabase(IApplicationBuilder app) { using (var scope=app.ApplicationServices.CreateScope()) { var userContext = scope.ServiceProvider.GetRequiredService<UserContext>(); //userContext.Database.Migrate(); if (userContext.Users.Count()==0) { userContext.Users.Add(new AppUser() { Name = "wyt" }); userContext.SaveChanges(); } } } } }
"ConnectionStrings": { "MysqlUser": "Server=192.168.103.240;Port=3306;Database=beta_user;Uid=root;Pwd=pwd123456" }
生成數據庫github
Add-Migration init
Update-Database
namespace User.API.Controllers { [Route("api/[controller]")] [ApiController] public class ValuesController : Controller { private UserContext _userContext; public ValuesController(UserContext userContext) { _userContext = userContext; } // GET api/values [HttpGet] public async Task<IActionResult> Get() { return Json(await _userContext.Users.FirstOrDefaultAsync(u => u.Name == "wyt")); } } }
訪問apiweb
//appsettings.json { "Logging": { "LogLevel": { "Default": "Warning" } }, "AllowedHosts": "*", "ConnectionStrings": { "MysqlUser": "Server=db;Port=3306;Database=beta_user;Uid=root;Pwd=pwd123456" } } //appsettings.Development.json { "Logging": { "LogLevel": { "Default": "Debug", "System": "Information", "Microsoft": "Information" } }, "ConnectionStrings": { "MysqlUser": "Server=47.111.84.191;Port=3306;Database=beta_user;Uid=root;Pwd=pwd123456" } }
修改 Program.cs 設置80端口sql
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseUrls("http://*:80") .UseStartup<Startup>();
建立 Dockerfile docker
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build WORKDIR /code COPY *.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o out FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime WORKDIR /app COPY --from=build /code/out ./ EXPOSE 80 ENTRYPOINT ["dotnet", "User.API.dll"]
拷貝到Linux服務器上,並執行下方命令建立鏡像數據庫
docker build -t wyt/aspnetcore:pred .
[root@localhost User.API]# docker build -t wyt/aspnetcore:pred . Sending build context to Docker daemon 1.265MB Step 1/11 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build ---> 155911c343f3 Step 2/11 : WORKDIR /code ---> Using cache ---> 3e2cb7223b3b Step 3/11 : COPY *.csproj ./ ---> 6f6d88b83c75 Step 4/11 : RUN dotnet restore ---> Running in c538c0a59636 Restore completed in 3.85 sec for /code/User.API.csproj. Removing intermediate container c538c0a59636 ---> 6e45bd786a9c Step 5/11 : COPY . ./ ---> 50ac66ac3f97 Step 6/11 : RUN dotnet publish -c Release -o out ---> Running in 9febf9972a3d Microsoft (R) Build Engine version 16.1.76+g14b0a930a7 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 667.65 ms for /code/User.API.csproj. User.API -> /code/bin/Release/netcoreapp2.2/User.API.dll User.API -> /code/out/ Removing intermediate container 9febf9972a3d ---> a7c92c3fd98b Step 7/11 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ---> c56aab97bc42 Step 8/11 : WORKDIR /app ---> Using cache ---> 12d1df98dc50 Step 9/11 : COPY --from=build /code/out ./ ---> Using cache ---> b901e53b64f8 Step 10/11 : EXPOSE 80 ---> Using cache ---> c61ad551fa76 Step 11/11 : ENTRYPOINT ["dotnet", "User.API.dll"] ---> Running in 36c66859c548 Removing intermediate container 36c66859c548 ---> 063fc4fe64ed Successfully built 063fc4fe64ed Successfully tagged wyt/aspnetcore:pred
運行容器,進行端口映射和容器關聯json
docker run -d -p 8002:80 --name aspnetcore --link mysql01:db wyt/aspnetcore:pred
成功訪問 vim
# 建立mybridge橋接網段 docker network create -d bridge mybridge # 顯示網絡信息 docker network ls
# 刪除以前建立的容器 docker rm aspnetcore -f # 使用mybridge橋接網段建立新的容器 docker run -d -p 8002:80 --net mybridge --name aspnetcore wyt/aspnetcore:pred
docker inspect aspnetcore
# 將mybridge網段與mysql01所在網段進行橋接
docker network connect mybridge mysql01
這時能夠查看 mysql01 的ip,而後進入 aspnetcore 容器內嘗試是否能夠ping通api
docker exec -it aspnetcore bash apt-get update -y apt-get install iputils-ping -y apt-get install net-tools -y ping 172.18.0.3
因爲咱們沒有進行數據卷映射,因此配置文件沒法更改,備註: appsettings.json 中使用的數據庫爲db,因此咱們只能將 mysql01 改成 db
# 容器重命名
docker rename mysql01 db
方法二
# 進入容器 docker exec -it aspnetcore bash ls apt-get install vim -y # 修改配置 vim appsettings.json exit # 重啓容器 docker restart aspnetcore
curl http://47.111.84.191:8002/api/values
或者訪問
# Startup.cs public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseMvc(); UserContextSeed.SeedAsync(app,loggerFactory); } # /Data/UserContextSeed.cs public class UserContextSeed { private ILogger<UserContextSeed> _logger; public UserContextSeed(ILogger<UserContextSeed> logger) { _logger = logger; } public static async Task SeedAsync(IApplicationBuilder app, ILoggerFactory loggerFactory) { using (var scope = app.ApplicationServices.CreateScope()) { var userContext = scope.ServiceProvider.GetRequiredService<UserContext>(); var logger = (ILogger<UserContextSeed>)scope.ServiceProvider.GetService(typeof(ILogger<UserContextSeed>)); logger.LogDebug("Begin UserContextSeed SeedAsync"); userContext.Database.Migrate(); if (userContext.Users.Count() == 0) { userContext.Users.Add(new AppUser() { Name = "wyt" }); userContext.SaveChanges(); } } } }
# 下載Docker Compose的當前穩定版本 sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # https://github.com/docker/compose/releases/download/1.24.1/docker-compose-Linux-x86_64 # 建議迅雷下載後進行重命名,這樣速度快 # 對二進制文件應用可執行權限 sudo chmod +x /usr/local/bin/docker-compose # 測試安裝 docker-compose --version
version: '3' services: db: image: mysql/mysql-server container_name: db command: mysqld --character-set-server=utf8 --collation-server=utf8_general_ci restart: always ports: - '3306:3306' #host物理直接映射端口爲3306 environment: MYSQL_ROOT_PASSWORD: pwd123456 #root管理員用戶密碼 MYSQL_USER: jeese #建立jeese用戶 MYSQL_PASSWORD: pwd123456 #設置jeese用戶的密碼 MYSQL_ROOT_HOST: '%' volumes: - "/home/wyt/beta/mysql-init:/docker-entrypoint-initdb.d" #設置數據庫自動執行腳本目錄,目錄要存在 web: build: . container_name: aspnetcore ports: - '8003:80' #host物理直接映射端口爲3306 depends_on: - db
# 初始化腳本mysql-init/init.sql use mysql; ALTER USER 'jeese'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123456'; ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd123456'; FLUSH PRIVILEGES;
docker-compose構建
docker-compose build
[root@localhost User.API]# docker-compose build db uses an image, skipping Building web Step 1/11 : FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build ---> 155911c343f3 Step 2/11 : WORKDIR /code ---> Using cache ---> 7525de38c042 Step 3/11 : COPY *.csproj ./ ---> Using cache ---> 397affedf1a6 Step 4/11 : RUN dotnet restore ---> Using cache ---> 964ce7a0de36 Step 5/11 : COPY . ./ ---> Using cache ---> 5d18774ff1df Step 6/11 : RUN dotnet publish -c Release -o out ---> Using cache ---> 3353849a8dd8 Step 7/11 : FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS runtime ---> c56aab97bc42 Step 8/11 : WORKDIR /app ---> Using cache ---> 12d1df98dc50 Step 9/11 : COPY --from=build /code/out ./ ---> Using cache ---> 4e6819b010fe Step 10/11 : EXPOSE 80 ---> Using cache ---> 2ee374887860 Step 11/11 : ENTRYPOINT ["dotnet", "User.API.dll"] ---> Using cache ---> 2b06acc1b707 Successfully built 2b06acc1b707 Successfully tagged userapi_web:latest
docker-compose up
[root@localhost User.API]# docker-compose up Creating network "userapi_default" with the default driver Creating db ... done Creating aspnetcore ... done Attaching to db, aspnetcore db | [Entrypoint] MySQL Docker Image 8.0.16-1.1.11 db | [Entrypoint] Initializing database aspnetcore | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] aspnetcore | No XML encryptor configured. Key {67f35cc4-a4c3-4224-ba07-7a0753ed0d09} may be persisted to storage in unencrypted form. aspnetcore | Hosting environment: Production aspnetcore | Content root path: /app aspnetcore | Now listening on: http://[::]:80 aspnetcore | Application started. Press Ctrl+C to shut down. db | 2019-07-05T09:27:43.358708Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server in progress as process 20 db | 2019-07-05T09:27:43.360043Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. db | 2019-07-05T09:27:43.360052Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead. db | 2019-07-05T09:27:46.943704Z 5 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option. db | 2019-07-05T09:27:48.131450Z 0 [System] [MY-013170] [Server] /usr/sbin/mysqld (mysqld 8.0.16) initializing of server has completed db | [Entrypoint] Database initialized db | 2019-07-05T09:27:49.902213Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting as process 66 db | 2019-07-05T09:27:49.903376Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. db | 2019-07-05T09:27:49.903389Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead. db | 2019-07-05T09:27:50.456492Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. db | 2019-07-05T09:27:50.477501Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.16' socket: '/var/lib/mysql/mysql.sock' port: 0 MySQL Community Server - GPL. db | 2019-07-05T09:27:50.558190Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' db | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it. db | Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it. db | Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it. db | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it. db | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it. db | db | [Entrypoint] running /docker-entrypoint-initdb.d/init.sql db | db | db | 2019-07-05T09:27:52.092496Z 12 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.16). db | 2019-07-05T09:27:54.191280Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.16) MySQL Community Server - GPL. db | [Entrypoint] Server shut down db | db | [Entrypoint] MySQL init process done. Ready for start up. db | db | [Entrypoint] Starting MySQL 8.0.16-1.1.11 db | 2019-07-05T09:27:55.417600Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.16) starting as process 1 db | 2019-07-05T09:27:55.419490Z 0 [Warning] [MY-013242] [Server] --character-set-server: 'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous. db | 2019-07-05T09:27:55.419504Z 0 [Warning] [MY-013244] [Server] --collation-server: 'utf8_general_ci' is a collation of the deprecated character set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation instead. db | 2019-07-05T09:27:55.858661Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed. db | 2019-07-05T09:27:55.880107Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.16' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server - GPL. db | 2019-07-05T09:27:56.066024Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: '/var/run/mysqld/mysqlx.sock' bind-address: '::' port: 33060 aspnetcore | Application is shutting down... aspnetcore exited with code 0 aspnetcore | Hosting environment: Production aspnetcore | Content root path: /app aspnetcore | Now listening on: http://[::]:80 aspnetcore | Application started. Press Ctrl+C to shut down.
# 中止docker-compose
# docker-compose down
啓動問題解決方式:因爲docker-compose.yml文件中存在db依賴,因此要修改/Data/UserContextSeed.cs進行延遲數據庫自動初始化
public static async Task SeedAsync(IApplicationBuilder app, ILoggerFactory loggerFactory,int? retry=0) { var retryForAvaiability = retry.Value; try { using (var scope = app.ApplicationServices.CreateScope()) { var userContext = scope.ServiceProvider.GetRequiredService<UserContext>(); var logger = (ILogger<UserContextSeed>)scope.ServiceProvider.GetService(typeof(ILogger<UserContextSeed>)); logger.LogDebug("Begin UserContextSeed SeedAsync"); userContext.Database.Migrate(); if (userContext.Users.Count() == 0) { userContext.Users.Add(new AppUser() { Name = "wyt" }); userContext.SaveChanges(); } } } catch (Exception ex) { if (retryForAvaiability<10) { retryForAvaiability++; var logger = loggerFactory.CreateLogger(typeof(UserContextSeed)); logger.LogError(ex.ToString()); await Task.Delay(TimeSpan.FromSeconds(2)); await SeedAsync(app, loggerFactory, retryForAvaiability); } } }