简体   繁体   English

如何将 Nginx docker 容器指向我的 Web 应用程序的正确容器?

[英]How to point Nginx docker container to the correct container for my web app?

I am setting up my Ruby on Rails application on AWS ECS and would like to redirect my website, example.com, to www.example.com .我正在 AWS ECS 上设置我的 Ruby on Rails 应用程序,并希望将我的网站 example.com 重定向到www.example.com I am running into an issue with redirecting my Nginx upstream server to my Rails app.我遇到了将我的 Nginx 上游服务器重定向到我的 Rails 应用程序的问题。 Everything seems to work fine locally.一切似乎都在本地正常工作。 My Docker container crashes with the following error message:我的 Docker 容器崩溃并显示以下错误消息:

[emerg] 8#8: host not found in upstream "web:3000" in /etc/nginx/conf.d/default.conf:3
nginx: [emerg] host not found in upstream "web:3000" in /etc/nginx/conf.d/default.conf:3

Here's my docker-compose.yml :这是我docker-compose.yml

version: '3'

services:
  web:
    build:
      args:
        DEPLOY_ENV_ARG: ${DEPLOY_ENV:-development}
        SERVER_ENV_ARG: ${SERVER_ENV:-development}
      context: .
      dockerfile: Dockerfile
    ports:
      - "3000:3000"

  nginx:
    build:
      dockerfile: Dockerfile.nginx
    links:
      - web
    ports:
      - "80:80"

Dockerfile.nginx Dockerfile.nginx

FROM nginx:1.23-alpine

COPY ./nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

nginx.conf nginx.conf

upstream rails_app {
  server web:3000;
}

server {
  server_name example.com;

  # Redirect all http://example.com requests to http://www.example.com
  return 301 $scheme://www.$server_name$request_uri;
}

server {
  listen 80;
  listen [::]:80;
  # server_name www.example.com;
  server_name xxxxx-xxxxx-xxxx-xxxx.us-west-2.elb.amazonaws.com; # My ALB address hostname

  # Specify the public application root
  root   /example/public;

  # Specify where Nginx should write its logs
  access_log /var/log/nginx/access.log;
  error_log /var/log/nginx/error.log;

  # Deny requests for files that should never be accessed such as .rb or .log files
  location ~ /\. {
    deny all;
  }

  location ~* ^.+\.(rb|log)$ {
    deny all;
  }

  # Serve static (compiled) assets directly
  location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/   {
    try_files $uri @rails;
    access_log off;
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    add_header Last-Modified "";
    add_header ETag "";
    break;
  }

  # Send non-static file requests to the app server
  location / {
    try_files $uri @rails;
  }

  # Reverse proxy redirecting the request to the rails app, port 3000.
  location @rails {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://rails_app;
    proxy_read_timeout 900;
  }
}

If it's helpful, here's the output of docker ps :如果有帮助,这里是docker ps的输出:

CONTAINER ID   IMAGE                                                                             COMMAND
  CREATED          STATUS                  PORTS                                       NAMES
4634eafd0ac1   xxxxxxxxxx.xxx.xxx.us-west-2.amazonaws.com/example_web_production:latest      "./docker/web-entryp…"   3 seconds ago    Up 2 seconds            0.0.0.0:3000->3000/tcp, :::3000->3000/tcp   ecs-example_web_production-10-web-aad0d39b88a584e02800
3385ac3e9bcd   amazon/amazon-ecs-agent:latest                                                    "/agent"
  37 hours ago     Up 37 hours (healthy)                                               ecs-agent

How can I get the Nginx config to recognize the web container running on the same instance?如何让 Nginx 配置识别在同一实例上运行的web容器?

I fixed it!我修好了它! Nginx could not find the web container because the links between the nginx and web containers were not set in the AWS ECS task definition. Nginx 找不到web容器,因为 AWS ECS 任务定义中未设置nginxweb容器之间的链接。 This is what my task definition looked like before:这是我之前的任务定义:

{
  ...
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "xxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/nginx:latest",
      "cpu": 0,
      "links": [],
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      ...
    },
    {
      "name": "web",
      "image": "xxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/web:latest",
      "cpu": 0,
      "links": [],
      "portMappings": [
        {
          "containerPort": 3000,
          "hostPort": 3000,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      ...
    }
  ]

  ...
}

Now it looks like the following (note the links ):现在它看起来如下(注意links ):

{
  ...
  "containerDefinitions": [
    {
      "name": "nginx",
      "image": "xxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/nginx:latest",
      "cpu": 0,
      "links": [
        "web"
      ],
      "portMappings": [
        {
          "containerPort": 80,
          "hostPort": 0,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      ...
    },
    {
      "name": "web",
      "image": "xxxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/web:latest",
      "cpu": 0,
      "links": [],
      "portMappings": [
        {
          "containerPort": 3000,
          "hostPort": 3000,
          "protocol": "tcp"
        }
      ],
      "essential": true,
      ...
    }
  ]

  ...
}

I had to use the old ECS console in order to add the web container as link;我必须使用旧的 ECS 控制台才能将web容器添加为链接; the new console doesn't have that option yet.新控制台还没有该选项。 See this SO answer for a screenshot.请参阅此 SO 答案以获取屏幕截图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM