如何使用 Amazon Lightsail 容器设置 Nginx 反向代理

Amazon Lightsail 是一款易于使用的虚拟专用服务器。Lightsail 最近发布了容器服务。您可以按照本教程学习如何使用 Amazon Lightsail 容器设置 Nginx 反向代理。 

在本教程中,您将学习如何使用 Lightsail 容器在 Nginx 反向代理后面配置 Flask Web 服务器。Nginx 反向代理通过端口 80 接受 Web 请求,并通过端口 5000 将这些请求转发到 Flask Web 服务器。Flask Web 服务器完成请求并将响应内容返回给 Nginx。

Lightsail 容器服务既托管 Nginx 容器又托管 Flask 容器。通过公共端点可以对 Nginx 服务器进行外部访问。

开始免费使用 Amazon Lightsail。 

关于本教程
时间 30 分钟   
费用 免费
使用场景 计算
产品 Amazon Lightsail
级别 200
上次更新时间 2021 年 2 月 10 日

步骤 1:前提条件

开始使用应用程序之前,先完成以下前提条件。

1.1 — 您需要一个 AWS 账户,而且必须在系统上安装 DockerDocker Compose、AWS 命令行界面 (CLI) 工具和 Lightsail Control (lightsailctl) 插件。如果您没有上述某些工具或插件,请按照提供的链接进行操作。

步骤 2:获取源代码

2.1 — 在本地克隆 GitHub 存储库。

 

git clone https://github.com/awsgeek/lightsail-containers-nginx.git

2.2 — 切换到项目目录。

在本指南的后续步骤中,所有命令均从项目目录运行。

cd lightsail-containers-nginx

步骤 3:Flask 应用程序

Flask 应用程序包含一个 hello_world() 函数,当请求路由 / 时会触发该函数。此应用程序在运行时会绑定到系统上的所有 IP (0.0.0.0) 并监听端口 5000(默认 Flask 端口)。

3.1 — 以下代码块中显示了 Flask 应用程序 app.py 的源代码。 

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello_world():
   return "Hello, World!"

if __name__ == "__main__":
   app.run(host="0.0.0.0", port=5000)

3.2 — Flask 应用程序的 Dockerfile 使用 Python alpine 镜像尽可能降低容器镜像的大小。容器启动时运行的命令与从命令行运行的命令相同:python app.py

# Set base image (host OS)
FROM python:3.8-alpine

# By default, listen on port 5000
EXPOSE 5000/tcp

# Set the working directory in the container
WORKDIR /app

# Copy the dependencies file to the working directory
COPY requirements.txt .

# Install any dependencies
RUN pip install -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY app.py .

# Specify the command to run on container start
CMD ["python", "./app.py"]

步骤 4:构建 Flask 容器

通过完成以下步骤在本地系统上构建 Flask 应用程序容器。

4.1 — 使用 Docker 构建容器。从项目目录完成以下命令:

此命令使用 Dockerfile 在当前目录下构建一个容器,并将该容器标记为 flask-container

docker build -t flask-container ./flask

4.2 — 容器构建完成后,通过运行容器在本地测试 Flask 应用程序。

docker run -p 5000:5000 flask-container

4.3 — Flask 应用程序将在容器中运行,并且将通过端口 5000 向您的本地系统公开数据。 

浏览到 http://localhost:5000 或从命令行使用 curl,您将看到 Hello, World!

若要停止容器,请输入 CTRL-C

curl localhost:5000

Hello, World!

步骤 5:Nginx 反向代理

5.1 — Nginx 反向代理通过端口 5000 将所有请求转发到 Flask 应用程序。若要配置 Nginx 以转发请求,需要使用下面的简单配置文件 nginx.conf: 

此配置会将所有请求转发到上游的 Flask 服务器。当容器运行时,Flask 服务器的主机名和端口会以环境变量的形式提供。

events {}

http {

   upstream flask {
      server ${FLASK_HOST}:${FLASK_PORT};
   }

   # a simple reverse-proxy
   server {

      listen 80 default_server;

      location / {
            # pass requests to the Flask host
            proxy_pass http://flask;
      }
   }
}

5.2 — Nginx 反向代理的 Dockerfile 使用头部 Nginx alpine 镜像,并且只是将 nginx.conf 配置文件复制到相应的目录。

如以下代码所示。 

FROM nginx:1.19-alpine
COPY ./nginx.conf /etc/nginx/templates/nginx.conf.template

步骤 6:构建 Nginx 容器

通过完成以下步骤在本地系统上构建 Nginx 反向代理容器。

6.1 — 使用 Docker 构建容器。从项目目录完成以下命令:

此命令使用 Dockerfile 在当前目录下构建一个容器,并将该容器标记为 nginx-container

docker build -t nginx-container ./nginx

6.2 — 容器构建完成后,通过运行容器在本地测试 Nginx 代理和 Flask 应用程序:

docker-compose up –-build

6.3 — Flask 应用程序和 Nginx 反向代理容器都将运行。Nginx 服务器通过端口 80 监听请求,并将请求转发到 Flask 应用程序。浏览到 http://localhost 或从命令行使用 curl,您将看到 Hello, World!

若要停止容器,请输入 CTRL-C

curl localhost

Hello, World!

步骤 7:创建容器服务

通过完成以下步骤来创建 Lightsail 容器服务并将本地容器镜像推送到新容器服务。

7.1 — 使用 create-container-service 命令创建 Lightsail 容器服务。

