品尝过船上的免费晚餐,眺望着 aws 上搭建博客园海外站的宏伟目标,琢磨着眼前可以实现的小目标,不由自主地在屏幕上敲出了 —— "Hello World!",就从这个最简单朴实的小目标开始吧 —— 用 ASP.NET Core on .NET 5.0 在 Amazon EC2 服务器显示出 "Hello World!"。
先登录到之前启动的 EC2 服务器安装 .NET 5.0 SDK
mkdir $HOME/dotnet_install && cd $HOME/dotnet_install curl -H 'Cache-Control: no-cache' -L https://aka.ms/install-dotnet-preview -o install-dotnet-preview.sh sudo bash install-dotnet-preview.sh
安装好之后查看一下 .NET 的版本
dotnet --info .NET SDK (reflecting any global.json): Version: 5.0.100-rc.2.20479.15 Commit: da7dfa8840 Runtime Environment: OS Name: ubuntu OS Version: 20.04 OS Platform: Linux RID: ubuntu.20.04-x64 Base Path: /usr/share/dotnet/sdk/5.0.100-rc.2.20479.15/
用 dotnet 命令基于模板创建一个 ASP.NET Core MVC 项目 hello-world
dotnet new mv --no-https --name hello-world
创建后之后用 dotnet run 命令运行项目
ubuntu@ip-172-31-44-65:~/hello-world$ dotnet run Building... warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] No XML encryptor configured. Key {b11ef41c-0ca0-4673-a6d2-05aa4a2bdb1a} may be persisted to storage in unencrypted form. info: Microsoft.Hosting.Lifetime[0] Now listening on: http://localhost:5000 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down. info: Microsoft.Hosting.Lifetime[0] Hosting environment: Development info: Microsoft.Hosting.Lifetime[0] Content root path: /home/ubuntu/hello-world
运行成功,接下来用 vim 修改一下视图文件,显示"Hello World!"与"Powered by ..."信息
vi Views/Home/Index.cshtml
改为下面的代码
@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Hello World!</h1> <p>Powered by @System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription on AWS</p> </div>
再接下来 build 项目生成 docker 镜像,用容器部署站点。
先安装 docker
curl -sSL https://get.docker.com/ | sh
安装后将当前用户添加到 docker 组
sudo usermod -aG docker ubuntu
编写 Dockerfile(采用 multistage build)
FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base WORKDIR /app EXPOSE 80 FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build WORKDIR /src COPY *.csproj . RUN dotnet restore COPY . . RUN dotnet build -c Release -o /app FROM build AS publish WORKDIR /src RUN dotnet publish -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "hello-world.dll"]
基于上面的 Dockerfile 生成 docker 镜像
$ docker build . -t hello-world Sending build context to Docker daemon 11.48MB Step 1/16 : FROM mcr.microsoft.com/dotnet/aspnet:5.0-buster-slim AS base ---> 3e92f5fcc999 ... Step 16/16 : ENTRYPOINT ["dotnet", "hello-world.dll"] ---> Using cache ---> a2da910535e2 Successfully built a2da910535e2 Successfully tagged hello-world:latest
用下面的命令以 daemon 方式启动 hellow-world 容器
docker run -d --net=host --restart unless-stopped hello-world
这时 hello-world 应用已经在后台运行了
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES df7d77140e76 hello-world "dotnet hello-world.…" 2 minutes ago Up 2 minutes dreamy_joliot
本机 curl 命令测试一下
$ curl -I localhost HTTP/1.1 200 OK Date: Sun, 08 Nov 2020 10:47:01 GMT Content-Type: text/html; charset=utf-8 Server: Kestrel
站点可以访问正常,但现在只能本机访问,要让外部能访问,需要在 aws 安全组中添加入站规则开放80端口。
在这台 EC2 实例的详情控制台,进入“安全” tab,点击安全组名称,进入安全组控制台,点击“编辑入站规则”,点击“添加入站规则”,添加一条开放80端口的入站规则。
保存规则并生效后,就可以通过公网IP访问了。为了让这个小目标正式一点,我们用了一个域名 —— optcode.net,通过 dns 解析到这台 EC2 服务器的公网 IP。
好了,浏览器访问 http://optcode.net/ ,小目标大功告成!