docker + haproxy on mac 10.11.5 doesn't work - macos

I am running an haproxy configuration on mac that works perfect on linux but I can't get the proxy to even respond. Here is my config:
defaults
mode http
timeout connect 5000ms
timeout client 5000ms
timeout server 5000ms
frontend http
bind *:80
acl oracle_content hdr(ContentType) -i application/vnd.api+json
acl oracle_accept hdr(Accept) -i application/vnd.api+json
use_backend oracle_be if oracle_content
use_backend oracle_be if oracle_accept
default_backend matrix_be
backend oracle_be
balance roundrobin
server oracle1 theoracle.stage.company.com:8080
backend matrix_be
balance roundrobin
server matrix1 192.168.1.6:3000
docker run -d --name cc -v /Users/cbongiorno/development/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro haproxy
docker -v
Docker version 1.12.0, build 8eab29e
the only machine specific config is the IP adress of the matrix_be entry which has to be my local interface. It's not working on 2 macs and I have tried binding the proxy to multiple interfaces. I am not even getting a 504 which would indicate the proxy is fine but one of the backend services is misconfigured.
Ideas?

Due to current docker on mac limitations, the -p 80:80 flag must be passed even if the container declares port 80 open for business

Related

Haproxy 503 service unavailable

We are running Haproxy and 3 nginx processes inside a single docker on the host network to access it from localhost. We have installed HaProxy version 2.6.6. 3 nginx servers are running behind it as backend servers. We are able to access them individually What is wrong with the haproxy configuration here? we are always getting the below error on curl (curl http://localhost:80) requests. Please suggest
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
pidfile /usr/local/etc/haproxy/haproxy.pid
defaults
timeout http-request 2000
timeout queue 1000
timeout check 2000
timeout connect 2000
timeout client 5000
timeout server 5000
log global
option dontlognull
option clitcpka
option srvtcpka
option tcpka
unique-id-format %[uuid()]
unique-id-header X-Request-ID
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %ID %{+Q}r"
frontend http-in
mode http
option forwardfor
bind *:80
use_backend webservers
backend webservers
mode http
server localhost-01 localhost:8000
server localhost-02 localhost:8001
server localhost-03 localhost:8002

Cannot connect to Container-optimized-os (running a spring-boot application using docker) using external ip

I have created a Google compute instance with Container-optimized-OS image.
I have configured the firewall to allow http and https.
I am using the docker image with spring boot application which connects to cloudsql. When I use run command on compute engine instance ssh, i.e. (docker run --rm name), the spring boot app is started successfully.
When I try to access the webservices through compute engine instance external ip, it is not working.
I went through a different question, and found that I should try using the sudo wget http://localhost command on the instance cli first and if it is good then everything should be good. But I am getting a connection refused message on 127.0.0.1:80.
I also tried the command to open port from Container optimized OS, I.E.
sudo iptables -w -A INPUT -p tcp --dport 80 -j ACCEPT , nothing is working.
The default port for Spring Boot is 8080 and not 80.
Run this command inside the instance container to see what ports are in LISTENING state:
sudo netstat -tulpn | grep LISTEN
You can redirect port 80 to port 8080 with this command:
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
Note: This iptables command only redirects port 80 to 8080 on network interfaces. This has no effect for localhost or 127.0.0.1.
For Google Compute Engine instances you do not need to enable ports using iptables. This is done via Google VPC firewall rules. You can use both but make sure you understand exactly what you are configuring and the side effects.
Note: Your Spring Boot application needs to listen on 0.0.0.0 and not 127.0.0.1 nor localhost. The last two are internal only addresses. 0.0.0.0 means listen on all network interfaces.
Note: Do not use sudo in front of wget. This is not necessary.
First, confirm what port your springboot application uses - if it's 8080 or 80. This depends on what you have configured inside application.properties file. This port is referred to as ContainerPort in below steps.
Execute docker run <image-name>:<tag>. This will run the image and show container logs on the console. If there is something wrong with your spring-boot app, the logs will show that and the container will shutdown. Press Ctrl+C to stop the container and return to shell.
If there is no error in step 1 run docker run -d -p<HostPort>:<ContainerPort> <image-name>:<tag>. Here HostPort is any free port in your GCP host VM and ContainerPort is the port used by your spring boot application within the container. Option d starts your container in detached mode.
Run docker ps and make sure that the container started in step 2 is running. It may not run if there is an error - for example if the HostPort you specified is already in use.
If step 3 shows that the container is running, execute curl http://localhost:<HostPort>/<End-Point-Path>. Here End-Point-Path is a valid path to a working endpoint within the container. If the endpoint is correct you should see expected result from the spring-boot app in the console.
Navigate to Google Cloud Console -> VPC network -> Firewall rules and add a firewall rule to open HostPort on your GCP VM.
Access your endpoint via the VM's external IP with URL - http://<VM-External-IP>:<HostPort>/<End-Point-Path>
Unless there is an application issue with your spring-boot app these steps should get you going.
I was able to build the correct solution by your help (John Hanley and Cyac).
I am combining both solutions in order to help the next person facing this.
As told by John, by default Spring boot uses port 8080, not 80 and as specified by Cyac you need to specify the port as 80 explicitly in application.properties file using
server.port=80
Make sure you expose the port 80 in docker image
On GCP Contaier optimized OS make sure you have allowed traffic for HTTP and HTTPs
Run command:
sudo iptables -w -A INPUT -p tcp --dport 80 -j ACCEPT
Run docker using:
docker run -p 80:80 SPRING_IMAGE.
Where SPRING_IMAGE is the name of the docker image with spring boot build.
Test by using curl http://localhost/ENDPOINT_NAME , e.g. http://localhost/shops/all

Can't access docker container on port 80 on OSX

In my current job we have development environment made with docker-compose.
One container is nginx, which provide routing to other containers.
Everything seems fine and work to my colleague on windows and osx. But on my system (osx El Capitan), there is problem with accessing nginx container on port 80.
There is setup of container from docker-compose.yml
nginx:
build: ./dockerbuild/nginx
ports:
- 80:80
links:
- php
volumes_from:
- app
... and more
In ./dockerbuild/nginx there is nothing special, just nginx config as we know it from everywhere.
When I run everyting with docker-compose create and docker-compose start. Then docker ps give me
3b296c1e4775 docker_nginx "nginx -g 'daemon off" About an hour ago Up 47 minutes 0.0.0.0:80->80/tcp, 443/tcp docker_nginx_1
But when I try to access it for example via curl I get error. curl: (7) Failed to connect to localhost port 80: Connection refused
I try to run container with port 81 and everything works fine.
Port is really binded to docker
22:47 $ sudo lsof -i -n -P | grep TCP
...
com.docke 14718 schovi 38u IPv4 0x6e9c93c51ec4b617 0t0 TCP *:80 (LISTEN)
...
Firewall in osx is turned off and I have no other security.
if you are using docker-for-mac:
Accessing by localhost:80 is correct, though you still have to ensure you do not have a local apache/nginx service running. Often leftovers from boxen/homebrew exist binding that port, because thats what developers did back then :)
if you are using dockertoolbox/virtualbox/whatever hypervisor
You will not be able to access it by localhost, by by the docker-machine ip, so write docker-machine ip default and the use http://$ip:80 in your browser
if that does not help
Ensure your nginx container actually does work, so connect to the container: docker exec -i -t <containerid> bash
and then run ps aux nginx or if telnet is installed try to connect to localhost
Solved!
Problem was, that long long time ago I installed pow (super simple automated rails server which run application on app_name.local domain). And this beast left LaunchAgent script which update pf to forward port 80 to pow port.
In my current job we have development environment made with docker-compose.
A privilege to use.
[W]hen I try to access [nginx on port 80] for example via curl I get error.
Given there's nothing from causing you from accessing docker on your host os you should look at the app running inside the container to ensure it's binding to the correct host, e.g. 0.0.0.0 and not localhost.
For example, if you're running Nuxt inside a container with nuxt-ts observe Nuxt will default to localhost thereby causing the container not to connect to the docker network whereas npx nuxt-ts -H 0.0.0.0 gets things squared away with the container's internal server connecting to the ip of the docker network used (verify ip like docker container inspect d8af01990363).

