Build the docker Rancher-Server container with SSL

Hi,

I’m currently trying to build my own rancher-server container. I want to access the rancher web interface over HTTPS. Nodes and registries are in the same private network and so will communicate over HTTP.

This works when I install an Apache proxy directly on the host server, in which rancher/server is running. I just keep the rancher/server running over http on port 8080, I simply redirect the proxy to this port. In this configuration, the rancher-server web interface is reachable throw HTTPS from everywhere, and throw HTTP on port 8080 but only on the local network.

What I would really prefer is installing the Apache SSL proxy directly in the rancher-server container (instead having this proxy directly installed on the host server). For that I build an new image from the official rancher/server image. Here is my Dockerfile:

FROM rancher/server MAINTAINER JayBee support@jaybee.com RUN apt-get update RUN apt-get upgrade -y RUN apt-get install -y apache2 RUN a2enmod headers && a2enmod filter && a2enmod proxy && a2enmod rewrite && a2enmod ssl && a2enmod socache_shmcb ADD 000-default.conf /etc/apache2/sites-available/ ADD default-ssl.conf /etc/apache2/sites-available/ RUN mkdir /etc/apache2/cert && a2ensite default-ssl ADD rancher.domain.crt /etc/apache2/cert/ ADD rancher.domain.key /etc/apache2/cert/ EXPOSE 443 8080 80 CMD /usr/sbin/apache2ctl -D FOREGROUND

Here is my Apache default-ssl.conf file:

<VirtualHost *:443>; ServerName rancher.domain.com SSLEngine On SSLCertificateFile /etc/apache2/cert/rancher.domain.crt SSLCertificateKeyFile /etc/apache2/cert/rancher.domain.key SSLProxyEngine On SSLProxyVerify none SSLProxyCheckPeerCN off SSLProxyCheckPeerName off RequestHeader set X-Forwarded-Proto "https" RequestHeader set X-Forwarded-Port "443" ProxyPreserveHost On ProxyRequests Off ProxyPass / http://localhost:8080/ ProxyPassReverse / http://localhost:8080/ CustomLog /var/log/apache2/discourse_apache_proxy_https_access.log combined ErrorLog /var/log/apache2/discourse_apache_proxy_https_error.log </VirtualHost>

The 000-default.conf file is just a redirection to the HTTPS.
Otherwise, the website interface is accessible in the local network only, over HTTP on the classical port 8080.

Then, when the container is successfully built, tagged, and pushed, I run it with this command:
docker run -d --restart=always -p 8080:8080 -p 443:443 -p 80:80 -e CATTLE_DB_CATTLE_MYSQL_HOST=10.129.0.155 -e CATTLE_DB_CATTLE_MYSQL_PORT=3306 -e CATTLE_DB_CATTLE_MYSQL_NAME=cattle -e CATTLE_DB_CATTLE_USERNAME=cattle -e CATTLE_DB_CATTLE_PASSWORD=cattle rancher.domain.com:5000/rancher-server:custom

Yes, I like complicated stuffs : that’s why I use an external database!

So in this case, only the Apache server is working but the rancher web interface not. When I remove the last line in the Dockerfile (CMD /usr/sbin/apache2ctl -D FOREGROUND), I only get the rancher/server working!

So, when you build an image FROM another image, the CMD directive will override the CMD in the base image.

If I do a docker inspect rancher/server, I see that it does have a command set already:

...
        "Cmd": [
            "/usr/bin/s6-svscan",
            "/service"
        ],
...

Since you override this with the apache command, the other command won’t execute. Remember that the CMD that you specify is responsible for starting everything that needs to run in that image.

It might make sense to run the rancher/server image as it is, and then run your apache image as a separate container.

Many thanks programmerq for your answer

It seems that a container must be dedicated for the proxy server. Furthermore, the CMD can be used only once in a Dockerfile. So I tried to find a workaround by putting the argument with the command and so writing 2 commands in one :sunglasses:! But no it doesn’t work :sweat_smile:.
CMD ["/usr/sbin/apache2ctl -D FOREGROUND && /usr/bin/s6-svscan /service"]
So yes I will dedicate one container for that!
[solved]

That command, "/usr/sbin/apache2ctl -D FOREGROUND && /usr/bin/s6-svscan /service" will first execute apache in the foreground. Once that process is exits with status 0 (and apache is no longer running), the && will then execute the s6-svscan /service command.

It is possible to run multiple processes in a container-- you can use something like supervisor or runit that are the pid1 as specified by the CMD, and configure those to launch multiple processes.

In this case, I would put apache in its own container in front of the rancher/server container, and not try to run both in one.

Thanks,

/Jeff