0

I am building a PHP Apache Web Service Docker Container Prototype.

  1. The first and simplest way was to create a Container with the official Image published by WordPress
    with a simple Dockerfile like:
FROM wordpress:latest

Which builds but than fails to run:

# docker run -it wordpress_local apache2-foreground
WordPress not found in /var/www/html - copying now...
Complete! WordPress has been successfully copied to /var/www/html
AH00534: apache2: Configuration error: No MPM loaded.

which is a Known Error unable to be fixed. So the Image is broken.
Other Images like php7-apache2 also produce the same Error.

  1. Unable to find a prebuild Image that would actually run I started to build an Image from scratch. It contains
  • Alpine Linux 3.12
  • Apache 2.4
  • PHP 7.3

with the Dockerfile:

# cat Dockerfile
FROM alpine:3.12
RUN apk add apache2 php7 php7-apache2 
ADD html/ /var/www/html/
WORKDIR /var/www/html/
CMD ["httpd", "-DNO_DETACH -DFOREGROUND -e debug"]

and a docker-compose.yml:

# cat docker-compose.yml
version: '3'
services:
  web:
    image: php_web_alpine
    build: .
    ports:
     - "8081:8081"

This builds nicely:

# docker build -t php_web_alpine .
Sending build context to Docker daemon  7.68 kB
Step 1/5 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/5 : RUN apk add apache2 php7 php7-apache2
 ---> Using cache
 ---> bf59e0c43f1f
Step 3/5 : ADD html/ /var/www/html/
 ---> 0fe4bfd871b2
Removing intermediate container cec9de242174
Step 4/5 : WORKDIR /var/www/html/
 ---> 03d3fe0a077f
Removing intermediate container b1763eb3e56b
Step 5/5 : CMD httpd -DNO_DETACH -DFOREGROUND -e debug
 ---> Running in 4ca69abc9f52
 ---> e3a33ae6e028
Removing intermediate container 4ca69abc9f52
Successfully built e3a33ae6e028

But than does not run because of a simple Configuration Error:

# docker-compose up 
Recreating phpalpine_web_1 ... done
Attaching to phpalpine_web_1
web_1  | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.20.0.2. Set the 'ServerName' directive globally to suppress this message
phpalpine_web_1 exited with code 0

It needs just to fill the httpd.conf Configuration File with the correct values.

So, how can I fill the Web Service Configuration Files (Apache and PHP and others, etc ...) at Build Time to get a nice reproducible Build ?

2 Answers2

0

Nothing could be more easy, add the COPY directive to your Dockerfile.

it will look like something like this:

COPY MyWebConf.conf /etc/apache2/sites-enabled/

It will copy and overwrite any existing configuration with the same name.

If you want to test the configuration before perform a build of the image mount it in the run time of the container.

AtomiX84
  • 415
  • 2
  • 7
  • I did as you told `Step 3/6 : COPY MyWeb.conf /etc/apache2/sites-enabled/` but the Error stays: `web_1 | AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.20.0.2. Set the 'ServerName' directive globally to suppress this message`. MyWeb.conf Content: `ServerName localhost Listen 8081` additionally I won't work with all configurations like explained in the official Documentation at: https://httpd.apache.org/docs/2.4/mod/mpm_common.html#listen – Bodo Hugo Barwich Jul 10 '20 at 18:39
  • That is not a Error, it is a WARNING, it say to you that apache cannot determinate the server name, and is pretty normal in a container due the hostname of the container is an hash. This WARNING do not stop apache2 to work. If apache2 isn't working as you expect there is another error. If you want to remove it anyway in this discussion have a way to resolve it: https://stackoverflow.com/questions/46266527/could-not-reliably-determine-the-servers-fully-qualified-domain-name-how-to | EDIT: another way to fix that warning is add the directive "ServerName namehere" in the apache2 configuration. – AtomiX84 Jul 13 '20 at 07:02
  • From your like I see it is a common issue that people trying to build an **Apache Docker Container** stumble over. There are many _workarounds_ that try to suppress this particular symptom of the common problem "**How to get Access to the Configurations Files?**" and to configure them as it should be done and is needed for a **Full Web Server** ready for Production. – Bodo Hugo Barwich Jul 13 '20 at 13:45
  • Not properly configured the Container is UP: `# docker-compose ps phpalpine_web_1 httpd -DNO_DETACH -DFOREGR ... Up 0.0.0.0:8081->8081/tcp` but it is **not working**: `$ wget -S -O - "http://localhost:8081" --2020-07-13 15:41:31-- http://localhost:8081/ Resolving localhost (localhost)... ::1, 127.0.0.1 Connecting to localhost (localhost)|::1|:8081... connected. HTTP request sent, awaiting response... Read error (Connection reset by peer) in headers. Retrying. ` – Bodo Hugo Barwich Jul 13 '20 at 14:49
