How to access guest IP in docker - docker

I am making my first steps with docker-compose. I created a very basic docker-compose.yml file with this content:
version: '2'
services:
webserver:
build: ./docker/webserver
image: runwaytest_web
ports:
- "80:80"
- "443:443"
volumes:
- /myhome/Docker/simple-docker/www:/var/www/html
- /myhome/Docker/simple-docker/symfony3:/var/www/symfony3
links:
- mysql
mysql:
# mysql stuff
I also have a very basic Dockerfile in ./docker/webserver. Servers are created correctly. If I ssh to the container, apache is running and the config file is correct.
When I inspect my container from the host, the IP is 172.18.0.3, but I can't ping it, and virtual host for symfony3 does not work (actually I can't neither reach the base http-document folder in /var/www).
I am using Docker for Mac.
What I am doing wrong?

See https://stackoverflow.com/a/24149795/99189 for why you can't ping your container. In general, don't expect to be able to do that. The only network access you have to the container is through the ports that you expose, 80 and 443 in this case.
From the perspective of running this in a docker container and using virtual hosts, you'll need your http client to send a Host: header when making requests to localhost:80/localhost:443.
Assuming you are testing with a browser, and that your vhost is user3174311.com, try the following:
add the line 127.0.0.1 user3174311.com to your /etc/hosts
visit user3174311.com in your browser
This is what should be happening:
browser looks up user3174311.com in /etc/hosts and resolves it to 127.0.0.1
browser sends an http request with a Host: user3174311.com header to 127.0.0.1:80
docker is listening on this address and forwards the connection to port 80 in your container
apache sees the request, looks at the Host: header and determines the correct virtual host to use
After that, it depends on your apache/symphony3 configuration. You'll have to post more details if it's not working.

Related

created apache service using docker compose but unable to access the apache(httpd) over browser

Below is my docker-compose.yml:
version: '3'
services:
proxy:
image: nginx:1.11 # this will use the latest version of 1.11.x
ports:
- '80:80' #expose 80 on host and send it to container on 80
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
web:
image: httpd #this will use httpd latest
I executed above code in an AWS EC2 instance and it created two services proxy and web as expected.
I have installed docker and docker compose on Ec2 instance and
inbound/outbound rule is "all traffic" for this instance which means port 80 is open on this instance.
However, when i try to access apache(httpd) over browser using
url htpp://Public Ip of EC2 Instance:80 then it does not open default page of apache and instead it shows message:
This site can’t be reached 54.211.70.155 refused to connect. Try: Checking the connection Checking the proxy and the firewall ERR_CONNECTION_REFUSED"

Dockerizing 2 separate dependant services

