Docker Container: Centos 7, Apache, PHP 7.3, and SSL

May 11, 2021

On this post we are setting up a Docker Container for Centos 7, PHP 7.3, and SSL.
With this container we can have a local web server that accepts https connections.


To set up SSL on this container we are building our own Self-Signed Certificate which can be used for development and testing purposes. They are not intended to be used in a production environment.


For this Docker Container we have defined two files.
A Dockerfile and a script that will generate the certificate programmatically.

We are using the expect utility to automaticaly responds to the prompts of the SSL commands.


Dockerfile

Copy the following content on a file named Dockerfile


FROM centos:7

# Install Apache
RUN yum -y update
RUN yum -y install httpd httpd-tools mod_ssl openssl expect

# Install EPEL Repo
RUN rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm \
 && rpm -Uvh http://rpms.remirepo.net/enterprise/remi-release-7.rpm

# Install PHP
RUN yum --enablerepo=remi-php73 -y install php php-bcmath php-cli php-common php-gd php-intl php-ldap php-mbstring \
    php-mysqlnd php-pear php-soap php-xml php-xmlrpc php-zip

# Copy script that generates SSL certificate
COPY generate_certificate.exp /generate_certificate.exp

# Generate SSL certificate
RUN chmod +x /generate_certificate.exp \
 && ./generate_certificate.exp \
 && cp ca.crt /etc/pki/tls/certs \
 && cp ca.key /etc/pki/tls/private/ca.key \
 && cp ca.csr /etc/pki/tls/private/ca.csr

# Update Apache Configuration
RUN sed -E -i -e '/<Directory "\/var\/www\/html">/,/<\/Directory>/s/AllowOverride None/AllowOverride All/' /etc/httpd/conf/httpd.conf
RUN sed -E -i -e 's/DirectoryIndex (.*)$/DirectoryIndex index.php \1/g' /etc/httpd/conf/httpd.conf

# Update Apache SSL Configuration
RUN sed -E -i -e 's/\/etc\/pki\/tls\/certs\/localhost\.crt/\/etc\/pki\/tls\/certs\/ca.crt/g' /etc/httpd/conf.d/ssl.conf
RUN sed -E -i -e 's/\/etc\/pki\/tls\/private\/localhost\.key/\/etc\/pki\/tls\/private\/ca.key/g' /etc/httpd/conf.d/ssl.conf
RUN sed -E -i -e 's/#ServerName www\.example\.com\:443/ServerName www.example.com:443/g' /etc/httpd/conf.d/ssl.conf

EXPOSE 80 443

# Start Apache
CMD ["/usr/sbin/httpd","-D","FOREGROUND"]

You can download this Dockerfile, and the script, as a zipped file here


  • On the first part of the Dockerfile we install apache--as we have done on previous Docker Containers.
    Additionaly, for this container in particular we install mod_ssl, and openssl for the SSL certificates, and expect for the script that will create the certificate.

  • After that, we install the EPEL repository, and PHP 7.3.

  • We copy our script generate_certificate.exp into the Docker Container, and update its permissions to make it executable. Then we run it.

  • The generated certificate files will be copied to their appropiate folders in /etc/pki/tls/.

  • Then we update the Apache configuration on the files httpd.conf and ssl.conf.

Script to Generate SSL Certificate

Copy the following content on a file named generate_certificate.exp


#!/usr/bin/expect -f

# -------------------------
# Generate private key file
# -------------------------

spawn openssl genrsa -des3 -out ca.key 2048

expect "Enter pass phrase for ca.key:"
send -- "test\r"
expect "Verifying - Enter pass phrase for ca.key:"
send -- "test\r"

# ------------------------------------
# Generate certificate signing request
# ------------------------------------

spawn openssl req -new -key ca.key -out ca.csr

expect "Enter pass phrase for ca.key:"
send -- "test\r"
expect "Country Name (2 letter code)"
send -- "US\r"
expect "State or Province Name (full name)"
send -- "State\r"
expect "Locality Name (eg, city)"
send -- "City\r"
expect "Organization Name (eg, company)"
send -- "Company\r"
expect "Organizational Unit Name (eg, section)"
send -- "Section\r"
expect "Common Name (eg, your name or your server's hostname)"
send -- "localhost\r"
expect "Email Address"
send -- "email@localhost\r"

expect "A challenge password"
send -- "\r"

expect "An optional company name"
send -- "\r"

# --------------------
# Generate certificate
# --------------------

spawn openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt

expect "Enter pass phrase for ca.key:"
send -- "test\r"

# ---------------------------
# Remove certificate password
# ---------------------------

exec cp ca.key ca.tmp

spawn openssl rsa -in ca.tmp -out ca.key

expect "Enter pass phrase for ca.tmp:"
send -- "test\r"

exec rm ca.tmp

  • The generate_certificate.exp script contains the commands that will create the Self-Signed SSL Certificate.

Create the Docker Image and Container

Now we create the Docker Image.


docker build -t image_apache_ssl .

Then we create the Docker Container.

Notice that we need to indicate the path of our local folder that will be served as the root of the Apache Web Server, which in this example is /path_to/my_website. Replace it with the location of your site's root folder.


docker run -tid -p 4000:80 -p 4001:443 --name=container_apache_ssl -v /path_to/my_website:/var/www/html image_apache_ssl

After the Docker Container is created, we can go to the url https://localhost:4001 to open the local website.


Downloads

Dockerfile-apache-ssl.zip


Check the Dockerfile on Github here.

Download the Image from Docker Hub here.