Usually I don’t bother setting up SSL for local development but sometimes you’ll be using a service that requires it. Plus, more and more browsers are pushing you towards SSL all the time. [Side note, I wish someone would make a browser just for developers that gets out of the way and stops trying to protect us from ourselves when we’re working on local sites.]
A lot of folks are moving towards using Let’s Encrypt for free SSL certs but I’m either stubborn or dumb. Basically I didn’t want to figure out how to work it into a Docker container system, so I went old school and created a self-signed certificate. Please note you WILL need to add a “security exception” to your browser when you’re done with this process.
First off, you need openssl. I ~think~ I installed OpenSSL via Chocolatey install openssl on Windows, but honestly it was a while ago. You could also use the Openssl that comes in Ubuntu for Windows.
The command to create a self-signed cert is:
openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=US/ST=NC/L=Local/O=Dev/CN=mysite.local" -keyout ./ssl.key -out ./ssl.crt
First off, credit for this goes to StackExchange user THelper and in all honesty I don’t know exactly what all the parameters mean. (I’m so trusting!)
Here’s what you need to know to get this to work. ssl.key and ssl.crt are the filenames you’ll be generating. This string “/C=US/ST=NC/L=Local/O=Dev/CN=mysite.local” has to be customized:
/C = country code (I’m in the US)
/ST = state (North Carolina for me)
/L = locale… as you can see I fudged this
/O = Organization… again, fudged. All these matter if you’re creating a real cert to use online but for local.. meh
/CN = domain name. This one is important. I’m working on https://mysite.local
So edit that string and run the command and it should generate ssl.key and ssl.crt files.
I use docker-compose so I need to tweak my docker-compose.yml file to expose port 443 (the ssl port):
ports:
- 80:80
- 443:443
And in your dockerfile you need to copy the keys to your container. To do this, first drop them in the same directory as your docker file (I tried keeping them outside the directory but would get “Forbidden path outside the build context” errors).
Next, add this to your docker file:
RUN mkdir -p /etc/apache2/ssl/
COPY ./ssl.crt /etc/apache2/ssl/ssl.crt
COPY ./ssl.key /etc/apache2/ssl/ssl.key
So we’re creating a directory and copying the files into it.
Also remember to expose port 443 in your docker file:
EXPOSE 80
EXPOSE 443
Now you need to update your apache virtual hosts to support ssl.
Here’s part of my Virtual Host file, the first 3 lines are what we’re focused on, notice they match the directory we created in our docker file:
<VirtualHost *:443>
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/ssl.crt
SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
ServerName mysite.local
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
<Directory "/var/www/html">
Require all granted
AllowOverride All
Options Indexes FollowSymLinks
</Directory>
</VirtualHost>
And that should do it!