I apologize if this has been answered before, or if this is the wrong place to post this, but this has me completely perplexed.
I’m having a strange issue when running with swarm mode on docker for Windows. I’m trying to deploy two containers, one based on the nginx:latest image and another custom build django app image. The nginx image is to act as the proxy for the web app.
However, when I try to run in swarm mode, the nginx container cannot contact the web app container. I have confirmed that the web app is running.
The nginx log looks like the following:
NGINX logs
2018/05/06 20:18:48 [error] 5#5: *2 connect() failed (111: Connection refused) while connecting to upstream, client: 10.255.0.2, server: localhost, request: "GET / HTTP/1.1", upstream: "http://92.242.140.2:8000/", host: "localhost", referrer: "http://localhost/about"
10.255.0.2 - - [06/May/2018:20:18:48 +0000] "GET / HTTP/1.1" 502 174 "http://localhost/about" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"
The compose file looks like:
docker-compose.yml
version: "3.3"
services:
nginx:
image: nginx:latest
ports:
- "80:80"
# This only works in swarm mode
configs:
- source: nginx_config
# need to overwrite the nginx.conf with ours.
target: /etc/nginx/nginx.conf
uid: "65534"
gid: "65534"
volumes:
- static:/static
depends_on:
- web
web:
image: mat-marketing:latest
# we want to mount the env file as a secret since it contains passwords,
# secret keys, etc...
secrets:
- source: django_secret
target: /app/django-mat-marketing-site/.env
volumes:
- static:/static
expose:
- "8000"
configs:
nginx_config:
file: ./nginx/mat_marketing.conf
secrets:
django_secret:
file: ./django-env/.env
# a named volume for the nginx container to share the /static folder from
# the web container for serving django collected static files.
volumes:
static:
The NGINX config looks like:
mat_marketing.conf
# This was started from the gunicorn deployment example NGINX conf file:
# https://github.com/benoitc/gunicorn/blob/master/examples/nginx.conf
worker_processes 1;
# 'user nobody nobody;' for systems with 'nobody' as a group instead
user nobody nogroup;
# Done to match the defualt nginx.conf from nginx:latest. Not sure if it matters.
# The NGINX Dockerfile link is in the comment below.
pid /var/run/nginx.pid;
# set this to /var/log/nginx/error.log so the stderr/stdout redirect done by the
# NGINX container works. Here's the dockerfile line that does this:
# https://github.com/nginxinc/docker-nginx/blob/d377983a14b214fcae4b8e34357761282aca788f/mainline/alpine/Dockerfile#L135
error_log /var/log/nginx/error.log;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # set to 'on' if nginx worker_processes > 1
# 'use epoll;' to enable for Linux 2.6+
# 'use kqueue;' to enable for FreeBSD, OSX
use epoll;
}
http {
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
# same reason for this log location as the error.log above
access_log /var/log/nginx/access.log combined;
sendfile on;
# The upstream must have the same name as the service configured in
# the docker-compose.yml file.
upstream web {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
# for UNIX domain socket setups
# server unix:/tmp/gunicorn.sock fail_timeout=0;
# for a TCP configuration
# server 192.168.0.7:8000 fail_timeout=0;
# We need to use the service name here since we don't know what IP
# the web docker container will have
server web:8000 fail_timeout=0;
}
server {
# if no Host match, close the connection to prevent host spoofing
listen 80 default_server;
return 444;
}
server {
# use 'listen 80 deferred;' for Linux
# use 'listen 80 accept_filter=httpready;' for FreeBSD
listen 80 deferred;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name localhost;
keepalive_timeout 5;
# configure nginx to serve static files
location /static/ {
autoindex on;
alias /static/;
}
# proxy everything else
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_pass http://web/;
}
# error_page 500 502 503 504 /500.html;
# location = /500.html {
# root /path/to/app/current/public;
# }
}
}
Here’s where things get strange. If I instead “build my own” nginx image named nginx-mat and change the compose file to reference the nginx-mat image, there is no issues contacting the web app container. The nginx configuration is unchanged.
Here’s the dockerfile for my own nginx build:
Dockerfile
FROM nginx:latest
Here’s the build command:
build command
docker build -t nginx-mat .\nginx\
Here’s the modified compose file that points to the image I built:
docker-compose.yml
version: "3.3"
services:
nginx:
# This makes zero sense, but I need to use the nginx-mat image otherwise the NGINX container cant
# contect the web app container.
image: nginx-mat:latest
I feel like the only possible answer has something to do with permissions, but I’m at a loss. Any help is greatly appreciated, as I’d much rather be able to pull the offical nginx:latest image than have to build my own.
Thanks,
-Ryan Causey