我正在AWS ECS上设置Ruby on Rails应用程序,并希望将我的网站example.com重定向到www.example.com。我遇到了一个问题,重定向我的Nginx上游服务器到我的Rails应用程序。一切似乎在本地工作良好。我的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
这是我的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
FROM nginx:1.23-alpine
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
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;
}
}
如果有帮助,下面是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
如何让Nginx配置识别在同一实例上运行的web
容器?
我修好了!Nginx找不到web
容器,因为nginx
和web
容器之间的链接没有在AWS ECS任务定义中设置。这是我的任务定义之前的样子:
{
...
"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,
...
}
]
...
}
现在看起来像这样(注意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,
...
}
]
...
}
为了添加web
容器作为链接,我不得不使用旧的ECS控制台;新主机还没有这个选项。请看这个SO答案的截图。