It isn't really necessary to use 80 as we can publish the port to any host port. Using port 80 however makes apache start as root, which is a security downgrade. How about changing it to 8080?
Making that change will break things for all existing users of this image. The security situation for Apache dropping privileges from root is pretty well understood, so I'm not sure that the benefits outweigh the breakage for existing users, particularly since there is no good way to communicate the change to users.
@md5 You can run a container and docker top it, you'll see a root process in running.
Even if you want to keep compatibility, how about the php-fpm image? This image also runs a root process but it never exposes a privileged port.
@xuhdev Indeed. It's also true that if you use lsof or the equivalent on the processes inside that container, you'll see that the root owned process is the one that has port 80 bound.
@xuhdev You might also be interested in this discussion around the logstash image and allowing non-root to bind "privileged" ports: https://github.com/docker-library/logstash/pull/14
In that case, setcap on the java binary is being proposed to allow non-root to bind the syslog port 514.
Also a related issue in Docker https://github.com/docker/docker/issues/8460
Seeing as the latest best practice from Docker (https://www.youtube.com/watch?v=LmUw2H6JgJo) is to not use a restricted port: Here is what I've done locally https://github.com/docker-library/php/pull/190
It does require users to add the -p 80:8080 or -p 443:8443 but seems like the shortest path to get the container updated. Documentation would look like https://github.com/deekthesqueak/docs/commit/be93e6c141ff52081bcc251adc60f2c2fd1df0c6
IMO it's worth pointing out that Docker now supports using user namespaces to remap your container root user to another non-root user on the host, which should make this essentially a non-issue.
For further configuration modification of this variety, I think our best (most maintainable) solution is going to be to have users provide custom configuration for custom requirements.
At the startup, you can always do stuff like
FROM php:7.0-apache
ENV PORT 80
ENTRYPOINT []
CMD sed -i "s/80/$PORT/g" /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf && docker-php-entrypoint apache2-foreground
Something like that will work : docker run -d -p 5000:5000 -e PORT=5000 'my_image'
Given both the solutions in this thread, and the solution in https://github.com/moby/moby/issues/8460#issuecomment-312459310, I believe this is now a non-issue, and as such I'm going to close. I have personally used --sysctl net.ipv4.ip_unprivileged_port_start=0 to successfully run this image as-is without any modifications as a non-root user:
$ docker run -it --rm --user 1000:1000 --sysctl net.ipv4.ip_unprivileged_port_start=0 --tmpfs /run:uid=1000 php:7.2-apache
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.19. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.18.0.19. Set the 'ServerName' directive globally to suppress this message
[Fri Dec 22 21:00:37.781952 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.25 (Debian) PHP/7.2.0 configured -- resuming normal operations
[Fri Dec 22 21:00:37.781974 2017] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
Restricted ports isn't the only reason to want this. For example, running in Google Cloud Run requires that you listen on a port specified in an environment variable; you don't get to choose your own port.
The sed idea isn't going to pass anyone's code review - it's far too likely to break mysteriously on an update.
ENV PORT 80
ENTRYPOINT []
CMD sed -i "s/80/$PORT/g" /etc/apache2/sites-available/000-default.conf /etc/apache2/ports.conf && docker-php-entrypoint apache2-foreground
ERROR [stage-0 13/14] COPY cloud-run-entrypoint.sh /usr/local/bin/
Most helpful comment
At the startup, you can always do stuff like
Something like that will work :
docker run -d -p 5000:5000 -e PORT=5000 'my_image'