23

I'm dockerizing our current old app. We use several services but the one I have issues on is the php, apache, and specifically the https for apache. I am using "php:5.6.30-apache" image, so I have php and apache pre-installed.

Now I changed the "000-default.conf" with this content:

<VirtualHost *:80>
    ServerAdmin admin@admin.io
    DocumentRoot /var/www/html/app/htdocsAdmin
    ServerName admin.local.app.io
    CustomLog /var/log/apache2/app.admin.access.log "trueip_combined"
    ErrorLog /var/log/apache2/app.admin.error.log
    <Directory /var/www/html/app/htdocsAdmin>
        AllowOverride Options FileInfo AuthConfig
        Require all granted
    </Directory>
</VirtualHost>

This is my docker file:

FROM php:5.6.30-apache

MAINTAINER Tzook Bar Noy

ADD default /etc/apache2/sites-available/000-default.conf


RUN apt-get update \
  && apt-get install -y apt-utils \
  && apt-get install -y php5-dev php5-memcached \
  && apt-get install -y memcached



RUN apt-get update && apt-get install -y apt-utils
RUN apt-get install -y libz-dev libmemcached-dev
RUN pecl install memcached-2.2.0
RUN echo extension=memcached.so >> /usr/local/etc/php/conf.d/memcached.ini

RUN a2enmod rewrite
RUN a2enmod ssl


EXPOSE 80
EXPOSE 443

Don't mind the memcached stuff, just see that I enable "ssl" and expose ports 80,443

This is being ran with docker-compose:

php:
build:
  context: ./php
  dockerfile: Dockerfile
ports:
  - "80:80"
  - "443:443"
volumes:
  - ./../../:/var/www/html
networks:
  - appnet
tty: true

but after all of that, I still get this from chrome:

"ERR_SSL_PROTOCOL_ERROR"

As requested in comments my "docker ps" response: enter image description here

THelper
  • 15,333
  • 6
  • 64
  • 104
Tzook Bar Noy
  • 11,337
  • 14
  • 51
  • 82

2 Answers2

33

Besides enabling ssl and exposing port 443, you need to create a (self-signed) certificate + private key and make sure Apache has access to those.

I recommend using openSSL to create a self-signed certificate:

openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj \
    "/C=../ST=...../L=..../O=..../CN=..." \
    -keyout ./ssl.key -out ./ssl.crt

Instead of the dots (...) fill in your 2-letter country code (/C), the name of your state or province (/ST), the name of your locality (/L), the name of your organization (/O) and your server FQDN (/CN)

Then add the following lines to your docker file:

COPY ./path/to/ssl.crt /etc/apache2/ssl/ssl.crt
COPY ./path/to/ssl.key /etc/apache2/ssl/ssl.key
RUN mkdir -p /var/run/apache2/

I'm not sure the last line is really necessary, but in my docker container the folder didn't exist yet causing Apache to fail on startup.

Finally in your 000-default.conf file you need to add something like this:

<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile /etc/apache2/ssl/ssl.crt
  SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
  ....
</VirtualHost>

Note that when you use self-signed certificates most browsers will alert you that "Your connection is not secure" (Firefox) or "Invalid certificate" (Chrome). This is because there is no valid security chain to a trusted CA. Most browsers allow you to continue your request or add the site as an exception so the warning isn't displayed anymore.

THelper
  • 15,333
  • 6
  • 64
  • 104
  • In my case I used default-ssl.conf file for it, but forgot to enable the site (`a2ensite default-ssl`). This caused me the error `SSL_ERROR_RX_RECORD_TOO_LONG` when accessing the site. I hope it helps who face the same issue. :) – Ricardo Martins Jul 02 '21 at 06:57
  • what is `./path/to/ssl.crt ` ie what determines what the path is? Is that the DIR where docker is run from? My WORKDIR? – James Jul 25 '21 at 12:06
  • 1
    @James The assumption here is that Docker is running on the same device where you created the ssl files, so the COPY command is copying those files from the location where you created them to the Apache folder in the Docker container. – THelper Jul 26 '21 at 09:00
17

Here's how I enabled Apache SSL in Docker for local development. This is with Docker running an Ubuntu image on macOS (though mkcert also works with Linux and Windows):

• In macOS, install mkcert:

brew install mkcert
brew install nss # if you use Firefox

mkcert makes it easy to create and install SSL certificates for local development use.

• Create the SSL certificates:

mkcert mysite.localhost someothersite.localhost localhost 127.0.0.1 ::1

This will install them on macOS for you, but will also leave a copy of them in the current working directory:

mysite.localhost+4-key.pem
mysite.localhost+4.pem

• Make the two .pem files available to your Docker container. e.g.: move them with your container's config files and add the like of this:

- ./config/ssl:/etc/apache2/ssl/

• Open port 443 in the container's docker-compose:

- "443:443"

(And you should certainly EXPOSE 443 in the image too, though for some reason it worked for me without doing so.) (Edit: EXPOSE is purely documentation and performs no actions per the documentation)

• Enable SSL in Apache:

RUN ln -s /etc/apache2/mods-available/ssl.load  /etc/apache2/mods-enabled/ssl.load

Though, technically, I did this from within my running container first, followed by an apachectl restart. Makes it easier to test things out and make sure everything worked before committing rebuilding the image.

• Configure your website(s) in Apache for them to use SSL by editing mysite.localhost and any other domain you want to use SSL with:

<VirtualHost *:443>
    …
    SSLEngine on
    SSLCertificateFile "/etc/apache2/ssl/clickandspeak.localhost+4.pem"
    SSLCertificateKeyFile "/etc/apache2/ssl/clickandspeak.localhost+4-key.pem"
    …
</VirtualHost>

…just duplicate your old config from <VirtualHost *:80>, change the port to 443, and add the three lines above.

Rebuild the image and restart the container along the way as needed.

…et voilà!

Fabien Snauwaert
  • 4,995
  • 5
  • 52
  • 70
  • 1
    Thanks a lot. I have to add following to enable the SSL : ```COPY ./config/ssl /etc/apache2/ssl/ COPY ./config/default-ssl.conf /etc/apache2/sites-available/default-ssl.conf RUN ln -s /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enabled/ssl.load RUN a2ensite default-ssl.conf ``` – CZ54 Jul 08 '21 at 09:32