I currently have a VM running 2 services. A frontend httpd/apache2 service that proxies all request to my backend services.
My bankend service only listens on 127.0.0.1:7878. This means it is only accessible via localhost. Thats the reason why Im using a frontend so that I can use that to proxy my requests to 127.0.0.1:7878
So my apache2 config on the VM looks like :
root#vm:/etc/apache2/sites-enabled# cat backend.conf
<VirtualHost *:443>
ServerName my.domain.com
ProxyPass / http://localhost:7878/
ProxyPassReverse / http://localhost:7878/
SSLEngine On
SSLCertificateFile /etc/apache2/ssl/ssl_cert.crt
SSLCertificateKeyFile /etc/apache2/ssl/ssl_cert.key
</VirtualHost>
Now I want to dockerize both services and deploy them using docker-compose
I have setup my backend service like :
version: '3'
services:
backend:
build: backend/.
ports:
- "7878:7878"
And my backend/ folder has all the required files for my backend service including the Dockerfile. I am able to successfully build by docker image and can run it successfully. When I exec into the pod, I can successfully run curl commands towards 127.0.0.1:7878/some-end-point
Now I need to dockerize the frontend service too. It could be apache or it could even be nginx. But Im not sure how both containers will interac with each other given that my backend services ONLY listens on 127.0.0.1
If I extend my docker-compose file like :
version: '3'
services:
backend:
build: backend/.
ports:
- "7878:7878"
frontend:
build: frontend/.
ports:
- "80:80"
- "443:443"
I believe it will spin up its own network and my backend service wont be accessible using 127.0.0.1:7878
So in this case, whats the best approach ? How do I use docker-compose to spin up different containers on the SAME network so that they share 127.0.0.1 ?
You can't do that as you describe: the IPv4 address 127.0.0.1 is a magic address that always means "me", and in a Docker context it will mean "this container".
It's easy enough to set up a private Docker-internal network for your containers; in fact, Docker Compose will do this automatically for you. Your backend service must be listening on 0.0.0.0 to be accessible from other containers. You're not required to set externally published ports: on your container (or use the docker run -p option), though. If you don't, then your container will only be reachable from other containers on the same Docker-internal network, using the service name in the docker-compose.yml file as a DNS name, on whatever port the process inside the container happens to be listening on.
A minimal example of this could look like:
version: '3'
services:
proxy:
image: 'my/proxy:20181220.01'
environment:
BACKEND_URL: 'http://backend'
BIND_ADDRESS: '0.0.0.0:80'
ports:
- '8080:80'
backend:
image: 'my/backend:20181220.01'
environment:
BIND_ADDRESS: '0.0.0.0:80'
From outside Docker, you can reach the proxy at http://server-hostname.example.com:8080. From inside Docker, the two hostnames proxy and backend will resolve to Docker-internal addresses, and we've set both services (via a hypothetical environment variable setup) to listen on the ordinary HTTP port 80.

docker-compose microservice inter-container api communication with nginx proxy