Can't connect to public IP for EC2 instance

I have an EC2 instance which is running with the following security groups:
HTTP - TCP - 80 - 0.0.0.0/0
Custom UDP Rule - UDP - 1194 - 0.0.0.0/0
SSH - TCP - 22 - 0.0.0.0/0
Custom TCP Rule - TCP - 943 - 0.0.0.0/0
HTTPS - TCP - 443 - 0.0.0.0/0
However, when I try to access http://{PUBLIC_IP} or https://{PUBLIC_IP} in the browser, I get a "{IP} refused to connect" error. I'm new to AWS. Am I missing something here? What should I do to debug?
One way to debug this particular class of problem is to use netcat in order to determine where the problem lies.
If you run netcat against port 80 on the public IP address of your instance and just get a hang (no output at all), then most likely your security group isn't allowing traffic through. Here is an example from an EC2 instance that is in a security group that doesn't allow port 80 traffic inbound:
% nc -v 55.35.300.45 80
<just hangs>
Whereas if the security group is changed to allow port 80, but the EC2 instance doesn't have any process listening on port 80, you'll get the following:
% nc -v 55.35.300.45 80
nc: connectx to 52.38.300.43 port 80 (tcp) failed: Connection refused
Given that your browser gave you a similar "connection refused", most likely the problem is that there is no web server running on your instance. You can verify this by ssh'ing into the instance and seeing if you can connect to port 80 there:
ssh ec2-user#55.35.300.45
% nc -v localhost 80
nc: connect to localhost port 80 (tcp) failed: Connection refused
If you get something like the above, you're definitely not running a webserver.
I'm not sure if it's too late to help but I was stuck with a similar issue with my test server
SG Inbound: ssh -> 22
HTTP -> 80
NACL: default allow/deny settings
but still couldn't ping to the server from my browser, then I realize there's nothing running on the server that can serve the request, and I started httpd server (webserver) and it worked.
sudo yum -y install httpd
sudo service httpd start
this way you can test the connectivity if you are playing with SGs and NACLs and of course it's not the only way, just an example if you're figuring your System N/W out.
Have you installed webserver(ngingx/apache) to serve your requests. If so please share your the config files. (So that it will help to troubleshoot)
I think the reason is probably that you did not set up a web server for your EC2 instance, because if you try to access http://{PUBLIC_IP} or https://{PUBLIC_IP}, you need to have a background server to serve the http request as #Niranj Rajasekaran said.
By the way, by simply pinging the {PUBLIC_IP}, you could see if your connection to your EC2 instance is normal or not.
In command prompt or terminal, type
ping {PUBLIC_IP}
In my case, the server was running but available on just 127.0.0.1 so it refused connections from external hosts. To see if this is your situation, you can run
netstat -an | grep <port number>
If it says 127.0.0.1:<port number> instead of 0.0.0.0:<port number>, you have this problem.
Usually there's a flag or an argument in your server code somewhere to set the host to 0.0.0.0:
app.run(host='0.0.0.0') # flask example
However, in my case, I had already set this so I thought that couldn't possibly be the issue, which is how I ended up on this thread, which asks more generally about the problem. Unfortunately, I was using docker, and had set 0.0.0.0 on the container but was mapping that explicitly to 127.0.0.1 on the host in the docker-compose port-mapping:
ports:
- "127.0.0.1:<port number>:<port number>"
Changing that line to remove the host IP specification fixed the problem upon re-deploy:
ports:
- "<port number>:<port number>"

