Container
Advanced
Containerization là cơ chế đóng gói dịch vụ cùng những thư viện và cấu hình cần thiết trong một container từ đó dễ dàng triển khai và chia sẻ trên nhiều môi trường khác nhau (development, server hay cloud). Việc sử dụng container giúp các kĩ sư phần mềm tập trung hơn vào phát triển logic sản phẩm, trong khi nhóm vận hàng DevOps có thể triển khai và vận hàng sản phẩm một cách thuận lợi hơn.
Có nhiều nền tảng cung cấp cơ chế xây dựng, triển khai và vận hàng containers: Docker, Kuberness, Vagrant, etc…Trong phần tiếp theo, chúng ta sẽ tìm hiểu việc sử dụng Docker để đóng gói dịch vụ RemindersManagement trong Docker Image, từ đó tạo ra Docker Container để thực thi dịch vụ này.
Nội dung
Cài đặt Docker
Tham khảo cài đặt Docker Destop
Kiểm tra hệ thống Docker:
docker info
Docker Image
Docker là công cụ cho phép xây dựng môi trường phát triển và thực thi ứng dụng chạy trong một container độc lập. Container đóng gói ứng dụng cùng những tài nguyên hoặc thư viện cần thiết. Sử dụng container cho phép những kĩ sư thiết lập môi trường làm việc nhanh gọn, không cần quan tâm đến việc cài đặt các thư viện cho môi trường làm việc.
Một container được tạo theo các bước:
- Khai báo Dockerfile - tập hợp các chỉ thị để xây dựng Docker Image
- Tạo Docker Image - tập hợp các files được chia thành nhiều layers
- Khởi tạo Docker Container dựa trên Docker Image
Trong phần này, chúng ta sẽ xây dựng một Docker Image cho dịch vụ RemindersManagement.
Tạo Dockerfile
trong foler RemindersManagement.API
# Define build environment and working directory
FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . .
RUN dotnet publish -c release -o out
# Define runtime environment and working directory
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
# Copy build result and asset to folder
WORKDIR /app
COPY --from=build /app/out .
# Define environment variable
ENV DOTNET_RUNNING_IN_CONTAINER=true \
ASPNETCORE_URLS=http://+:8000
# Define port and entry point for running docker
EXPOSE 8000
ENTRYPOINT ["dotnet", "RemindersManagement.API.dll"]
Dockerfile
thực hiện hai việc chính:
- Download image
mcr.microsoft.com/dotnet/core/sdk:3.1
, kết hợp lệnhdotnet restore / dotnet publish
để cài đặt thư viện và biên dịch dịch vụRemindersManagement
trên Docker Container. - Download image
mcr.microsoft.com/dotnet/core/aspnet:3.1
, khai báoENTRYPOINT
cho phép thực thi container như một chương trình với main commanddotnet RemindersManagement.API.dll
Trong folder RemindersManagement.API
tạo Docker Image với lệnh:
docker build --tag remindersmanagement:1.0 .
Câu lệnh sử dụng tham số:
-t remindersmanagement:1.0
: tên và version của Docker Image.
: vị trí của thư mục chứa Dockerfile
Output:
Sending build context to Docker daemon 180.6MB
Step 1/12 : FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build
---> 9ab567a29502
Step 2/12 : WORKDIR /app
---> Using cache
---> 4413e130453d
Step 3/12 : COPY *.csproj ./
---> 2ae0d9c0e0d7
Step 4/12 : RUN dotnet restore
---> Running in 72d7aabef5da
Determining projects to restore...
Restored /app/RemindersManagement.API.csproj (in 39.78 sec).
Removing intermediate container 72d7aabef5da
---> 5a2226da309a
Step 5/12 : COPY . .
---> e3d34d9024d8
Step 6/12 : RUN dotnet publish -c release -o out
---> Running in e809355e8e1c
Microsoft (R) Build Engine version 16.7.0-preview-20360-03+188921e2f for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
Restored /app/RemindersManagement.API.csproj (in 814 ms).
RemindersManagement.API -> /app/bin/release/netcoreapp3.1/RemindersManagement.API.dll
RemindersManagement.API -> /app/out/
Removing intermediate container e809355e8e1c
---> b6f83339f334
Step 7/12 : FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
---> bdca989bc8d3
Step 8/12 : WORKDIR /app
---> Using cache
---> 729e605b63dc
Step 9/12 : COPY --from=build /app/out .
---> f09bf1a60e06
Step 10/12 : ENV DOTNET_RUNNING_IN_CONTAINER=true ASPNETCORE_URLS=http://+:8000
---> Running in bfe989c99c9f
Removing intermediate container bfe989c99c9f
---> a63a0e590682
Step 11/12 : EXPOSE 8000
---> Running in 1a4845d9faa4
Removing intermediate container 1a4845d9faa4
---> 12bd9184dc49
Step 12/12 : ENTRYPOINT ["dotnet", "RemindersManagement.API.dll"]
---> Running in 8c727d26c18e
Removing intermediate container 8c727d26c18e
---> 5fa79800389e
Successfully built 5fa79800389e
Successfully tagged remindersmanagement:1.0
Bên cạnh đó, có thể dùng câu lệnh sau để xác nhận remindersmanagement
đã được build thành công:
docker images
Output
REPOSITORY TAG IMAGE ID CREATED SIZE
remindersmanagement 1.0 322671312233 35 seconds ago 267MB
mcr.microsoft.com/dotnet/core/sdk 3.1-buster 65279ad76723 2 weeks ago 708MB
mcr.microsoft.com/dotnet/core/runtime 3.1-buster-slim 601add7f3c26 2 weeks ago 190MB
mcr.microsoft.com/dotnet/core/sdk 3.1 9ab567a29502 6 weeks ago 708MB
mcr.microsoft.com/dotnet/core/aspnet 3.1 bdca989bc8d3 6 weeks ago 207MB
Docker Compose
Docker Compose là công cụ cho phép thực thi và quản lý nhiều thành phần của ứng dụng trên các containers khác nhau.
Phần thực hành của Docker Compose chia thành các phần:
- Health Check & CloudWatch: tích hợp Health Check, CloudWatch
- Setup Reverse Proxy: sử dụng Reverse Proxy dựa trên NGINX
- Setup HTTPS NGINX: cài đặt giao thức HTTP Secure (HTTPS)
Health Check & CloudWatch
Trong phần ví dụ Middleware Health Check, chúng ta sử dụng Health Check UI để giám sát thông tin về trạng thái của dịch vụ RemindersManagament
. Thông tin Health Check được ghi lại trực tiếp trong “in-memory storage”.
Tuy nhiên, cách làm này chưa thực sự hợp lý:
- Health Check nên thực thi trên một môi trường độc lập với services
- Dữ liệu Health cần được lưu trữ trong một cơ sở dữ liệu riêng biệt
Khi thực thi ứng dụng với Docker Compose, chúng ta có thể bổ sung thêm các containers cho Health Check service và Health Check Storage Provider (MySQL Server).
Các bước thực hiện:
Bước 1: Khai báo cấu hình Docker Compose
Trong solution folder FriendReminders
, tạo file docker-compose.yml
với nội dung
version: '3.8'
services:
remindersmgtservice:
build:
context: ./Services/RemindersManagement/RemindersManagement.API
dockerfile: ./Dockerfile
ports:
- 8000:8000
environment:
- ASPNETCORE_ENVIRONMENT=Development
env_file:
- ./aws-secret-dev.env
networks:
- webproxy
depends_on:
- healthcheckserver
healthcheckserver:
image: xabarilcoding/healthchecksui
depends_on:
- healthcheckdbserver
environment:
- storage_provider=MySql
- storage_connection=Server=healthcheckdbserver;uid=root;Password=password;database=healthcheckdb
- Logging:LogLevel:Default=Debug
- Logging:Loglevel:Microsoft=Warning
- Logging:LogLevel:HealthChecks=Debug
ports:
- 5000:80
networks:
- webproxy
healthcheckdbserver:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: healthcheckdb
MYSQL_USER: root
MYSQL_PASSWORD: password
networks:
- webproxy
networks:
webproxy:
driver: bridge
Những điểm thay đổi cần chú ý:
- Bổ sung Containers cho health check
healthcheckserver
: sử dụnghealthchecksui
image, thực hiện việc giám sát healthhealthcheckdbserver
: sử dụngmysql
image, lưu trữ dữ liệu health trong database
- Trong
remindersmgtservice
:env_file
: AWWS credential cho phép service gửi log từ Serilog đến CloudWatchdepends_on
: khai báo sự phụ thuộc vào health check service- Thực thi Development mode với khai báo
ASPNETCORE_ENVIRONMENT
Bên cạnh đó, chúng ta cần tạo file aws-secret-dev.env
chứa thông tin AWS Credential
AWS_ACCESS_KEY_ID=[Your_Secret_ID]
AWS_SECRET_ACCESS_KEY=[Your_Secret_Access_Key]
Chú ý
Việc lưu giá trị AWS Credential dưới dạng text file không phải là phương án tối ưu nhất, mặc dù chúng ta có thể chỉ lưu file này trên máy tính local và không commit lên source code repository. Bên cạnh phương án sử dụng *.env file , chúng ta có thể sử dụng Docker Secret áp dụng trong chế độ Docker Swarm, hoặc sử dụng dịch vụ Secret Manager của AWS.
Bước 2: Thay đổi nội dung ConfigureServices
trong Startup.cs
cho phép service lưu dữ liệu health check xuống MySQL Database
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using RemindersManagement.API.Domain.Interfaces;
using RemindersManagement.API.Domain.Services;
using RemindersManagement.API.Infrastructure.Data;
using RemindersManagement.API.Infrastructure.Repositories;
using Serilog;
namespace RemindersManagement.API
{
public class Startup
{
...
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRemindersRepository, RemindersRepository>();
services.AddScoped<ICategoriesRepository, CategoriesRepository>();
services.AddScoped<IRemindersService, RemindersService>();
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddDbContext<RemindersDbContext>(options => {
options.UseSqlite("Data Source=FriendReminders.db");
});
// Register the Swagger generator
services.AddSwaggerGen();
// Register health check services
services.AddHealthChecks();
// Register HealthChecks UI and storage provider
services
.AddHealthChecksUI()
.AddMySqlStorage("Server=healthcheckdbserver;uid=root;Password=password;database=healthcheckdb");
}
}
}
ConfigureServices
sử dụng method AddMySqlStorage
để lưu thông tin health check xuống MySQL server healthcheckdbserver
, do vậy trong folder RemindersManagement.API
, chúng ta cần cài đặt MySQL storage provider package với lệnh:
dotnet add package AspNetCore.HealthChecks.UI.MySql.Storage
Ngoài ra, do sử dụng Docker Compose, nội dung file cấu hình appsettings.Development.json
cũng cần cập nhật lại giá trị endpoint Uri
của Health Check:
{
"HealthChecksUI": {
"HealthChecks": [
{
"Name": "RemindersManagement",
"Uri": "http://remindersmgtservice:8000/health"
}
]
},
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"AWS.Logger.SeriLog"
],
"LogGroup": "friendreminders/RemindersManagement",
"Region": "ap-southeast-2",
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "AWSSeriLog"
}
],
"Enrich": [
"FromLogContext"
]
},
"AllowedHosts": "*"
}
Bước 3: Xác nhận kết quả
Trong folder FriendReminders
thực thi lệnh:
docker-compose up --build
Sử dụng Docker Desktop kiểm tra danh sách các containers:
Danh sách Docker Containers trên Docker Desktop
Gửi HTTP Get request đến URL endpoint http://localhost:8000/api/Reminders
:
Nội dung HTTP Response từ Kestrel endpoint
/api/Reminders
content-type: application/json; charset=utf-8
date: Tue22 Sep 2020 10:21:23 GMT
server: Kestrel
transfer-encoding: Identity
Thông tin Header cho thấy kết quả được trả về từ Kestrel Server. Trong phần tiếp theo, chúng ta sẽ cài đặt NGINX proxy với mục đích hạn chế giao tiếp trực tiếp giữa client và HTTP server.
Setup Reverse Proxy
Có hai mô hình kết hợp việc thực thi ứng dụng Web API và HTTP Server:
- In-process: Thực thi trên cùng một tiến trình
- Out-process: Thực thi trên các tiến trình khác nhau
Theo mặc định, ứng dụng ASP.NET Core và HTTP Server - Kestrel kết hợp theo mô hình in-process. Kestrel tiếp nhận HTTP request, đóng gói lại dưới đối tượng HTTPContext trước khi gửi lại cho ứng dụng. Mô hình in-process đem lại tính tối ưu cao hơn so với out-process do hệ thống không cần thực hiện chức năng quản lý tiến trình cũng như chuyển tiếp yêu cầu qua lại giữa các network adapter.
Khi triển khai trong môi trường Production, Kestrel thường kết hợp cùng Reverse Proxy (Internet-facing proxy) cho những mục đích:
- Hạn chế giao tiếp trực tiếp giữa ứng dụng và bên ngoài
- Cung cấp thêm một lớp bảo vệ cùng khả năng tuỳ biến cần thiết
- Đem lại khả năng cân bằng tải - Load Balancing
- Tăng cường khả năng bảo mật với giao thức HTTPS
- Giảm tải - offload cho Web/Application Server
Theo phân tích trên, chúng ta sẽ bổ sung một Reverse Proxy - Nginx vào ví dụ Docker Compose. Bên cạnh Nginx, cũng có rất nhiều lựa chọn khác bao gồm: HAProxy, Enyou, Traefik, Apache.
Hướng dẫn:
Việc kết hợp Reverse Proxy và Application Server được áp dụng phổ biến trong mô hình kiến trúc Microservices với thuật ngữ Sidecar Patterns.
Các bước thực hiện:
- Trong folder
RemindersManagement.API
, tạo folder Proxy bao gồm:
Dockerfile
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
nginx.conf
worker_processes auto;
events { worker_connections 512; }
http {
sendfile on;
upstream app_servers {
server remindersmgtservice:8000;
}
server {
listen 80;
location / {
proxy_pass http://app_servers;
}
}
}
Trong cấu hình này, Nginx thực thi trên cổng 80 và liên kết với upstream service remindersmgtservice
.
- Cập nhật file
docker-compose.yaml
:
version: '3.8'
services:
nginx:
restart: always
build:
dockerfile: Dockerfile
context: ./Services/RemindersManagement/RemindersManagement.API/Proxy
ports:
- "80:80"
- "443:443"
networks:
- webproxy
depends_on:
- remindersmgtservice
remindersmgtservice:
build:
context: ./Services/RemindersManagement/RemindersManagement.API
dockerfile: ./Dockerfile
environment:
- ASPNETCORE_ENVIRONMENT=Development
env_file:
- ./aws-secret-dev.env
networks:
- webproxy
depends_on:
- healthcheckserver
healthcheckserver:
image: xabarilcoding/healthchecksui
depends_on:
- healthcheckdbserver
environment:
- storage_provider=MySql
- storage_connection=Server=healthcheckdbserver;uid=root;Password=password;database=healthcheckdb
- Logging:LogLevel:Default=Debug
- Logging:Loglevel:Microsoft=Warning
- Logging:LogLevel:HealthChecks=Debug
ports:
- 5000:80
networks:
- webproxy
healthcheckdbserver:
image: mysql:5.7
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: healthcheckdb
MYSQL_USER: root
MYSQL_PASSWORD: password
networks:
- webproxy
networks:
webproxy:
driver: bridge
Chú ý
docker-compose.yaml
loại bỏ khai báo ports
trong remindersmgtservice
do service này không cần giao tiếp trực tiếp với môi trường Docker Host. Mọi messages trao đổi giữa client và Http server phải đi qua và kiểm soát bởi Reverse Proxy.
- Để xác nhận kết quả, trong folder
FriendReminders
thực thi lệnh:
docker-compose up --build
Gửi HTTP Get request đến URL endpoint http://localhost/api/Reminders
:
Nội dung HTTP Response từ NGINX endpoint
/api/Reminders
Thông tin Header cho thấy kết quả được trả về từ NGINX proxy.
connection: keep-alive
content-type: application/json; charset=utf-8
date: Tue22 Sep 2020 11:02:40 GMT
server: nginx/1.19.2
transfer-encoding: Identity
Setup HTTPS NGINX
Theo đề cập trong phần trước, một trong những chức năng của Reverse Proxy là tăng cường khả năng bảo mật cho một dịch vụ thông qua giao thức HTTPS. Về bản chất, giao thức HTTS là một bản “nâng cấp” của HTTP khi bổ sung thêm một lớp mã hoá thông tin - Secure Socket Layer (SSL). SSL thực hiện việc mã hoá / giải mã thông tin giữa Client và Server thông qua một hạ tầng khoá công khai - Public Key Instrastructure (PKI).
Trong mô hình trao đổi thông tin của PKI, chúng ta sử dụng một cặp khoá, Public / Private Key. Client sử dụng Public Key để mã hoá thông tin gửi đến Server. Server sử dụng Private Key để giải mã thông tin này, đồng thời có trách nhiệm quản lý bảo mật đối với Private Key. Có nhiều thuật toán được áp dụng để tạo ra Public / Private Key, một trong những thuật toán phổ biến nhất là Rivest–Shamir–Adleman (RSA).
Bên cạnh đó, trước khi Client sử dụng Public Key để mã hoá thông tin, câu hỏi đặt ra là Public Key sẽ được chia sẻ như nào giữa Client và Server? Khi Client nhận được Public Key, làm cách nào để Client biết Public Key đó thuộc về Server mà nó đang cần gửi thông tin?
Để thực hiện điều này, Client và Server sẽ cần tin tưởng đến một bên thứ ba - Certificate Authority (CA). CA là một tổ chức quản lý và xác thực danh tính bằng việc sử dụng chữ kí điện tử - Digital Certification. Để tạo ra Certification trên CA, Server cần gửi đến CA Public Key sử dụng cùng với thông tin chứng thực danh tính - Distinguised Name. Phía CA kiểm chứng thông tin này, và cung cấp cho Server một Certification sử dụng cho quá trình trao đổi thông tin với Client.
Trong giai đoạn trao đổi thông tin đầu tiên giữa Client và Server qua giao thức HTTPS với port 443, phía Server sẽ cung cấp Public Key và Certification. Client liên lạc với CA và được chứng thực về thông tin này. Khi việc chứng thực được đảm bảo bởi CA, Client sẽ sử dụng Public Key để mã hoá thông tin gửi đến Server. Trong một số cơ chế, Client có thể tạo thêm một Session Key, mã hoá bởi Public Key khi gửi trả Server, sau đó Client / Server sẽ dựa trên Session Key để trao đổi thông tin.
Trong phần thực hành này, chúng ta sẽ tiến hành việc cài đặt HTTPS trên NGINX. Dựa trên đó, Client sử dụng HTTPS để trao đổi thông tin với remindersmgtservice
một cách gián tiếp qua NGINX. NGINX nhận được thông tin từ Client, và chuyển tiếp đến remindersmgtservice
qua giao thức HTTP. Trong môi trường Development, Client và Server hoạt động trên cùng một Host, do vậy NGINX chỉ cần thực hiện self-signed certification thay vì gửi yêu cầu đến một CA bên ngoài.
Quá trình tạo self-signed certification:
- Trên Terminal, xác nhận phiên bản OpenSSL:
openssl version -a
Output:
LibreSSL 2.8.3
built on: date not available
platform: information not available
options: bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"
- Trong folder
RemindersManagement.API\Proxy
, tạo filelocalhost.conf
:
[req]
default_bits = 1024
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Texas
localityName = Locality Name (eg, city)
localityName_default = Dallas
organizationName = Organization Name (eg, company)
organizationName_default = localhost
organizationalUnitName = organizationalunit
organizationalUnitName_default = Development
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
commonName_max = 64
[req_ext]
subjectAltName = @alt_names
[v3_ca]
subjectAltName = @alt_names
[alt_names]
DNS.1 = localhost
DNS.2 = 127.0.0.1
File localhost.conf
cung cấp cấu hình của Distinguised Name sẽ sử dụng khi thực hiện yêu cầu tạo Certification.
- Tạo 2048 bit Private Key
localhost.key
với thuật toán RSA
openssl genrsa -out localhost.key 2048
Có thể sử dụng câu lệnh sau để hiển thị thông tin của một Private Key
openssl rsa -check -in localhost.key
- Tạo self-signed certification
localhost.crt
với chuẩn mã hoá x509
openssl req -key localhost.key -new -x509 -days 365 -out localhost.crt -config localhost.conf
- Đăng kí
localhost.crt
với hệ thống MacOS Keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ./localhost.crt
Cập nhật Nginx Dockerfile để copy Private Key và Certification vào image:
FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf
COPY localhost.crt /etc/ssl/certs/localhost.crt
COPY localhost.key /etc/ssl/private/localhost.key
Do HTTPS request khi chuyển qua HTTP sẽ bị mất một số thông tin gốc (schema, ip…) từ phía Client, chúng ta cần cập nhật nginx.conf
cho phép Reverse Proxy thiết lập lại thông tin này trước khi chuyển cho remindersmgtservice
:
worker_processes auto;
events { worker_connections 512; }
http {
sendfile on;
upstream app_servers {
server remindersmgtservice:8000;
}
server {
listen 80;
location / {
proxy_pass http://app_servers;
}
}
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
location / {
proxy_pass http://app_servers;
proxy_redirect off;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection keep-alive;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
}
}
}
- Đăng kí Forwarded Headers Middleware trong
Startup.cs
. Middleware này sẽ đọc các thông tin header được thiệt lập trên Nginx và đóng gói lại trong HttpContext:
using HealthChecks.UI.Client;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using RemindersManagement.API.Domain.Interfaces;
using RemindersManagement.API.Domain.Services;
using RemindersManagement.API.Infrastructure.Data;
using RemindersManagement.API.Infrastructure.Repositories;
using Serilog;
namespace RemindersManagement.API
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseForwardedHeaders();
}
else
{
app.UseForwardedHeaders();
app.UseHsts();
}
...
}
}
}
- Trong folder
ReminderFriends
, thực hiện lệnhdocker-compose up --build
, và kiểm tra kết quả theo địa chỉ
https://localhost/swagger/index.html
Khi lần đầu tiên vào địa chỉ trên, trình duyệt (Safari) có thể hiển thị Warning trên do việc chúng ta sử dụng self-signed certification.
Self-signed certification warning & confirmation
Bỏ qua Warning này và lựa chọn Visit this website
, xác nhận Swagger API Document hiển thị thành công. Icon lock trên thanh địa chỉ của trình duyệt cho biết kết nối được thực hiện qua giao thức HTTPS.
Giao diện Swagger của
RemindersManagement
API qua HTTPS
Tài liệu tham khảo
- Host Core on Linux with Nginx
- Implement Web Server in .NET Core
- Kestrel Implementation in .NET Core
- In Process Hosting
- Configure .NET Core with Proxy Server
- Enable SSL with .NET Core with Nginx/Docker
- Nginx Turning