I am trying to build a docker-compose file that will mimic my production environment with its various microservices. I am using a custom bridge network with an nginx proxy that routes port 80 and 443 requests to the correct service containers. The docker-compose file and the nginx conf files together specify the port mappings that allow the proxy container to route traffic for each DNS entry to its matching container.
Consequently, I can use my container names as DNS entries to access each container service from my host browser. I can also exec into each container and ping other containers by that same DNS hostname. However, I cannot successfully curl from one container to another by the container name alone.
It seems that I need to append the proxy port mapping to each inter-service API call when operating within the Docker environment. In my production environment each service has its own environment and can respond on ports 80 and 443. The code written for each service therefore ignores port specifications and simply calls each service by its DNS hostname. I would rather not have to append port id mappings to each API call throughout the various code bases in order for my services to talk to each other in the Docker environment.
Is there a tool or configuration setting that will allow my microservice containers to successfully call each other in Docker without the need of a proxy port map?
version: '3'
services:
#---------------------
# nginx proxy service
#---------------------
nginx_proxy:
image: nginx:alpine
networks:
- test_network
ports:
- "80:80"
- "443:443"
volumes:
- "./site1/site1.test.conf:/etc/nginx/conf.d/site1.test.conf"
- "./site2/site2.test.conf:/etc/nginx/conf.d/site2.test.conf"
container_name: nginx_proxy
#------------
# site1.test
#------------
site1.test:
build: alpine:latest
networks:
- test_network
ports:
- "9001:9000"
environment:
- "VIRTUAL_HOST=site1.test"
volumes:
- "./site1:/site1"
container_name: site1.test
#------------
# site2.test
#------------
site2.test:
build: alpine:latest
networks:
- test_network
ports:
- "9002:9000"
environment:
- "VIRTUAL_HOST=site2.test"
volumes:
- "./site2:/site2"
container_name: site2.test
# networks
networks:
test_network:
http://hostname/ always means http://hostname:80/ (that is, TCP port 80 is the default port for HTTP URLs). So if you want one container to be able to reach the other as http://othercontainer/, the other container needs to be running an HTTP daemon of some sort on port 80 (which probably means it needs to at least be started as root within its container).
If your nginx proxy routes to all of the containers successfully, it's not wrong to just route all inter-container traffic through it (in a previous technology generation we would have called this a service bus). There's not a trivial way to do this in Docker, but you might be able to configure it as a standard HTTP proxy.
I would suggest making all of the outbound service URLs configurable in any case, probably as environment variables. You can imagine wanting to run multiple services together in a development environment (in which case the service URL might be http://localhost:9002), or in a pure-Docker environment like what you show (http://otherservice:9000), or in a hybrid multi-host Docker setup (http://other.host.example.com:9002), or in Kubernetes (http://otherservice.default.svc.cluster.local:9000).

nginx proxy + apache in docker

I am new in Docker.
And i had a task - create docker container with nginx that will be send php (dynamics) to the apache docker container.
I solved my problem. But i've spend much time. So i hope this will help to other people
There is many articles - how to build nginx + apache...
But they dont work in Docker
My problem was solved by changing nginx configuration file (my.conf | default ...)
from:
upstream backend {
server 127.0.0.1:8080;
}
to:
upstream backend {
server apache2php:8080;
}
where apache2php is the service name in docker-compose.yml
like this:
version: "3"
services:
apache2php:
image: apache2php
ports:
- "8080:8080"
volumes:
- "/var/www/html:/var/www/html"
mynginx:
image: mynginx
ports:
- "80:80"
volumes:
- "/var/www/html:/var/www/html"
When i checked logs (/var/log/nginx/error.log) in the nginx container with my bad settings i found an error 111 (Connection refused while connecting to upstream)
And also there was not my local ip (127.0.0.1) in the Host field but another (like 10.5.100.2 - maybe another)
I think that docker use its own ip addresses in the docker's network and that IP-addresses are used by docker containers (nginx use 10.5.100.2:8080 when need to redirect php file to apache)
But when we go to 127.0.0.1:80 in outer network (like when we type the IP in the browser) Docker translate inner IP (nginx - 10.5.100.2:80) into outer IP that we type later (127.0.0.1:80)
Am i right?

Is it possible to expose http ports with docker-compose?

I am running postgres and keycloak images on my local machine. Both of this images have exposed ports configured. But docker machine only exposing ports via TCP. So I was able to connect to the postgres via TCP, but was not able to connect to the keycloack's localhost:8080 via HTTP.
So is it possible to connect to the docker exposed ports via HTTP.
docker-compose.yml
postgres:
image: postgres:9.6.3
volumes:
- ./db/init:/docker-entrypoint-initdb.d
environment:
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
ports:
- 5432:5432
keycloak:
image: jboss/keycloak-postgres
environment:
- KEYCLOAK_LOGLEVEL=DEBUG
- POSTGRES_DATABASE=user-service
- POSTGRES_USER=root
- POSTGRES_PASSWORD=root
links:
- postgres:postgres
ports:
- "8080:8080"
- "9999:9990"
- "443:8443"
volumes:
- ./data:/data
HTTP is a protocol that rides on top of TCP, so if Docker exposes a port via TCP (as opposed to UDP, the other option), then you can connect to that port over HTTP, provided something that speaks HTTP is listening on that port inside the container.
So if you can't connect to http://localhost:8080 with the above compose file, that probably means that the keycloak service either doesn't have anything listening on port 8080 inside the container, or whatever's listening doesn't speak HTTP, or whatever's listening and speaks HTTP is refusing the connection for some other reason.
To completely rule out that the problem is with the port mapping or something on the host, hop inside the container (using docker exec) and try to connect to 8080 from inside; if you can't, then you've confirmed the problem is with whatever's running inside the container, not with anything Docker-related.
It appears that port exposing is about connecting to the docker machine via http://{docker-machine-ip}:{port} and to be able to connect to it with localhost one need to configure ports forwarding within Virtual machine.
After this configuration I was able to connect to all my running containers with http://localhost:{port}

Resources