Add nginx-aspnet-mysql implementation (#119)
* Added nginx-aspnet-mysql implementation Signed-off-by: GitHub <noreply@github.com> * Updated nginx+aspnet+mysql README.md Signed-off-by: GitHub <noreply@github.com> * Added db healthcheck Signed-off-by: GitHub <noreply@github.com>
This commit is contained in:
		
							parent
							
								
									a90d4902e0
								
							
						
					
					
						commit
						eece4feb98
					
				
					 8 changed files with 229 additions and 0 deletions
				
			
		
							
								
								
									
										68
									
								
								nginx-aspnet-mysql/README.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								nginx-aspnet-mysql/README.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,68 @@ | |||
| ## Compose sample application | ||||
| ### ASP.NET server with an Nginx proxy and a MySQL database | ||||
| 
 | ||||
| Project structure: | ||||
| ``` | ||||
| . | ||||
| ├── backend | ||||
| │   ├── Dockerfile | ||||
| │   ├── aspnet.csproj | ||||
| │   └── Program.cs | ||||
| ├── db | ||||
| │   └── password.txt | ||||
| ├── docker-compose.yaml | ||||
| ├── proxy | ||||
| │   ├── conf | ||||
| │   └── Dockerfile | ||||
| └── README.md | ||||
| ``` | ||||
| 
 | ||||
| [_docker-compose.yaml_](docker-compose.yaml) | ||||
| ``` | ||||
| services: | ||||
|   backend: | ||||
|     build: backend | ||||
|     ... | ||||
|   db: | ||||
|     image: mysql:8.0.19 | ||||
|     ... | ||||
|   proxy: | ||||
|     build: proxy | ||||
|     ports: | ||||
|     - 80:80 | ||||
|     ... | ||||
| ``` | ||||
| The compose file defines an application with three services `proxy`, `backend` and `db`. | ||||
| When deploying the application, docker-compose maps port 80 of the proxy service container to port 80 of the host as specified in the file. | ||||
| Make sure port 80 on the host is not already being in use. | ||||
| 
 | ||||
| ## Deploy with docker-compose | ||||
| 
 | ||||
| ``` | ||||
| $ docker-compose up -d | ||||
| ``` | ||||
| 
 | ||||
| ## Expected result | ||||
| 
 | ||||
| Listing containers must show three containers running and the port mapping as below: | ||||
| ``` | ||||
| $ docker ps | ||||
| CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES | ||||
| 8906b14c5ad1        nginx-aspnet-mysql_proxy     "nginx -g 'daemon of…"   2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp    nginx-aspnet-mysql | ||||
| l_proxy_1 | ||||
| 13e0e0a7715a        nginx-aspnet-mysql_backend   "/server"                2 minutes ago       Up 2 minutes        8000/tcp              nginx-aspnet-mysq | ||||
| l_backend_1 | ||||
| ca8c5975d205        mysql:5.7                    "docker-entrypoint.s…"   2 minutes ago       Up 2 minutes        3306/tcp, 33060/tcp   nginx-aspnet-mysql | ||||
| l_db_1 | ||||
| ``` | ||||
| 
 | ||||
| After the application starts, navigate to `http://localhost:80` in your web browser or run: | ||||
| ``` | ||||
| $ curl localhost:80 | ||||
| ["Blog post #0","Blog post #1","Blog post #2","Blog post #3","Blog post #4"] | ||||
| ``` | ||||
| 
 | ||||
| Stop and remove the containers | ||||
| ``` | ||||
| $ docker-compose down | ||||
| ``` | ||||
							
								
								
									
										17
									
								
								nginx-aspnet-mysql/backend/Dockerfile
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										17
									
								
								nginx-aspnet-mysql/backend/Dockerfile
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,17 @@ | |||
| 
 | ||||
| FROM mcr.microsoft.com/dotnet/aspnet:5.0 as base | ||||
| WORKDIR /app | ||||
| 
 | ||||
| FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build | ||||
| COPY . /src | ||||
| WORKDIR /src | ||||
| RUN ls | ||||
| RUN dotnet build "aspnetapp.csproj" -c Release -o /app/build | ||||
| 
 | ||||
| FROM build AS publish | ||||
| RUN dotnet publish "aspnetapp.csproj" -c Release -o /app/publish | ||||
| 
 | ||||
| FROM base AS final | ||||
| WORKDIR /app | ||||
| COPY --from=publish /app/publish . | ||||
| ENTRYPOINT ["dotnet", "aspnetapp.dll"] | ||||
							
								
								
									
										84
									
								
								nginx-aspnet-mysql/backend/Program.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								nginx-aspnet-mysql/backend/Program.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,84 @@ | |||
| using System; | ||||
| using System.IO; | ||||
| using System.Collections.Generic; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.AspNetCore; | ||||
| using Microsoft.AspNetCore.Builder; | ||||
| using Microsoft.AspNetCore.Hosting; | ||||
| using Microsoft.AspNetCore.Http; | ||||
| using Microsoft.AspNetCore.Routing; | ||||
| using Microsoft.Extensions.Primitives; | ||||
| using MySql.Data; | ||||
| using MySql.Data.MySqlClient; | ||||
| 
 | ||||
| class Program | ||||
| { | ||||
|     public static void Main(string[] args)  => WebHost.CreateDefaultBuilder(args) | ||||
|         .Configure(async app => | ||||
|         { | ||||
|             app.UseRouting(); | ||||
|                      | ||||
|             string password = File.ReadAllText("/run/secrets/db-password"); | ||||
|             string connectionString = $"server=db;user=root;database=example;port=3306;password={password}"; | ||||
| 
 | ||||
|             app.UseEndpoints(e => | ||||
|             { | ||||
|                 e.MapGet("/",  context => { | ||||
|                     using MySqlConnection connection = new MySqlConnection(connectionString); | ||||
|                     var titles = new List<string>(); | ||||
| 
 | ||||
|                     try | ||||
|                     { | ||||
|                         Console.WriteLine("Connecting to MySQL..."); | ||||
|                         connection.Open(); | ||||
| 
 | ||||
|                         string sql = "SELECT title FROM blog"; | ||||
|                         using var cmd = new MySqlCommand(sql, connection); | ||||
|                         using MySqlDataReader reader = cmd.ExecuteReader(); | ||||
| 
 | ||||
|                         while (reader.Read()) | ||||
|                         { | ||||
|                             titles.Add(reader.GetString(0)); | ||||
|                         } | ||||
|                         reader.Close(); | ||||
|                     } | ||||
|                     catch (Exception ex) | ||||
|                     { | ||||
|                         Console.WriteLine(ex.ToString()); | ||||
|                         context.Response.StatusCode = 500; | ||||
|                         return Task.CompletedTask; | ||||
|                     } | ||||
|                     connection.Close(); | ||||
|                      | ||||
|                     context.Response.StatusCode = 200; | ||||
|                     context.Response.WriteAsJsonAsync(titles); | ||||
| 
 | ||||
|                     return Task.CompletedTask; | ||||
|                 }); | ||||
|             }); | ||||
|             Prepare(connectionString); | ||||
| 
 | ||||
|         }).Build().Run(); | ||||
| 
 | ||||
|         private static void Prepare(string connectionString) | ||||
|         { | ||||
|             using MySqlConnection connection = new MySqlConnection(connectionString); | ||||
| 
 | ||||
|             connection.Open(); | ||||
|             using var transation = connection.BeginTransaction(); | ||||
| 
 | ||||
|             using MySqlCommand cmd1 = new MySqlCommand("DROP TABLE IF EXISTS blog", connection, transation); | ||||
|             cmd1.ExecuteNonQuery(); | ||||
| 
 | ||||
|             using MySqlCommand cmd2 = new MySqlCommand("CREATE TABLE IF NOT EXISTS blog (id int NOT NULL AUTO_INCREMENT, title varchar(255), PRIMARY KEY (id))", connection, transation); | ||||
|             cmd2.ExecuteNonQuery(); | ||||
|              | ||||
|             for (int i = 0; i < 5; i++) | ||||
|             { | ||||
|                 using MySqlCommand insertCommand = new MySqlCommand( $"INSERT INTO blog (title) VALUES ('Blog post #{i}');", connection, transation); | ||||
|                 insertCommand.ExecuteNonQuery(); | ||||
| 	        } | ||||
|             transation.Commit(); | ||||
|             connection.Close(); | ||||
|         } | ||||
| } | ||||
							
								
								
									
										8
									
								
								nginx-aspnet-mysql/backend/aspnetapp.csproj
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								nginx-aspnet-mysql/backend/aspnetapp.csproj
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| <Project Sdk="Microsoft.NET.Sdk.Web"> | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net5.0</TargetFramework> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="MySql.Data" Version="8.0.23" /> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
							
								
								
									
										1
									
								
								nginx-aspnet-mysql/db/password.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								nginx-aspnet-mysql/db/password.txt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| db-q5n2g | ||||
							
								
								
									
										41
									
								
								nginx-aspnet-mysql/docker-compose.yaml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								nginx-aspnet-mysql/docker-compose.yaml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | |||
| version: "3.7" | ||||
| services: | ||||
|   backend: | ||||
|     build: backend | ||||
|     secrets: | ||||
|       - db-password | ||||
|     depends_on:  | ||||
|       - db | ||||
|     environment: | ||||
|       - ASPNETCORE_URLS=http://+:8000 | ||||
|     depends_on: | ||||
|       db: | ||||
|         condition: service_healthy | ||||
|   db: | ||||
|     image: mysql:8.0.19 | ||||
|     command: '--default-authentication-plugin=mysql_native_password' | ||||
|     restart: always | ||||
|     healthcheck: | ||||
|       test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1", "--silent"] | ||||
|       interval: 3s | ||||
|       retries: 5 | ||||
|       start_period: 30s | ||||
|     secrets: | ||||
|       - db-password | ||||
|     volumes: | ||||
|       - db-data:/var/lib/mysql | ||||
|     environment: | ||||
|       - MYSQL_DATABASE=example | ||||
|       - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db-password | ||||
| 
 | ||||
|   proxy: | ||||
|     build: proxy | ||||
|     ports: | ||||
|       - 80:80 | ||||
|     depends_on:  | ||||
|       - backend | ||||
| volumes: | ||||
|   db-data: | ||||
| secrets: | ||||
|   db-password: | ||||
|     file: db/password.txt | ||||
							
								
								
									
										2
									
								
								nginx-aspnet-mysql/proxy/Dockerfile
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										2
									
								
								nginx-aspnet-mysql/proxy/Dockerfile
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| FROM nginx:1.13-alpine | ||||
| COPY conf /etc/nginx/conf.d/default.conf | ||||
							
								
								
									
										8
									
								
								nginx-aspnet-mysql/proxy/conf
									
										
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								nginx-aspnet-mysql/proxy/conf
									
										
									
									
									
										Executable file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| server { | ||||
|     listen       80; | ||||
|     server_name  localhost; | ||||
|     location / { | ||||
|         proxy_pass   http://backend:8000; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue