codesuki / ecs-nginx-proxy

Reverse proxy for AWS ECS. Lets you address your docker containers by sub domain.
MIT License
98 stars 23 forks source link

server_names_hash issue #5

Closed simplesteph closed 7 years ago

simplesteph commented 7 years ago

Running the ecs-nginx-proxy without any special config, I'm getting the following error as soon as I introduce a service:

2017/03/06 03:44:09 found cluster name to be: test-reverse-proxy
2017/03/06 03:44:09 updating config
2017/03/06 03:44:10 container is own container. skipping
2017/03/06 03:44:10 running signal command
2017/03/06 03:44:10 ===== output start =====
2017/03/06 03:44:10 2017/03/06 03:44:10 [emerg] 14#14: could not build server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 64

2017/03/06 03:44:10 ===== output end =====
2017/03/06 03:44:10 failed to run signal command
2017/03/06 03:44:10 error:  exit status 1
2017/03/06 03:44:10 []

Any idea what could be wrong?

The task definition for the container is:

{
  "requiresAttributes": [
    {
      "value": null,
      "name": "com.amazonaws.ecs.capability.logging-driver.json-file",
      "targetId": null,
      "targetType": null
    },
    {
      "value": null,
      "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19",
      "targetId": null,
      "targetType": null
    }
  ],
  "taskDefinitionArn": "arn:aws:ecs:ap-southeast-2:1234567890:task-definition/hello-world:1",
  "networkMode": "bridge",
  "status": "ACTIVE",
  "revision": 1,
  "taskRoleArn": null,
  "containerDefinitions": [
    {
      "volumesFrom": [],
      "memory": 128,
      "extraHosts": null,
      "dnsServers": null,
      "disableNetworking": null,
      "dnsSearchDomains": null,
      "portMappings": [
        {
          "hostPort": 81,
          "containerPort": 80,
          "protocol": "tcp"
        }
      ],
      "hostname": null,
      "essential": true,
      "entryPoint": null,
      "mountPoints": [],
      "name": "hello-world",
      "ulimits": null,
      "dockerSecurityOptions": null,
      "environment": [
        {
          "name": "VIRTUAL_HOST",
          "value": "helloworld.test-reverse-proxy.a.little.bit.longer"
        }
      ],
      "links": null,
      "workingDirectory": null,
      "readonlyRootFilesystem": null,
      "image": "tutum/hello-world",
      "command": null,
      "user": null,
      "dockerLabels": null,
      "logConfiguration": {
        "logDriver": "json-file",
        "options": {
          "max-size": "200m"
        }
      },
      "cpu": 10,
      "privileged": null,
      "memoryReservation": null
    }
  ],
  "placementConstraints": [],
  "volumes": [],
  "family": "hello-world"
}
codesuki commented 7 years ago

http://charles.lescampeurs.org/2008/11/14/fix-nginx-increase-server_names_hash_bucket_size Try adding that to the template.

simplesteph commented 7 years ago

@codesuki yes it seems the domain name is too long. Is there an easy way to do so without having to build my own ecs-nginx-proxy and ecs-gen image? Otherwise no worries I'll take care of that then do a PR

codesuki commented 7 years ago

You could run with docker run -v src:dst to map some new template file and replace the CMD to use that.

simplesteph commented 7 years ago

hmmm it doesn't seem to work? Any idea?

[ec2-user@ip-10-13-81-40 ~]$ docker run 123456789.dkr.ecr.ap-southeast-2.amazonaws.com/ecs-nginx-proxy:latest cat nginx.tmpl
server_names_hash_bucket_size 64;
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';
access_log off;
# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
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 $proxy_x_forwarded_proto;
# Mitigate httpoxy attack (see https://github.com/jwilder/nginx-proxy for details)
proxy_set_header Proxy "";
server {
        server_name _; # This is just an invalid value which will never trigger on a real hostname.
        listen 80;
        access_log /var/log/nginx/access.log vhost;
        location = / {
                return 200 'nginx is alive';
                add_header Content-Type text/plain;
        }
        location / {
                return 503;
        }
}

{{ range $domain, $container := . }}
upstream {{ $domain }} {
    {{ range $_, $value := $container }}
         server {{ $value.Address }}:{{ $value.Port }};
    {{ end }}
}
server {
        server_name {{ $domain }};
        listen 80;
        access_log /var/log/nginx/access.log vhost;
        location / {
                proxy_pass http://{{ $domain }};
        }
}
{{ end }}

log

2017/03/06 04:50:55 found cluster name to be: test-reverse-proxy
2017/03/06 04:50:55 updating config
2017/03/06 04:50:56 container is own container. skipping
2017/03/06 04:50:56 running signal command
2017/03/06 04:50:56 ===== output start =====
2017/03/06 04:50:56 2017/03/06 04:50:56 [emerg] 14#14: could not build server_names_hash, you should increase server_names_hash_bucket_size: 64
nginx: [emerg] could not build server_names_hash, you should increase server_names_hash_bucket_size: 64

2017/03/06 04:50:56 ===== output end =====
2017/03/06 04:50:56 failed to run signal command
2017/03/06 04:50:56 error:  exit status 1
2017/03/06 04:50:56 []
simplesteph commented 7 years ago

nevermind I had to increase it to 128. Should we put this as a default? I'm happy to do a PR

It'd be also good to do a deeper PR and not make the proxy crash is someone pushes a VIRTUAL_HOST that's too long for the proxy. That's a big risk in my opinion?

simplesteph commented 7 years ago

FYI nginx-proxy has the fix already https://github.com/jwilder/nginx-proxy/blob/6554a1cf287f79a23bff84672601422caca8cb10/Dockerfile#L14

codesuki commented 7 years ago

Thanks for the report and the PR!

simplesteph commented 7 years ago

You're welcome. Still unsure about how your proxy would break if someone tried to enter a very very long name, but I guess that's unlikely at the 128 limit

codesuki commented 7 years ago

Well if somebody needs support for that they could fix it by replacing the template which is something that we could leave to the user. You set a good default I think.