António Quadrado
António Quadrado

Reputation: 1325

How to expose an nginx docker container via Apache 2 with SSL?

I have a web app running on docker containers on my Digital Ocean droplet. The app has its own container and is served through an Nginx container on the address 0.0.0.0:8080. Here is the nginx conf:

server {
    listen 80;
    index index.php index.html;
    root /var/www/public;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

and my nginx container dockerfile:

FROM nginx:1.10

ADD ./vhost.conf /etc/nginx/conf.d/default.conf
WORKDIR /var/www

Now, I have domain to which I generated an SSL certificate using certbot and I want to serve my app through this domain but I am failing miserably.

I am using(or trying) Apache2 as a reverse proxy for this but I cannot get it to work. I can now access the main page of the app but without any resources since the page is being served through https but the resources are being fetch from the container via http. I don't know how many things I tried already but I am going nowhere. Any help would be much appreciated. Here are my virtual hosts configs, if that helps.

vhost-le-ssl.conf:

<IfModule mod_ssl.c>
#Listen 443
#NameVirtualHost *:443
<VirtualHost *:443>

     SSLEngine  On

        # Set the path to SSL certificate
    # Usage: SSLCertificateFile /path/to/cert.pem

 SSLCertificateFile /etc/letsencrypt/live/antonioquadrado.com/cert.pem

    # Servers to proxy the connection, or;
    # List of application servers:
    # Usage:
    # ProxyPass / http://[IP Addr.]:[port]/
    # ProxyPassReverse / http://[IP Addr.]:[port]/
    # Example: 
    ProxyPass / http://0.0.0.0:8080/
    ProxyPassReverse / http://0.0.0.0:8080/

        ServerName antonioquadrado.com
        ServerAlias www.antonioquadrado.com

        ServerAdmin webmaster@localhost
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
RewriteEngine on
# Some rewrite rules in this file were disabled on your HTTPS site,
# because they have the potential to create redirection loops.

# RewriteCond %{SERVER_NAME} =antonioquadrado.com [OR]
# RewriteCond %{SERVER_NAME} =www.antonioquadrado.com
# RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/antonioquadrado.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/antonioquadrado.com/privkey.pem
</VirtualHost>
</IfModule>

vhost.conf:

VirtualHost *:80>

        ProxyPreserveHost On

    # Servers to proxy the connection, or;
    # List of application servers:
    # Usage:
    # ProxyPass / http://[IP Addr.]:[port]/
    # ProxyPassReverse / http://[IP Addr.]:[port]/
    # Example: 
    ProxyPass / https://0.0.0.0:8080/
    ProxyPassReverse / https://0.0.0.0:8080/

        ServerName antonioquadrado.com
        ServerAlias www.antonioquadrado.com

        ServerAdmin webmaster@localhost
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
RewriteEngine on
RewriteCond %{SERVER_NAME} =antonioquadrado.com [OR]
RewriteCond %{SERVER_NAME} =www.antonioquadrado.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

I have followed this digital ocean tutorial to get at this point.

Thanks in advance!

Edit: after being pointed by @SmileIt to the serverfault answer I have updated my virtualhosts configs to this:

<VirtualHost *:80>
        ServerName antonioquadrado.com
        ServerAlias www.antonioquadrado.com

        Redirect permanent / https://www.antonioquadrado.com/
</VirtualHost>

ssl vhosts:

<IfModule mod_ssl.c>
<VirtualHost *:443>

        ServerName www.antonioquadrado.com
        DirectoryIndex index.php index.html
        SetOutputFilter SUBSTITUTE,DEFLATE

        ProxyPass / http://0.0.0.0:8080/
        ProxyPassReverse / http://0.0.0.0:8080/

        AddOutputFilterByType SUBSTITUTE text/html
        Substitute "s|http://0.0.0.0:8080/|https://www.antonioquadrado.com/|i"

        SSLEngine on
        SSLProtocol all -SSLv2
        SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateKeyFile /etc/letsencrypt/live/antonioquadrado.com/privkey.pem
        SSLCertificateFile /etc/letsencrypt/live/antonioquadrado.com/fullchain.pem
        #SSLCertificateChainFile /path-to/chain.pem
        <Proxy *>
                Order deny,allow
                Allow from all
                Allow from localhost
        </Proxy>
</VirtualHost>
</IfModule>

But I have the same errors about the resources being fetched over the internal ip via http.

Here's also my docker-compose file:

version: '2'
services:
    web:
        build:
            context: ./
            dockerfile: web.docker
        volumes:
            - ./:/var/www
        ports:
            - "8080:80"
        links:
            - app
    app:
        build:
            context: ./
            dockerfile: app.docker
        volumes:
            - ./:/var/www
        links:
            - database
        environment:
            - "DB_PORT=3306"
            - "DB_HOST=database"
    database:
        image: mysql:5.6
        environment:
            - "MYSQL_ROOT_PASSWORD=*****"
            - "MYSQL_DATABASE=*******"
        ports:
            - "33061:3306"

Upvotes: 0

Views: 1193

Answers (1)

SmileIT
SmileIT

Reputation: 468

Apache output filters are out of order most likely.

Add the following to your VirtualHost config near the top and restart Apache.

SetOutputFilter SUBSTITUTE;DEFLATE

Essentially we have to tell Apache to order output filters. Do substitution first then deflate. If this does not work for you add the following to your VirturalHost config and send the output.

LogLevel trace3 rewrite:error filter:trace8

The output should tell us what filters are running before substitution filter.

Upvotes: 1

Related Questions