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"
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.
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à!