0

When I do lynx localhost:14080 from host, it works. The website is loaded from the container.

When I do lynx localhost:14433 from host, it does NOT work.

When I do lynx https://localhost:14433 from host, it does NOT work. Error: Unable to make secure connection to remote host.

The container is running on a bridge network, launched by docker-compose. The IP of the container is: 172.21.0.2.

BUT, when I do lynx https://172.21.0.2 IT WORKS...

...the website is loaded from the container using https and SSL-certificates. I only get SSL warning:

172.21.02!=cert(CN<example.com>)-Continue?

...which means the CN of the certificate does not mach the IP I was trying to open, but I am still able to ignore this warning and continue to open the site.

This means that http is working on localhost (and it also works when I use the container IP).

But https is only working when I try to connect using the container IP, but it is not working when I use localhost.

This is the reason why I think there is an error in the port bindings of the networks created by docker.

I would like to be able to connect to the container using localhost, so I do not need to specify the new IP of the container each time I relaunch the container, because I am planning to set up a reverse apache2 proxy on the host, so that the outside world can connect to my website in the container using https.

This is my apache2 settings on the host:

File example.com.conf in my host apache conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerAdmin martin@email.com
    CustomLog /var/www/docker/example.com/log/host/custom.log combined
    ErrorLog /var/www/docker/example.com/log/host/error.log
    Redirect permanent / https://example.com/
    ProxyRequests off
    ProxyPreserveHost On
    ProxyPass        "/" "http://172.21.0.2/"
    ProxyPassReverse "/" "http://172.21.0.2/"
</VirtualHost>

File example.com-le-ssl.conf in my host apache conf:

<IfModule mod_ssl.c>
ErrorLog /var/www/docker/example.com/log/host/error.log
LogLevel debug
<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    ProxyPreserveHost on
    ServerAdmin martin@email.com
    LogLevel debug
    CustomLog /var/www/docker/example.com/log/host/custom.log combined
    ErrorLog /var/www/docker/example.com/log/host/error.log
    <If "%{HTTP_HOST} == 'www.example.com'">
      Redirect permanent / https://example.com/
    </If>
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLProxyEngine on
    SSLEngine on
    ProxyRequests off
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off
    <Proxy *>
        Order allow,deny
        Allow from all
    </Proxy>
    ProxyPass        "/" "http://172.21.0.2/"
    ProxyPassReverse "/" "http://172.21.0.2/"
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>

This is my apache conf in the container:

File default-ssl.conf in my host apache conf:

ServerName example.com

<VirtualHost _default_:80>
    ServerName example.com
    ServerAlias www.example.com
    ServerADmin martin@email.com
    DocumentRoot /var/www/html/www
    ErrorLog /var/log/container/error.log
    CustomLog /var/log/container/custom.log combined
</VirtualHost>

<IfModule mod_ssl.c>
LogLevel debug
    <VirtualHost _default_:443>
        ServerName example.com
        ServerAlias www.example.com
        ServerAdmin martin@email.com
        DocumentRoot /var/www/html/www
        LogLevel debug
        ErrorLog /var/log/container/error.log
        CustomLog /var/log/container/custom.log combined
        Include /etc/letsencrypt/options-ssl-apache.conf
        SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
</VirtualHost>
</IfModule>

This is my docker-compose.yml file:

version: '3.7'

networks:
  examplewebapp:
    driver: bridge

services:
  referental:
    container_name: examplewebapp
    build:
      context: ./
      dockerfile: Dockerfile
      target: dev
    image: examplewebapp
    restart: unless-stopped
    networks:
      - examplewebapp
    ports:
      **- "14433:433"
      - "14080:80"**
    working_dir: /var/www/html
    volumes:
      - ./container_apache_conf:/etc/apache2/sites-available
      - ./api:/var/www/html/api
      - ./archive:/var/www/html/archive
      - ./log/container:/var/log/container
      - ./log/host:/var/log/host
      - ./etc/letsencrypt:/etc/letsencrypt
      - ./www:/var/www/html/www

This is my Dockerfile:

FROM php:7.4-apache AS base
RUN apt-get update
RUN mkdir -p /var/www/html/www # website will be saved here
RUN mkdir -p /var/log/container # apache logs will be saved here
# mysql connectivity and internationalization for php
RUN docker-php-ext-install mysqli
RUN docker-php-ext-enable mysqli
RUN apt-get install -y libicu-dev
RUN docker-php-ext-configure intl
RUN docker-php-ext-install intl
# enables https for apache
RUN a2enmod ssl
RUN a2ensite default-ssl.conf


FROM base AS dev
RUN pecl install xdebug-3.1.1
RUN docker-php-ext-enable xdebug

FROM base AS test

FROM base AS prod

This is what is generated by:

docker network inspect examplecom_example


[
    {
        "Name": "examplecom_example",
        "Id": "7311d1a7254466bd6ab44833362460cde4336ade622bca87def62bb3d840ef3f"                                                   ,
        "Created": "2022-02-13T21:16:34.861655456Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.21.0.0/16",
                    "Gateway": "172.21.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "be53d5b37e2fbcaae49bb111b921dfd4caf5db20ed680403083333ffac983b93":                                                    {
                "Name": "example",
                "EndpointID": "fb1428d29e2fc9564b3e1758a7efac15909a897021320b15f                                                   1df8c1d600efd89",
                "MacAddress": "00:00:00:00:00:00",
                "IPv4Address": "172.21.0.2/16",
                "IPv6Address": ""
            },
    }
]