Access Docker forwarded port on Mac

There is a related post here: Port mapping in Docker on Mac OSX installed with Docker Toolbox
but it didn't work for me
Get ports for container
docker port 485186e65a5e
8080/tcp -> 0.0.0.0:33360
8088/tcp -> 0.0.0.0:33359
19888/tcp -> 0.0.0.0:33358
50070/tcp -> 0.0.0.0:33357
50075/tcp -> 0.0.0.0:33356
8042/tcp -> 0.0.0.0:33361
Check that someone listens to ports in container
bash-4.1# netstat -alnpt | grep 19888
tcp 0 0 127.0.0.1:19888 0.0.0.0:* LISTEN 1094/java
Do wget in container
bash-4.1# wget 127.0.0.1:19888
--2016-04-11 14:16:54-- http://127.0.0.1:19888/
Connecting to 127.0.0.1:19888... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://127.0.0.1:19888/jobhistory [following]
--2016-04-11 14:16:54-- http://127.0.0.1:19888/jobhistory
Reusing existing connection to 127.0.0.1:19888.
HTTP request sent, awaiting response... 200 OK
Length: 6763 (6.6K) [text/html]
Saving to: `index.html'
100%[================================================================================================================================================================================>] 6,763 --.-K/s in 0s
2016-04-11 14:16:54 (182 MB/s) - `index.html' saved [6763/6763]
Try to access forwarded port from host, no luck... :(((
$docker-machine ip default
192.168.99.100
$ wget 192.168.99.100:33358
--2016-04-11 16:18:04-- http://192.168.99.100:33358/
Connecting to 192.168.99.100:33358... failed: Connection refused.
What do I do wrong?
Omg, desired service started on 127.0.0.1 in container, that is why it wasn't visible from outside world. I've modified service config to start on 0.0.0.0 and now I can access forwarded container port
I had the same problem and was able to fix it by specifying the host that the server within the container uses.
NOTE: when using host below, it means a web server host. When I use host-machine, I mean the main operating system I'm using, (i.e. not a container or a web server, just my laptop as a machine)
The Problem
Running web servers on the container like webpack-dev-server and http-server automatically run the app using a host of http://localhost. Typically you will see that in the output when you start the server. Something like :
Project is running at http://localhost:8080
or
Server available at http://127.0.0.1:8080
On most machines, localhost and 127.0.0.1 are the same thing. This host is not publicly viewable. As a result, your host machine can't see anything, even though it's looking in the right place.
Solution
You should specify a public host when you run the server inside your container.
webpack-dev-server --port 8080 --host 0.0.0.0
or
http-server -p 8080 -a 0.0.0.0
Because the 0.0.0.0 address is viewable to any outside machine, you should be able to see your app working as expected from your host machine.
NOTE: This works for any server, like Python's SimpleHTTPServer, etc. Just look up how to change the host for your chosen server in the documentation
Resources/Nods
(how to run webpack-dev-erver with a publicly accessible host)[How to make the webpack dev server run on port 80 and on 0.0.0.0 to make it publicly accessible?

Resources