After a bit of experimenting, I've successfully managed to get it to work. Thanks to @yanokwa for pointing me in the right direction.
What I actually end up with:
One machine, one IP address, two services:
- an Apache server that was already running on the machine and could not be altered
- ODK represented by an nginx server in Docker
A reverse proxy server was needed to separate requests for Apache and ODK. The separation is ensured by setting ODK to listen to custom ports. Apache keeps listening to standard ports :80 and :443.
Assumptions:
- ODK was already installed, configured to listen to custom ports :4480 and :4443. This configuration does not work perfectly, which is why we're here. It's probably better if you apply these steps appropriately during installation.
- The current domain
my.example.com
already has a Let's Encrypt certificate. - Root access.
There were three necessary things to do:
- Register a new subdomain:
survey.example.com
- Set up a reverse proxy
- Rebuild nginx
Disclaimer: the order of these steps is what it probably should be, but I didn't try it this way. Due to the experimenting involved the actual order of successful steps is shrouded in mystery.
Setting a new subdomain
Add a new DNS record. Then add the new subdomain to your Let's Encrypt certificate:
sudo certbot --expand -d my.example.com -d survey.example.com
The reverse proxy
Add the following content to httpd.conf. The three marked lines were probably added by certbot. I'm pretty sure I didn't put them there. (I ran certbot after modifying httpd.conf.) If certbot does not add those three lines, add them manually. Be sure the addresses are correct and the files exist.
<VirtualHost *:80>
ServerName survey.example.com
ProxyPreserveHost On
ProxyPass / http://localhost:4480/ # 4480 is the alternative for port 80
ProxyPassReverse / http://localhost:4480/
</VirtualHost>
<VirtualHost _default_:443>
SSLProxyEngine On
ServerName survey.example.com
ProxyPreserveHost On
ProxyPass / https://localhost:4443/ # 4443 is an alternative for 443
ProxyPassReverse / https://localhost:4443/
SSLCertificateFile /etc/letsencrypt/live/my.example.com/fullchain.pem # added by certbot
SSLCertificateKeyFile /etc/letsencrypt/live/my.example.com/privkey.pem # added by certbot
Include /etc/letsencrypt/options-ssl-apache.conf # added by certbot
</VirtualHost>
After saving the config file don't forget to reload it.
sudo apachectl -k graceful
Rebuild nginx
.env
is now this:
SSL_TYPE=letsencrypt
DOMAIN=survey.example.com
SYSADMIN_EMAIL=my.mail@example.com
I didn't have to change docker-compose.yml
but I'm adding it here to be complete.
This just the nginx chapter, and only the two commented lines are going to be changed.
nginx:
container_name: nginx
build:
context: .
dockerfile: nginx.dockerfile
depends_on:
- service
environment:
- SSL_TYPE=${SSL_TYPE}
- DOMAIN=${DOMAIN}
- CERTBOT_EMAIL=${SYSADMIN_EMAIL}
ports:
- "4480:80" # on the left goes the alternative port number, on right the real port
- "4443:443" # and the same applies for https
healthcheck:
test: [ "CMD-SHELL", "nc -z localhost 443 || exit 1" ]
Then run docker-compose build
in your working folder and run the usual steps:
docker-compose up --no-start
sudo systemctl start docker-compose@central
Check systemctl status docker-compose@central
and docker ps -a
. Everything green, up and healthy? Good. Now it should work. If not, try the steps in a different order.