This is the output of docker ps:

CONTAINER ID   IMAGE                    COMMAND                  CREATED        STATUS        PORTS                                                                                            NAMES
be53d5b37e2f   example          "docker-php-entrypoi…"   11 hours ago   Up 11 hours   443/tcp, 0.0.0.0:14080->80/tcp, :::14080->80/tcp, 0.0.0.0:14433->433/tcp, :::14433->433/tcp      example

I am using the official php docker image.

And in docker compose I am creating a bridge network and I am mapping:

  • "14433:433"
  • "14080:80"

My questions are:

  1. Why can I connect from my host to my container using http on http://127.0.0.1:14080, but not using https on https://127.0.0.1:14433, even though both ports for http and https (14080:80 and 14433:433) should be mapped in the same way? And why does https still work when I connect to container using https on https://172.21.0.2.

  2. What should I do to be able to redirect https traffic from my host apache (as reverse proxy), to my container apache using localhost, i.e. https://127.0.0.1:14433/ - so that my container can be accessed from the internet, also using https, and so I do not need to specify the IP of the container in my host apache configuration of the reverse https proxy?

Martin
  • 1
  • 1

1 Answers1

0

Why are there these *?

      **- "14433:433"
      - "14080:80"**

Try it with

version: '3.7'

networks:
  examplewebapp:
    driver: bridge

services:
  referental:
    container_name: examplewebapp
    build:
      context: ./
      dockerfile: Dockerfile
      target: dev
    image: examplewebapp
    restart: unless-stopped
    networks:these
      - examplewebapp
    ports:
      - "14433:433"
      - "14080:80"
    working_dir: /var/www/html
    volumes:
      - ./container_apache_conf:/etc/apache2/sites-available
      - ./api:/var/www/html/api
      - ./archive:/var/www/html/archive
      - ./log/container:/var/log/container
      - ./log/host:/vatheser/log/host
      - ./etc/letsencrypt:/etc/letsencrypt
      - ./www:/var/www/html/www

And please show the output of docker ps.

And for Apache as a Proxy, even though i hear nginx is the preferred nowadays you could use a Config like this.

<VirtualHost *:80>

ServerName your.vhost.tld

RewriteEngine on
RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]

ErrorLog ${APACHE_LOG_DIR}/your.vhost.tld-error.log
CustomLog ${APACHE_LOG_DIR}/your.vhost.tld-access.log vhost_combined

</VirtualHost>

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

ServerName your.vhost.tld
<Proxy *>
order deny,allow
Allow from all
</Proxy>

SSLEngine on
SSLCertificateFile      /etc/apache2/ssl/your.vhost.tld/certificate.crt
SSLCertificateKeyFile   /etc/apache2/ssl/your.vhost.tld/certificate.key
#SSLCACertificateFile   /etc/apache2/ssl/your.vhost.tld/cert.cabundle

SetEnv           force-proxy-request-1.0 1
SetEnv           proxy-nokeepalive       1
SetEnv           proxy-initial-not-pooled 1

ErrorLog ${APACHE_LOG_DIR}/your.vhost.tld-error.log
CustomLog ${APACHE_LOG_DIR}/your.vhost.tld-access.log vhost_combined

ProxyTimeout 600
SSLProxyEngine On
#ProxyRequests On
#ProxyPreserveHost On
RewriteEngine off

#PROXY's
ProxyRequests Off
<Location "/">
ProxyPreserveHost On
ProxyPass https://localhost:14443
ProxyPassReverse https://localhost:14443
</VirtualHost>
</IfModule>
crpb
  • 51
  • 4
  • **- "14433:433" - "14080:80"** was just a spelling error on serverfault. The docker-compose.yml had the correct spelling without **. – Martin Feb 14 '22 at 08:11
  • What is the difference in the docker-compose.yml file? The only difference that I can see is the addition of "these" after "networks:". But this gives me an error when trying to run docker compose. ERROR: yaml.scanner.ScannerError: while scanning a simple key in "./docker-compose.yml", line 16, column 5 could not find expected ':' in "./docker-compose.yml", line 18, column 5 – Martin Feb 14 '22 at 08:29
  • openssl s_client -crlf -connect localhost:14433 -servername www.example.com Gives me: CONNECTED(00000003) write:errno=104 --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 310 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) --- – Martin Feb 14 '22 at 08:34
  • I agree, nginx is the prefered way, but I hesitate to run nginx and apache2 on the same machine, and I also hesitate to migrate all other websites to docker or nginx, because they have lots of server and apache2-settings – Martin Feb 14 '22 at 09:00
  • I did try your settings but the error still persist. Lynx gives me: Alert!: Unexpected network read error; connection aborted. Can't Access `example.com' Alert!: Unable to access document. – Martin Feb 14 '22 at 17:56
  • I gave up the problem, and tried with nginx. It works. I will now migrate everything to nginx instead. – Martin Feb 16 '22 at 22:46