Maryan
Maryan

Reputation: 1574

Nginx container fails to start on Cloud Run

I'm attempting to serve simple static page with Nginx on Cloud Run. But the container fails to properly start serving.

Container is starting, as shown by the debug lines echoed from docker-entrypoint.sh:

2019-05-26T22:19:02.340289Z testing config
2019-05-26T22:19:02.433935Z nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
2019-05-26T22:19:02.434903Z nginx: configuration file /etc/nginx/nginx.conf test is successful
2019-05-26T22:19:02.436605Z starting on 8080
2019-05-26T22:19:02.487188Z2019/05/26 22:19:02 [alert] 6#6: prctl(PR_SET_DUMPABLE) failed (22: Invalid argument)

and eventually terminates

2019-05-26T22:20:00.153060259ZContainer terminated by the container manager on signal 9.

In order to conform with the Cloud Run service contract specifically listening on $PORT the docker-entrypoint.sh performs $PORT substitution in conf.d/*.conf.

FROM nginx:1.15-alpine

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

COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

I'm pretty confident issue lies within docker-entrypoint.sh because once $PORT is hardcoded as 8080 and image looks like this:

FROM nginx:1.15-alpine

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

Cloud Run "runs" fine.

The code performing the substitution:

export NGINX_PORT=${PORT:-8080}
for f in $(find /etc/nginx/conf.d/ -type f -name '*.conf'); do
  envsubst '$NGINX_PORT' < $f > $f
done

NOTE: reading < $f and writing > $f to the same file works as tested by running the container locally.

Expected

Actual

Upvotes: 1

Views: 2535

Answers (2)

ahmet alp balkan
ahmet alp balkan

Reputation: 45196

I have published a blog post to show how to run nginx in a Cloud Run container (alongside with a process).

You can read the article here: https://ahmet.im/blog/cloud-run-multiple-processes-easy-way/ or take a look at the code repository at https://github.com/ahmetb/multi-process-container-lazy-solution

Basically, the nginx.conf file should be something like:

events {}

http {
    server {
        listen 8080; # Cloud Run PORT env variable
        access_log /dev/stdout;
        error_log /dev/stdout;

        # if you need to serve static access, specify an absolute path like below
        location /static/ {
            alias /src/static/;
        }

        # anything else is routed to your app that you would start on port 8081
        location / {
            proxy_pass http://localhost:8081;
        }
    }
}

daemon off;
pid /run/nginx.pid;

You can sort of safely hard code port 8080 in your nginx.conf as it's very unlikely to change in the foreseeable future on Cloud Run.

Upvotes: 5

Maryan
Maryan

Reputation: 1574

fixed by replacing

for f in $(find /etc/nginx/conf.d/ -type f -name '*.conf'); do
  envsubst '$NGINX_PORT' < $f > $f
done

with

sed -i "s/\${NGINX_PORT}/${NGINX_PORT}/g" /etc/nginx/conf.d/*.conf

and changing $NGINX_PORT -> ${NGINX_PORT} in *.conf files to avoid substitution ambiguities

Upvotes: 1

Related Questions