0

I figured out a way to get Full Access to just any Configuration File.

I developed my solution from this tutorial about Database Container Configuration and Build
MySQL Container Build and Configuration

As well from the Official Documentation at:
Docker Volumes Configuration and Usage

This is a Multi Step Process but which only needs to be done when the Original Configuration File changed. The Concept consists of the Export and Reimport of the configured Configuration Files at Container Build Time.

  1. I create a Local Directory where to export the Original Configuration Files to.
    $ mkdir config
    $ mkdir uploads/config -p
    $ vi Dockerfile
    RUN mkdir /home/uploads
    VOLUME /home/uploads
  1. To access the Image I launch it mounting the Local Directory to the Volume Mount Point
    (Important is the :Z to be able to export anything there)
    # docker run  -it --entrypoint sh -v /absolute/path/uploads:/home/uploads:Z php_web_alpine
  1. Now I can access the Configuration Directories and copy any File I need to edit to the Export Directory
/var/www/html # cd /etc/ap*
/etc/apache2 # pwd
/etc/apache2
/etc/apache2 # ls -lah
total 188K   
drwxr-xr-x    1 root     root        4.0K Jul  7 11:30 .
drwxr-xr-x    1 root     root          62 Jul  7 11:33 ..
drwxr-xr-x    2 root     root        4.0K Jul  7 11:30 conf.d
-rw-r--r--    1 root     root       17.3K Jul  7 11:30 httpd.conf
-rw-r--r--    1 root     root       17.4K Apr  1 18:18 httpd.conf.save
-rw-r--r--    1 root     root       17.4K Jul  7 11:30 httpd.conf.setup.1
-rw-r--r--    1 root     root       17.3K Jul  7 11:30 httpd.conf.setup.2
-rw-r--r--    1 root     root       17.3K Jul  7 11:30 httpd.conf.setup.3
-rw-r--r--    1 root     root       12.8K Apr  1 18:18 magic
-rw-r--r--    1 root     root       59.4K Apr  1 18:18 mime.types
/etc/apache2 # cp httpd.conf /home/uploads/config/apache/
/etc/apache2 # cd conf.d
/etc/apache2/conf.d # ls -lah
total 40K    
drwxr-xr-x    2 root     root        4.0K Jul  7 11:30 .
drwxr-xr-x    1 root     root        4.0K Jul  7 11:30 ..
-rw-r--r--    1 root     root        2.2K Apr  1 18:18 default.conf
-rw-r--r--    1 root     root        1.2K Apr  1 18:18 info.conf
-rw-r--r--    1 root     root        5.0K Apr  1 18:18 languages.conf
-rw-r--r--    1 root     root        4.3K Apr  1 18:18 mpm.conf
-rw-r--r--    1 root     root         378 Jun 12 12:27 php7-module.conf
-rw-r--r--    1 root     root         732 Apr  1 18:18 userdir.conf
/etc/apache2/conf.d # cp mpm.conf /home/uploads/config/apache/
/var/www/html # cd /etc/php7
/etc/php7 # pwd
/etc/php7
/etc/php7 # mkdir /home/uploads/config/php/
/etc/php7 # cp php.ini /home/uploads/config/php/
/etc/apache2 # exit
  1. After the Export I find the Configuration Files from the Image in the Local Directory and can move them to the Configuration Directory for the Container Build
# cd config
# pwd
/apsolute/path/uploads/config
# ls -lah apache
insgesamt 28K
drwxr-xr-x. 2 user_name user_group   38 jul  7 12:45 .
drwxr-xr-x. 3 user_name user_group   19 jul  7 12:25 ..
-rw-r--r--. 1 root  root    18K jul  7 12:45 httpd.conf
-rw-r--r--. 1 root  root   4,4K jul  7 12:45 mpm.conf
# ls -lah php
insgesamt 72K
drwxr-xr-x. 2 root  root    20 jul  7 13:32 .
drwxr-xr-x. 4 user_name user_group  29 jul  7 13:33 ..
-rw-r--r--. 1 root  root   70K jul  7 13:32 php.ini
# mv apache ../../config/
# mv php ../../config/
# cd ../../config/
  1. Now I can edit the Configuration Files completely, easily and naturally.
  2. I include the configured Configuration Files in the Dockerfile to build a Completely Configured Web Server Container
  • Keeping in mind that Configuration Files can change over time I will avoid to clobber the original files without having a save copy. In the nice RPM style with the .save Extension
