Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

https in multiple docker containers

I have problems figuring out how to properly set up a web server with https which contains multiple Docker containers.

I have a main container running apache by using the "httpd" docker-image. For simplicity lets call this website "main.com". SSL works perfectly here. I have set up the httpd.conf configuration file to redirect all calls to port 80 to port 443 and loaded SSL and proxy modules. (Port 80 and 443 are both exposed).

I have another Docker container which runs an API to serve geodata to "main.com". We can call this container for "side-container". In the Dockerfile for "side-container" I expose port 8080 from this. Then I can call "main.com:8080" to make a query to my "side-container" which runs the API.

Problem --> At least I could until I changed "main.com" to only use https.

I am stuck trying to get "side-container" to work again. When trying to connect to "main.com:8080" I get a timeout error.

My "docker ps" looks like this:

IMAGE  COMMAND PORTS NAMES        
main-container     "httpd-foreground"  0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:9010->9010/tcp  main
side-container:latest   "/docker-entrypoint.…"  0.0.0.0:8080->8080/tcp side-container

I use docker-compose to control the containers, so perhaps I need to set something there? I have made an attempt to get it working by using a reverse proxy setting in apache (see http.conf below), by using port 9010 on the "main" container to point to port 8080 on the "side-container". I can get it to reply with an "internal server error" due to a failed SSL handshake, but no more than that.

My background is in pure physics and not software and webservers so maybe I am missing something obvious. Any hint is greatly appreciated.

From httpd.conf:

<IfModule mod_ssl.c>
    Listen 443
    Listen 8080
    Listen 0.0.0.0:9010 https
    LoadModule socache_shmcb_module modules/mod_socache_shmcb.so
    SSLProtocol all -SSLv3
    SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256
    SSLHonorCipherOrder     on
    SSLCompression          off
    SSLSessionTickets       off
    SSLRandomSeed startup file:/dev/urandom 512
    SSLRandomSeed connect file:/dev/urandom 512
    SSLSessionCache shmcb:/dev/ssl_gcache_data(512000)
</IfModule>


<Virtualhost *:443>
   ServerName main.com
   SSLEngine on
   #Primary Certificate file
   SSLCertificateFile /usr/local/apache2/conf/certificate.crt
   #Private Key
   SSLCertificateKeyFile /usr/local/apache2/conf/private.key
   #Chain bundle file
   SSLCertificateChainFile /usr/local/apache2/conf/ca_bundle.crt
</VirtualHost>

<Virtualhost 0.0.0.0:9010>
   ServerName main.com

   SSLEngine on
   SSLProxyEngine on
   SSLProxyVerify none
   SSLProxyCheckPeerCN off
   SSLProxyCheckPeerName off
   SSLProxyCheckPeerExpire off

   SSLCertificateFile /usr/local/apache2/conf/certificate.crt
   SSLCertificateKeyFile /usr/local/apache2/conf/private.key
   SSLCertificateChainFile /usr/local/apache2/conf/ca_bundle.crt

   ProxyPass /apptest http://0.0.0.0:8080/
   ProxyPassReverse /apptest https://0.0.0.0:8080/

</VirtualHost>

docker-compose.yml:

version: '3'
services:
  main-container:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: "main"
    restart: "always"
    ports:
      - "80:80"
      - "443:443"
      - "9010:9010"
    links:
      - side-container
    networks:
      - fu
  side-container:
    image: side-container:latest
    container_name: "side-container"
    ports:
      - "8080:8080"
    volumes:
      - ${HOME}/data:/data
    restart: "always"
    networks:
      - fu
networks:
  fu:
    driver: bridge
like image 368
Whir Avatar asked Jul 09 '20 09:07

Whir


People also ask

Can you run 2 Docker containers at the same time?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.

Can multiple Docker containers use the same port?

Surprisingly or not, neither Docker nor Podman support exposing multiple containers on the same host's port right out of the box. Example: docker-compose failing scenario with "Service specifies a port on the host. If multiple containers for this service are created on a single host, the port will clash."

Can I run multiple services in a docker container?

Run multiple services in a container. It is generally recommended that you separate areas of concern by using one service per container. That service may fork into multiple processes (for example, Apache web server starts multiple worker processes). It’s ok to have multiple processes, but to get the most benefit out of Docker,...

What is the main running process of a docker container?

A container’s main running process is the ENTRYPOINT and/or CMD at the end of the Dockerfile. It is generally recommended that you separate areas of concern by using one service per container. That service may fork into multiple processes (for example, Apache web server starts multiple worker processes).

How do I point a docker container to https?

First, you need to kick things off with a config file (docker-compose.yml) that encompasses images for both Nginx and certbot. Next, you can use this basic configuration to point incoming requests to HTTPS.

How to run MySQL in a docker container?

Lastly, since the default port for MySQL is 3306, we are mapping it to the container’s port 3306 and exposing that port for access. Once the above file is created, run the below command to get your Docker image created and run it as a container. The MySQL image will be pulled and then Docker will spin up a container to run this image.


1 Answers

When linking docker containers within the same network with docker compose you need to reference them by the docker service name, thus instead of 0.0.0.0 use side-container:

ProxyPass /apptest http://side-container:8080/
ProxyPassReverse /apptest https://side-container:8080/

NOTE: the server running in the side container must be listening into 0.0.0.0:8080 in its httpd configuration.

Now you can remove from the docker compose file the ports declaration altogether, because both containers are in the same docker network, therefore you don't need to expose any ports. Exposing ports are only necessary if you want to reach the side-container from localhost in the host machine or from the internet.

So from the side container remove:

ports:
      - "8080:8080"

Also in the docker compose file you should replace links with the new syntax depends_on:

depends_on:
      - side-container

Ports declaration

For educational purpose.

Please bear in mind that when specifying the port like 8080:8080 is the same as 0.0.0.0:8080:8080 and 0.0.0.0 listens in all requests from the internet, thus to restrict them to localhost 127.0.0.1 of the machine running docker you would do 127.0.0.1:8080:8080.

like image 144
Exadra37 Avatar answered Oct 01 '22 20:10

Exadra37