nginxinc / docker-nginx

Official NGINX Dockerfiles
BSD 2-Clause "Simplified" License
3.26k stars 1.73k forks source link

documentation on custom CMD/ENTRYPOINT #875

Open ne555 opened 7 months ago

ne555 commented 7 months ago
# alpine-slim/Dockerfile
ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]
# entrypoint/docker-entrypoint.sh
if [ "$1" = "nginx" ] || [ "$1" = "nginx-debug" ]; then
#  code that executes /docker-entrypoint.d/ scripts

so for a custom CMD to actually execute those scripts it has to be on the form

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

but there is no such mention on the documentation https://hub.docker.com/_/nginx/

thresheek commented 7 months ago

Hi @ne555!

Can you elaborate on what exactly needs to be documented and why?

We do indeed only run customization via docker-entrypoint.sh when nginx is requested as first argument CMD since it does not make sense to run them when you do e.g. docker run -ti --rm nginx:latest bash or similar.

kale1d0code commented 3 months ago

I was caught out by this today. I am trying to get nginx to trust the ip addresses of the services in front of it. nginx does not provide functionality to add multiple ip address within the set_real_ip_from directive I also don't want to allow for entire directives to be stored in an environment variable as this could allow for arbitrary configuration in an environment variable like the following:

eg

$config = "
set_real_ip_from 253.26.12.14
set_real_ip_from 10.0.0.4
"

to get around this, I added a custom command in my docker-compose file so that nginx would generate a file with the correct contents for ip forwarding however the container stopped generating templates after I added this custom command.

    command: >
      /bin/sh -c '
        # Define the configuration file path
        CONFIG_FILE="/etc/nginx/conf.d/trusted_proxies.conf";

        # Initialize an empty string to store the configuration
        trusted_ips="";

        # Iterate over the space-separated IPs in NGINX_TRUSTED_PROXY_IPS
        for ip in $NGINX_TRUSTED_PROXY_IPS; do
            # Simple IP validation: check if it matches the basic IP/subnet pattern
            if echo "$ip" | grep -Eq "^[0-9]{1,3}(\.[0-9]{1,3}){3}(/[0-9]{1,2})?$"; then
                trusted_ips="${trusted_ips}set_real_ip_from ${ip};\n";
            else
                echo "Invalid IP address: $ip";
                exit 1;
            fi
        done

        # Generate the Nginx configuration file
        echo -e "${trusted_ips}real_ip_header ${NGINX_TRUSTED_PROXY_HEADER};\nreal_ip_recursive on;" > $CONFIG_FILE;

        # Start Nginx
        nginx -g "daemon off;";
      '

I also tried adding this as a config file within /docker-entrypoint.d/ however nginx refuses to run it as it is not executable.

I did expect that the entrypoint script would still generate the templates but this will only happen if a custom command is not provided or if the entrypoint is also called within the command

thresheek commented 3 months ago

Hi @kale1d0code,

You can just create a docker-entrypoint.d shell script to generate the file contents you'd like, and then include it in the configuration files for your service. No need for a special entrypoint or cmd.