Using this docker-compose file:
version: '3'
services:
hello:
image: nginxdemos/hello
ports:
- 7080:80
tool:
image: wbitt/network-multitool
tty: true
networks:
default:
name: test-network
If I curl from the host, it works.
❯ curl -s -o /dev/null -v http://192.168.1.102:7080
* Expire in 0 ms for 6 (transfer 0x8088b0)
* Trying 192.168.1.102...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x8088b0)
* Connected to 192.168.1.102 (192.168.1.102) port 7080 (#0)
> GET / HTTP/1.1
> Host: 192.168.1.102:7080
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Sun, 10 May 2071 00:06:00 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Expires: Sun, 10 May 2071 00:05:59 GMT
< Cache-Control: no-cache
<
{ [6 bytes data]
* Connection #0 to host 192.168.1.102 left intact
If I try to contact another container from within the network, it fails.
❯ docker exec -it $(gdid tool) curl -s -o /dev/null -v http://hello
* Could not resolve host: hello
* Closing connection 0
Is this intended behaviour? I thought networks within the same network (and using docker-compose) are meant to be able to talk by their service name?
I am bringing the containers up with docker-compose up -d
I installed the Docker release of ColdFusion with the following command:
docker pull eaps-docker-coldfusion.bintray.io/cf/coldfusion:latest
I then created a compose file:
version: "3.7"
services:
coldfusion:
image: eaps-docker-coldfusion.bintray.io/cf/coldfusion:latest
ports:
- "8500:8500"
networks:
coldfusion:
hostname: coldfusion
volumes:
- "~/dev/docker/projects/coldfusion/volumes/app:/app"
- "~/dev/docker/projects/coldfusion/volumes/logs:/opt/coldfusion/cfusion/logs"
environment:
acceptEULA: "YES"
password: "ColdFusion123"
enableSecureProfile: "false"
HOST_USER_ID: ${CURRENT_UID}
HOST_GROUP_ID: ${CURRENT_GID}
deploy:
replicas: 1
restart_policy:
condition: any
delay: 5s
max_attempts: 3
window: 10s
healthcheck:
test: curl --fail http://localhost:8500 || exit 1
interval: 1m
timeout: 3s
retries: 3
networks:
coldfusion:
name: coldfusion
common:
external: true
name: common
and started it with the command:
docker stack deploy --compose-file docker-compose-dev.yml coldfusion
The log shows:
stephane#stephane-pc:~/dev/docker/projects/coldfusion$ docker service logs -f coldfusion_coldfusion
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Updating webroot to /app
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Configuring virtual directories
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Updating password
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Skipping language updation
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Serial Key: Not Provided
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Previous Serial Key: Not Provided
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Starting ColdFusion
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Starting ColdFusion 2018 server ...
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | The ColdFusion 2018 server is starting up and will be available shortly.
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | ======================================================================
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | ColdFusion 2018 server has been started.
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | ColdFusion 2018 will write logs to /opt/coldfusion/cfusion/bin/../logs/coldfusion-out.log
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | ======================================================================
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | [000] Checking server startup status...
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | % Total % Received % Xferd Average Speed Time Time Time Current
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | External Addons: Disabled
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | External Session Storage: Disabled
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Skipping setup script invocation
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Secure Profile: Disabled
coldfusion_coldfusion.1.rlhixv3jctvm#stephane-pc | Cleaning up setup directories
But it hangs when typing the http://localhost:8500/ request in the browser.
The log remains empty:
tail -f volumes/logs/coldfusion-out.log
I created an index.cfm page in the /app directory:
hi
<cfset firstName = "World">
Hello <cfoutput>#firstName#</cfoutput>!
This CFML tutorial was designed for
<cfif firstName eq "World">
you!
<cfelse>
the world to see.
</cfif>
UPDATE: A 200 response comes back fine when using 127.0.0.1 instead of localhost
Opening the firewall ports does not change anything to the issue:
stephane#stephane-pc:~$ sudo ufw allow from 127.0.0.0 to any port 8500;
Rules updated
stephane#stephane-pc:~$ sudo ufw allow from any to any port 8500;
Rules updated
Rules updated (v6)
My host /etc/hosts file contains the line:
127.0.0.1 localhost
The nmap command responds:
stephane#stephane-pc:~/dev/docker/projects/coldfusion$ nmap -p 8500 localhost
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-08 12:09 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00038s latency).
PORT STATE SERVICE
8500/tcp open fmtp
Nmap done: 1 IP address (1 host up) scanned in 0.22 seconds
Your docker compose file shows
hostname: coldfusion
so shouldn't it be available at http://coldfusion:8500?
If it's docker compose v3, it should be
services:
dns:
hostname: 'your-domain'
Update
The details in this question are getting long, but I think it narrows down to this:
For some reason the host name matters to Nginx when it's trying to figure out whether to proxy the request. If the host name is set to git.example.com the request does not seem to go through, but if it's set to 203.0.113.2 then it goes through. Why does the host name matter?
Filed an issue with Nginx here
And docker compose
Start of original question
When I type in the IP address of the reverse proxy directly into my browser bar, it does perform the redirect.
When using a URL that is resolved via the /etc/hosts entry 203.0.113.2 git.example.com the "Welcome to Ngnix page" is shown. Any ideas? This is the configuration:
server {
listen 203.0.113.2:80 default_server;
server_name 203.0.113.2 git.example.com;
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
location / {
proxy_pass http://203.0.113.1:3000;
}
}
This is the docker-compose.yml file that is used to launch the whole thing:
version: '3'
services:
gogs-nginx:
build: ./proxy
ports:
- "80:80"
networks:
mk1net:
ipv4_address: 203.0.113.2
gogs:
image: gogs/gogs
ports:
- "3000:3000"
volumes:
- gogs-data:/data
networks:
mk1net:
ipv4_address: 203.0.113.3
volumes:
gogs-data:
external: true
networks:
mk1net:
ipam:
config:
- subnet: 203.0.113.0/24
One interesting thing is that I can navigate to for example:
http://203.0.113.2/issues
The log for the above URL is:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:28:06 +0000] "GET / HTTP/1.1" 200 38825 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"
If I then change 203.0.113.2 with git.example.com (So that the url ends up being git.example.com I get Nginxs "404 not found" page, and the log says:
gogs-nginx_1 | 2018/10/07 11:31:34 [error] 8#8: *10 open() "/usr/share/nginx/html/issues" failed (2: No such file or directory), client: 203.0.113.1, server: localhost, request: "GET /issues HTTP/1.1", host: "git.example.com"
If I only use http://git.example.com as the URL I get the NGINX welcome page, and the following log:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:34:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"
It looks like Nginx understands that the request is for the proxy because it logs the IP of the proxy, but it does not redirect to the proxy and returns a 304 ...
Using Curl to perform requests
Using curl with a host name parameter that targets the proxy like this:
curl -H 'Host: git.example.com' -si http://203.0.113.2
Results in the Nginx welcome page:
ole#mki:~/Gogs/.gogs/docker$ curl -H 'Host: git.example.com' -si http://203.0.113.2
HTTP/1.1 200 OK
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:09:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Jul 2018 13:27:08 GMT
Connection: keep-alive
ETag: "5b3b79ac-264"
Accept-Ranges: bytes
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
nginx.org.<br/>
Commercial support is available at
nginx.com.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
But if I change the host name to the ip address like this:
Using curl with a host name parameter that targets the proxy like this:
curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
Then the proxy works as it should:
ole#mki:~/Gogs/.gogs/docker$ curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
HTTP/1.1 302 Found
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:14:46 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34
Connection: keep-alive
Location: /user/login
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=845bb09d69587b81; Path=/; HttpOnly
Set-Cookie: _csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 17:14:46 GMT; HttpOnly
Set-Cookie: redirect_to=%252F; Path=/
Found.
I am sorry, I failed to realize what's happening on your side because the information is sometimes confusing and sometimes incomplete. But Stackoverflow provides a great explanation on what is considered a good question: How to create a Minimal, Complete, and Verifiable example and so I have just tried to implement a minimal example of a system you are likely going to build.
Below I am providing all the files and will show you a test run as well.
File #1: docker-compose.yml
gogs:
image: gogs/gogs
web:
build: .
ports:
- 8000:80
links:
- gogs
I have outdated Docker at my computer and I do not want to bother with Docker networking, so I have just linked both containers using Docker links. This is the most important part and the link will ensure that (1) our web container depends on gogs; (2) we are able to reference gogs IP from inside web as just gogs. Docker will resolve the name to an IP assigned to the container.
Since I want a minimal example, I've skipped everything else as irrelevant. For example, volume.
File #2: Dockerfile
Newer Compose versions support config options specified right in docker-compose.yml, but I need a custom Dockerfile instead. It's trivial:
FROM nginx:stable-alpine
COPY gogs.conf /etc/nginx/conf.d
File #3: gogs.conf
And finally we need Nginx configuration for proxy:
server {
listen 80 default_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://gogs:3000;
}
}
You may notice here we are referring another container simply by name gogs and we need to know what port number it is exposes. We know: 3000.
Running
$ docker-compose build
$ docker-compose up
It's up and running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f74293df630 g_web "nginx -g 'daemon off" 2 minutes ago Up 26 seconds 0.0.0.0:8000->80/tcp g_web_1
dfa2dbaa6074 gogs/gogs "/app/gogs/docker/sta" 2 minutes ago Up 26 seconds 22/tcp, 3000/tcp g_gogs_1
web container is exposed to the world at port number 8000.
Tests
by IP
Let's request it by IP:
$ curl -si http://192.168.99.100:8000/
HTTP/1.1 302 Found
Server: nginx/1.14.0
Date: Sun, 07 Oct 2018 15:13:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 31
Connection: keep-alive
Location: /install
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=50411f542e2ae8f8; Path=/; HttpOnly
Set-Cookie: _csrf=ZJxRPqnqayIbpAYgZ22zrPIOaSo6MTUzODkyNTIzNTQ2NTg5MDE1NA%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 15:13:55 GMT; HttpOnly
Found.
Corresponding log file:
web_1 | 192.168.99.1 - - [07/Oct/2018:15:14:24 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
gogs_1 | [Macaron] 2018-10-07 15:14:24: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:14:24: Completed GET / 302 Found in 199.519µs
gogs_1 | 2018/10/07 15:14:24 [TRACE] Session ID: 38d06d393a9e9d21
gogs_1 | 2018/10/07 15:14:24 [TRACE] CSRF Token: Xth986dFWhhj8w8vBdIqRZu4SbI6MTUzODkyNTI2NDYxMDYzNzAyNA==
I can see from the log that (1) both containers work and they were used to process the request; (2) 192.168.99.1 is my host's IP address, which means "gogs" successfully gets a real request IP via X-Forwarded-For.
by domain name
OK, let's request using a domain name:
$ curl -H 'Host: g.example.com' -si http://192.168.99.100:8000/
Trust me, this is just sufficient. Host is an HTTP protocol header to pass domain name. And any browser will do the same under the hood.
and the corresponding log file is --
gogs_1 | [Macaron] 2018-10-07 15:32:49: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:32:49: Completed GET / 302 Found in 618.701µs
gogs_1 | 2018/10/07 15:32:49 [TRACE] Session ID: 81f64d97e9c3dd1e
gogs_1 | 2018/10/07 15:32:49 [TRACE] CSRF Token: X5QyHM4LMIfn8OSJD1gwSSEyXV46MTUzODkyNjM2OTgyODQyMjExMA==
web_1 | 192.168.99.1 - - [07/Oct/2018:15:32:49 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
No changes, everything works as expected.
When I try to connect to my app I can connect and start sending and receiving ICE candidates. But the negotiation does not complete the rtc connection state eventually gets to "Checking", and then after about 30 seconds drops to "Failed"
I have this working with a local setup, but once I have deployed to AWS this starts to fail.
I went and bjorked the settings in AWS and opened all the ports and now I can reach the coturn service (returns 200 when requesting through http), and the Trickle service here works fine.
I am using the Kurento Media Server and hoping to make a websocket connection to that service. As I mentioned this works locally so I'm fairly sure that there is nothing wrong with how I'm making the request but instead it is a configuration option with AWS or my docker compose file.
I have a docker compose file with three apps in it:
version: "3.4"
services:
media-controller:
image: my-custom-images/my-server:latest.version
volumes:
- "tmp-video-storage:/tmp"
ports:
- "8899:8899"
kurento-media-service:
image: kurento/kurento-media-server:6.6.0
volumes:
- "tmp-video-storage:/tmp"
ports:
- "8888:8888"
coturn:
image: my-custom-images/coturn:lastest.version
ports:
- "3478:3478/udp"
- "3478:3478/tcp"
volumes:
tmp-video-storage:
coturn's /etc/turnserver.conf
min-port=49152
max-port=65535
fingerprint
lt-cred-mech
realm=my-domain.com
log-file stdout
user=username-placeholder:password-placeholder
external-ip=public-ip/private-ip
listening-port=3478
Output from Trickle Ice Candidates:
0.004 1 host 1019731727 udp 192.168.1.104 64702 126 | 32543 | 0
0.068 1 srflx 3180321211 udp 10.255.0.2 64702 100 | 32542 | 255
0.091 1 relay 610197926 udp 35.183.10.44 50008 2 | 32542 | 255
0.106 1 host 1917068287 tcp 192.168.1.104 9 90 | 32542 | 255
0.106 Done
0.120
I have the following configuration for my stack:
api:
deployment_strategy: every_node
environment:
- 'DATABASE_URL=postgresql://.....'
- REDIS_HOST=redis
image: 'image/image:latest'
links:
- redis
ports:
- '5000:5000'
lb:
image: 'dockercloud/haproxy:latest'
links:
- api
ports:
- '80:80'
privileged: true
roles:
- global
and this is the haproxy output
2017-05-26T12:00:51.752500376Z INFO:haproxy:dockercloud/haproxy 1.6.6 has access to the Docker Cloud API - will reload list of backends in real-time
2017-05-26T12:00:51.752599249Z INFO:haproxy:dockercloud/haproxy PID: 5
2017-05-26T12:00:51.883065649Z INFO:haproxy:=> Add task: Websocket open
2017-05-26T12:00:52.884078353Z INFO:haproxy:=> Executing task: Websocket open
2017-05-26T12:00:52.884105435Z INFO:haproxy:==========BEGIN==========
2017-05-26T12:00:53.364820267Z INFO:haproxy:Linked service: API(d73c0091-ae4f-43b8-a3a8-ea11a276652e)
2017-05-26T12:00:53.364872613Z INFO:haproxy:Linked container: API_1(3f981340-9b04-4105-8876-2ad1e5521f5c)
2017-05-26T12:00:53.365695674Z INFO:haproxy:HAProxy configuration:
2017-05-26T12:00:53.365705363Z global
2017-05-26T12:00:53.365708753Z log 127.0.0.1 local0
2017-05-26T12:00:53.365712075Z log 127.0.0.1 local1 notice
2017-05-26T12:00:53.365715245Z log-send-hostname
2017-05-26T12:00:53.365718228Z maxconn 4096
2017-05-26T12:00:53.365721207Z pidfile /var/run/haproxy.pid
2017-05-26T12:00:53.365724305Z user haproxy
2017-05-26T12:00:53.365727513Z group haproxy
2017-05-26T12:00:53.365730447Z daemon
2017-05-26T12:00:53.365733783Z stats socket /var/run/haproxy.stats level admin
2017-05-26T12:00:53.365736704Z ssl-default-bind-options no-sslv3
2017-05-26T12:00:53.365746260Z ssl-default-bind-ciphers xxxxxx
2017-05-26T12:00:53.365752089Z defaults
2017-05-26T12:00:53.365755064Z balance roundrobin
2017-05-26T12:00:53.365758035Z log global
2017-05-26T12:00:53.365761046Z mode http
2017-05-26T12:00:53.365764045Z option redispatch
2017-05-26T12:00:53.365767032Z option httplog
2017-05-26T12:00:53.365769951Z option dontlognull
2017-05-26T12:00:53.365775842Z option forwardfor
2017-05-26T12:00:53.365780388Z timeout connect 5000
2017-05-26T12:00:53.365793420Z timeout client 50000
2017-05-26T12:00:53.365796603Z timeout server 50000
2017-05-26T12:00:53.365799585Z listen stats
2017-05-26T12:00:53.365802356Z bind :1936
2017-05-26T12:00:53.365805270Z mode http
2017-05-26T12:00:53.365808233Z stats enable
2017-05-26T12:00:53.365811235Z timeout connect 10s
2017-05-26T12:00:53.365814235Z timeout client 1m
2017-05-26T12:00:53.365817155Z timeout server 1m
2017-05-26T12:00:53.365827005Z stats hide-version
2017-05-26T12:00:53.365830160Z stats realm Haproxy\ Statistics
2017-05-26T12:00:53.365833322Z stats uri /
2017-05-26T12:00:53.365837063Z stats auth stats:stats
2017-05-26T12:00:53.365839909Z frontend default_port_80
2017-05-26T12:00:53.365842760Z bind :80
2017-05-26T12:00:53.365845760Z reqadd X-Forwarded-Proto:\ http
2017-05-26T12:00:53.365848857Z maxconn 4096
2017-05-26T12:00:53.365851745Z default_backend default_service
2017-05-26T12:00:53.365854664Z backend default_service
2017-05-26T12:00:53.365857581Z server API_1 10.7.0.2:5000 check inter 2000 rise 2 fall 3
2017-05-26T12:00:53.365886854Z INFO:haproxy:Launching HAProxy
2017-05-26T12:00:53.368391859Z INFO:haproxy:HAProxy has been launched(PID: 12)
2017-05-26T12:00:53.368498117Z INFO:haproxy:===========END===========
when I access the haproxy IP, I get ERR_CONNECTION_REFUSED on Chrome and the API service logs is empty, but when I access the haproxy on port 5000, then yes, the request hits my API.
I found it very weird, because I thought that HAProxy would do this routing for me. Am I missing something? maybe bind 80:5000?
This very simple example is working for me:
api:
image: nginx
lb:
image: 'dockercloud/haproxy:latest'
links:
- api
ports:
- '80:80'
privileged: true
(without the roles part because I'm not using docker cloud)
...
lb_1 | INFO:haproxy:HAProxy has been launched(PID: 13)
lb_1 | INFO:haproxy:===========END===========
api_1 | 172.17.0.3 - - [26/May/2017:12:40:36 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36" "172.17.0.1"
...
maybe bind 80:5000?
You shouldn't. It should be enough accessing :80 and then haproxy do the rest.