power 和 scale 参数用于指定容器服务的容量。在本指南中,需要的容量很小。

create-container-service 命令的输出结果表明新服务的状态为 PENDING(如第二个代码块所示)。

aws lightsail create-container-service --service-name sample-service \
--power small \
--scale 1
{
    "containerService": {
        "containerServiceName": "sample-service",
        ...
        "state": "PENDING",

7.2 — 使用 get-container-services 命令监控创建中的容器的状态。

待容器服务的状态更改为 ACTIVE 后,再继续执行下一步。您的容器服务应当在几分钟后就会变为 ACTIVE 状态。

aws lightsail get-container-services --service-name sample-service

7.3 — 使用 push-container-image 命令将 Flask 应用程序容器推送到 Lightsail。

注意:sample-service.flask-container.X 中的 X 将为一个数值。如果这是您首次将镜像推送到容器服务,则此数值为 1。在下一步中将需要此数值。

aws lightsail push-container-image --service-name sample-service \
--label flask-container \
--image flask-container

...

Refer to this image as ":sample-service.flask-container.X" in deployments.

7.4 — 使用 push-container-image 命令将 Nginx 反向代理容器推送到 Lightsail。

注意:sample-service.nginx-container.Y 中的 Y 将为一个数值。如果这是您首次将镜像推送到容器服务,则此数值为 1。在下一步中将需要此数值。

aws lightsail push-container-image --service-name sample-service \
--label nginx-container \
--image nginx-container

...

Refer to this image as ":sample-service.nginx-container.Y" in deployments.

步骤 8:部署容器

通过完成以下步骤,创建用于部署和公共端点配置的 JSON 文件,然后将容器镜像部署到容器服务。

8.1 — 创建一个名为 containers.json 的新文件。

编辑该文件并添加以下代码块。 

将 sample-service.flask-container.X 中的 X  sample-service.nginx-container.Y 中的 替换为上一步中的数值。

保存该文件。

containers.json 文件用于描述将在容器服务上启动的容器的设置。在此实例中,containers.json 文件描述了 Nginx 容器和 Flask 容器以及这些容器将使用的镜像和公开数据的端口。此外,文件还提供了用于指定 Flask 主机和端口的环境变量。在运行时,Nginx 会将 nginx.conf 文件中的占位符值替换为此处提供的实际值。

{
   "sample-nginx": {
      "image": ":sample-service.nginx-container.Y",
      "command": [],
      "ports": {
            "80": "HTTP"
      },
      "environment": {
            "NGINX_ENVSUBST_OUTPUT_DIR": "/etc/nginx",
            "FLASK_HOST": "localhost",
            "FLASK_PORT": "5000"
      }
   },
   "sample-flask": {
      "image": ":sample-service.flask-container.X",
      "ports": {
            "5000": "HTTP"
      }
   }

8.2 — 创建一个名为 public-endpoint.json 的新文件。 

编辑该文件并添加以下代码。 

保存该文件。

public-endpoint.json 文件用于描述容器服务的公共端点的设置。在此实例中,public-endpoint.json 文件表明 Nginx 容器将通过端口 80 公开数据。只有要进行公共访问的服务才需要设置公共端点。

{
    "containerName": "sample-nginx",
    "containerPort": 80
}

8.3 — 在 AWS CLI 中,使用 create-container-service-deployment 命令将容器部署到容器服务。

create-container-service-deployment 命令的输出结果表明容器服务的状态现在为 DEPLOYING(如第二个代码块所示)。 

aws lightsail create-container-service-deployment --service-name sample-service \
--containers file://containers.json \
--public-endpoint file://public-endpoint.json
{
    "containerServices": [{
        "containerServiceName": "sample-service",
        ...
        "state": "DEPLOYING",

8.4 — 使用 get-container-services 命令监控容器的状态,待状态更改为 RUNNING 后再继续执行下一步。

get-container-service 命令还会返回容器服务的端点 URL。

待容器服务的状态更改为 RUNNING 后,通过浏览器前往此 URL,以验证容器服务是否正常运行。和之前一样,您的浏览器输出结果应当显示“Hello, World!”。

恭喜您!您已使用 Amazon Lightsail 容器成功部署了容器化 Nginx 反向代理和 Flask 应用程序。

aws lightsail get-container-services --service-name sample-service
{
    "containerServices": [{
        "containerServiceName": "sample-service",
        ...
        "state": "RUNNING",
        ...
        "url": "https://sample-service...

步骤 9:清除

通过完成以下步骤来清除在学习本教程的过程中创建的 Lightsail 容器服务。

9.1 — 若要清除和删除 Lightsail 资源,请使用 delete-container-service 命令。

delete-container-service 命令会删除容器服务、任何关联的容器部署以及容器镜像。

aws lightsail delete-container-service --service-name sample-service
{
    "containerService": {
        "containerServiceName": "sample-service",
        ...
        "state": "PENDING",

恭喜您

恭喜您!您已经成功部署了容器化 Nginx 反向代理和 Flask 应用程序。

Amazon Lightsail 是开发、构建和部署各种应用程序(如 WordPress、网站和博客平台)的绝佳选择。

此页内容对您是否有帮助?

推荐的后续步骤

查看容器日志

在容器服务上查看容器日志。在此处阅读更多信息。 

监控利用率指标

监控容器服务的利用率指标。在此处阅读更多信息。 

查看源代码

本指南和本文档的源代码来自 Github 存储库。