问题
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
- nginx configuration gets
$PORT
placeholder substituted with actual values - container runs and listens on
$PORT
on Cloud Run
Actual
- container fails to run on Cloud Run
- container runs and listens on
$PORT
locally
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/56318026/nginx-container-fails-to-start-on-cloud-run