$ vi Dockerfile
COPY config/apache/httpd.conf /etc/apache2/httpd.conf.setup
COPY config/apache/mpm.conf /etc/apache2/conf.d/mpm.conf.setup
COPY config/php/php.ini /etc/php7/php.ini.setup
RUN cd /etc/apache2\
  && mv httpd.conf httpd.conf.save\
  && cp -f httpd.conf.setup httpd.conf
RUN cd /etc/apache2/conf.d\
  && mv mpm.conf mpm.conf.save\
  && cp -f mpm.conf.setup mpm.conf
RUN cd /etc/php7\
  && mv php.ini php.ini.save\
  && cp -f php.ini.setup php.ini
  1. Now I can build the Container savely
# docker build -t php_web_alpine .
Sending build context to Docker daemon 122.9 kB
Step 1/12 : FROM alpine:3.12
 ---> a24bb4013296
Step 2/12 : RUN apk add apache2 php7 php7-apache2
 ---> Using cache
 ---> bf59e0c43f1f
Step 3/12 : COPY MyWeb.conf /etc/apache2/sites-enabled/
 ---> Using cache
 ---> f38a0d067fdd
Step 4/12 : COPY config/apache/httpd.conf /etc/apache2/httpd.conf.setup
 ---> d29e5b94e1ab
Removing intermediate container 9efaed4b5da5
Step 5/12 : COPY config/apache/mpm.conf /etc/apache2/conf.d/mpm.conf.setup
 ---> 286100656541
Removing intermediate container 2cc1ebac920a
Step 6/12 : COPY config/php/php.ini /etc/php7/php.ini.setup
 ---> cb12fe5aa008
Removing intermediate container 7dd9bde72996
Step 7/12 : RUN cd /etc/apache2  && mv httpd.conf httpd.conf.save  && cp -f httpd.conf.setup httpd.conf
 ---> Running in d29ed8f6c3a1

 ---> dc1dcbc6adf6
Removing intermediate container d29ed8f6c3a1
Step 8/12 : RUN cd /etc/apache2/conf.d  && mv mpm.conf mpm.conf.save  && cp -f mpm.conf.setup mpm.conf
 ---> Running in 1667394701de

 ---> ecf4b961add4
Removing intermediate container 1667394701de
Step 9/12 : RUN cd /etc/php7  && mv php.ini php.ini.save  && cp -f php.ini.setup php.ini
 ---> Running in 55502cdfc2da

 ---> c32bfcb13c4a
Removing intermediate container 55502cdfc2da
Step 10/12 : ADD html/ /var/www/html/
 ---> c458eec870e2
Removing intermediate container 2359ebc7b630
Step 11/12 : WORKDIR /var/www/html/
 ---> 56790c506e0d
Removing intermediate container ef739299fb95
Step 12/12 : ENTRYPOINT httpd -DNO_DETACH -DFOREGROUND -e info
 ---> Running in cb6d5ff8b90c
 ---> e2abe6e4091a
Removing intermediate container cb6d5ff8b90c
Successfully built e2abe6e4091a

Now I can launch it and it runs smoothly:

# docker-compose up -d
Recreating phpalpine_web_1 ... done
# docker-compose ps
        Name               Command                         State     Ports         
---------------------------------------------------------------------------------------
phpalpine_web_1            httpd -DNO_DETACH -DFOREGR ...   Up      0.0.0.0:8081->8081/tcp

I find that the Web Server is Up and Running:

# netstat -lpn|grep -i :80
tcp6       0      0 :::8081                 :::*                    LISTEN      31528/docker-proxy- 
# wget -S -O - "http://localhost:8081"
--2020-07-13 15:43:55--  http://localhost:8081/
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:8081... connected.
HTTP request sent, awaiting response... 
  HTTP/1.1 200 OK
  Date: Mon, 13 Jul 2020 14:43:55 GMT
  Server: Apache/2.4.43 (Unix)
  X-Powered-By: PHP/7.3.19
  Content-Length: 0
  Keep-Alive: timeout=5, max=100
  Connection: Keep-Alive
  Content-Type: text/html; charset=UTF-8
Length: 0 [text/html]
Saving to: ‘STDOUT’

    [ <=>                                                       ] 0           --.-K/s   in 0s      

2020-07-13 15:43:55 (0,00 B/s) - written to stdout [0/0]

Discussion:

  • Why do I want export the Original Configuration Files?
    Configuration Files and Package Layout are very different from Distribution to Distribution. I might not have the correct ones and so the Service might turn out to be configured not as intended.
  • Why do I want to preserve the Original Configuration Files at Build Time?
    At Build Time the Packages might get updated and some Update might change something within the Configurations as it happens often with MySQL / MariaDB. To troubleshoot any Issue I need to be able to compare with the Original Configuration Files.