Score:0

Can NOT bind host port 14433 to container port 433 using localhost, but https works using container IP (for example 172.21.0.2)

bd flag

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 [email protected]
    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 [email protected]
    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 [email protected]
    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 [email protected]
        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?

Score:0
in flag

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>
bd flag
**- "14433:433" - "14080:80"** was just a spelling error on serverfault. The docker-compose.yml had the correct spelling without **.
bd flag
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
bd flag
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) ---
bd flag
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
bd flag
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.
bd flag
I gave up the problem, and tried with nginx. It works. I will now migrate everything to nginx instead.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.