According to the documentation, I should be able to provide a template directory and the container will automatically extract and replace environment variables, dropping the resulting files in /etc/nginx/conf.d/. I don't see that behavior.
Given the following files (copied and pasted from the example in the documentation):
docker-compose.yml:
version: '3.7'
services:
web:
image: nginx
volumes:
- ./templates:/etc/nginx/templates
ports:
- "8080:80"
environment:
- NGINX_HOST=foobar.com
- NGINX_PORT=80
templates/foobar.conf.template:
server {
listen ${NGINX_PORT};
}
I then run docker-compose up and attach a separate shell to my running web container.
From within the container I observe the following:
$ ls /etc/nginx/templates/
foobar.conf.template
# as expected
$ ls /etc/nginx/conf.d/
default.conf
# where is foobar.conf?
Thank you for your help and forgive me if I'm missing an obvious step!
Same problem here. I also tried manually running nginx -g 'daemon off;' -T and it's using the original default.confonly.
Using nginx:1.19.0-alpine
I've just tried it and it works.
Can you "docker pull nginx" or "nginx:1.19.0-alpine" and then docker-compouse up -d and then show the output of docker logs for the launched container?
For my case, I know what the problem was.
I was overriding CMD in my Dockefile. By taking a look at the content of the entrypoint script of the Nginx docker image:
if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
This means that, if your custom CMD does not start with nginx or nginx-debug (which was the case for me), none of the /docker-entrypoint.d scripts will be run because of how docker-entrypoint.sh works. The Nginx template compilation step is one of those scripts.
This is very unclear in the README of the image on dockerhub and I was only able to figure it out by looking at the code of the entrypoint script.
My solution was to simply add whatever I want to execute on entrypoint to a custom script and copy it to /docker-entrypoint.d/ so that it gets executed with the existing scripts, and just not overriding CMD or ENTRYPOINT in my custom image Dockerfile.
I think the README should be updated to reflect how this custom templating function actually works and how the entrypoint works too.
I also recommend taking a look at this how CMD and ENTRYPOINT interact.
I also recommend taking a look at this how
CMDandENTRYPOINTinteract.
Is there something there that should be considered?
Unfortunately that table isn't correct/complete. Everything under the ENTRYPOINT exec_entry p1_entry should start with /bin/sh -c 'exec_entry p1_entry' (the quotes are important since it is a single argument for the -c of /bin/sh) and CMD needs to be shown as extra arguments to the sh -c. While these extra args wouldn't usually have an effect, they do become arguments to the "script":
entrypoint/cmd examples:
$ docker build .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM bash
---> 2437bbe54138
Step 2/3 : ENTRYPOINT echo "'self': $0"; i=0; for arg in "$@"; do echo "$i: $arg"; let "i=i+1"; done
---> Running in 3f01c9594b33
Removing intermediate container 3f01c9594b33
---> 0bd7f79cb7f3
Step 3/3 : CMD arg1 arg2
---> Running in f0b15fc9586e
Removing intermediate container f0b15fc9586e
---> 583dd978ce72
Successfully built 583dd978ce72
19:47:44 [sauron@isengard ~/tmp/entrypoint]$ docker run -it --rm 583dd978ce72
'self': /bin/sh
0: -c
1: arg1 arg2
$ docker build .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM bash
---> 2437bbe54138
Step 2/3 : ENTRYPOINT echo "'self': $0"; i=0; for arg in "$@"; do echo "$i: $arg"; let "i=i+1"; done
---> Using cache
---> 0bd7f79cb7f3
Step 3/3 : CMD ["arg1", "arg2"]
---> Running in 44b2751d10b8
Removing intermediate container 44b2751d10b8
---> 67ce95e48e75
Successfully built 67ce95e48e75
$ docker run -it --rm 67ce95e48e75
'self': arg1
0: arg2
Regardless, the entrypoint and command here are working as designed (and very similar to most other images in the official-images program, e.g. redis).
@TamerShlash :
I was overriding
CMDin myDockefile.
Same for me (but ENTRYPOINT). Removing ENTRYPOINT from child image resolved the issue..
I just tried and it works for me.
My docker-compose file :
version: '3.7'
services:
nginx:
container_name: nginx
environment:
NGINX_PORT: 80
image: nginx
restart: always
volumes:
- ./docker/nginx/templates:/etc/nginx/templates:rw,cached
And my default.conf.template file :
server {
root /var/www/project/public;
listen ${NGINX_PORT};
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
# optionally disable falling back to PHP script for the asset directories;
# nginx will return a 404 error when files are not found instead of passing the
# request to Symfony (improves performance but Symfony's 404 page is not displayed)
# location /bundles {
# try_files $uri =404;
# }
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# optionally set the value of the environment variables used in the application
# fastcgi_param APP_ENV prod;
# fastcgi_param APP_SECRET <app-secret-id>;
# fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/index.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
You need to create your file and to copy it in /etc/nginx/templates.
This file will not be changed by nginx, but the content will be replaced and you should see it in /etc/nginx/conf.d/default.conf.
You will have in your default.conf file :
server {
root /var/www/project/public;
listen 80;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
# optionally disable falling back to PHP script for the asset directories;
# nginx will return a 404 error when files are not found instead of passing the
# request to Symfony (improves performance but Symfony's 404 page is not displayed)
# location /bundles {
# try_files $uri =404;
# }
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
# optionally set the value of the environment variables used in the application
# fastcgi_param APP_ENV prod;
# fastcgi_param APP_SECRET <app-secret-id>;
# fastcgi_param DATABASE_URL "mysql://db_user:db_pass@host:3306/db_name";
# When you are using symlinks to link the document root to the
# current version of your application, you should pass the real
# application path instead of the path to the symlink to PHP
# FPM.
# Otherwise, PHP's OPcache may not properly detect changes to
# your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126
# for more information).
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
# Prevents URIs that include the front controller. This will 404:
# http://domain.tld/index.php/some-path
# Remove the internal directive to allow URIs like this
internal;
}
# return 404 for all other php files not matching the front controller
# this prevents access to other php files you don't want to be accessible.
location ~ \.php$ {
return 404;
}
error_log /var/log/nginx/project_error.log;
access_log /var/log/nginx/project_access.log;
}
I hope this helps 馃槈
same problem with 1.9.15-alpine.
@abdounikarim may be, that works for the default.conf template, but the issue here is that we want it to work for a custom template.
OK, finally that works for me with 1.9.15-alpine :
cseunion-nginx | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
cseunion-nginx | 20-envsubst-on-templates.sh: Running envsubst on /etc/nginx/templates/default.conf.template to /etc/nginx/conf.d/default.conf
cseunion-nginx | 20-envsubst-on-templates.sh: Running envsubst on /etc/nginx/templates/site.conf.template to /etc/nginx/conf.d/site.conf
cseunion-nginx | /docker-entrypoint.sh: Configuration complete; ready for start up
Both files gets created.
This issue should be considered resolved.
Most helpful comment
I just tried and it works for me.
My docker-compose file :
And my
default.conf.templatefile :You need to create your file and to copy it in
/etc/nginx/templates.This file will not be changed by nginx, but the content will be replaced and you should see it in
/etc/nginx/conf.d/default.conf.You will have in your
default.conffile :I hope this helps 馃槈