The web server

Our web server changes will be a bit trickier due to a quirk/feature of the NGINX configuration processing that may also impact you if you do Java-based DNS resolution. Essentially, NGINX caches DNS entries so hard that effectively, once it reads the configuration files, any new DNS resolution within that configuration will not actually take place at all unless some extra flags ( resolver ) are specified. With the Docker service being constantly mutable and relocatable, this is a serious issue that must be worked around to function properly on the Swarm. Here, you have a couple of options:

  • Run a DNS forwarder (such as dnsmasq) in parallel with NGINX and use that as the resolver. This requires running both dnsmasq and NGINX in the same container.
  • Populate the NGINX configuration container start with the same resolvers from the system using something such as envsubst: this requires all containers to be in the same user-defined network.
  • Hardcode the DNS resolver IP (127.0.0.11): this also requires all containers to be in the same user-defined network.

For robustness, we will use the second option, so copy the web server from the previous chapter into a new folder and rename it to nginx_main_site.conf.template. We will then add a resolver configuration to it and a variable $APP_NAME for our proxy host endpoint:

server {
listen 8080;
server_name _;

resolver $DNS_RESOLVERS;

root /srv/www/html;

location ~/. {
deny all;
}

location / {
auth_basic "Authentication required";
auth_basic_user_file /srv/www/html/.htpasswd;

proxy_pass http://$APP_NAME:8000;
}
}

Since NGINX does not handle environment variable substitution in the configuration files, we will write a wrapper script around it. Add a new file called start_nginx.sh and include the following content in it that takes the host's resolvers and generates the new main_site config:

#!/bin/bash -e

export DNS_RESOLVERS=$(cat /etc/resolv.conf | grep 'nameserver' | awk '{ print $2 }' | xargs echo)

cat /etc/nginx/conf.d/nginx_main_site.conf.template | envsubst '$DNS_RESOLVERS $APP_NAME' > /etc/nginx/conf.d/nginx_main_site.conf

nginx -g 'daemon off;'

To get this to run, we finally need to make sure we start NGINX with this script instead of the one built in, so we need to modify our Dockerfile as well.

Open up our Dockerfile and make sure that it has the following:

FROM nginx:latest

RUN apt-get update -q &&
apt-get dist-upgrade -y &&
apt-get install openssl &&
apt-get clean &&
apt-get autoclean

EXPOSE 8080

ENV SRV_PATH /srv/www/html

ARG PASSWORD=test

RUN rm /etc/nginx/conf.d/default.conf

COPY start_nginx.sh /usr/local/bin/

RUN mkdir -p $SRV_PATH &&
chown nginx:nginx $SRV_PATH &&
printf "user:$(openssl passwd -crypt $PASSWORD) " >> $SRV_PATH/.htpasswd &&
chmod +x /usr/local/bin/start_nginx.sh

COPY nginx_main_site.conf.template /etc/nginx/conf.d/

CMD ["/usr/local/bin/start_nginx.sh"]

Here, the main change is the start up script CMD override and turning the configuration into a template with the rest pretty much left alone.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.111.130