NGINX [Optional]

If you require more structured traffic routing, NGINX can be utilized. We use the Alpine distribution of the NGINX container. Below is the nginx.conf configuration file for two secure endpoints: configure.ocs.io and api.ocs.io. NGINX can be used to route traffic and provide an additional layer of security.

First, we’ll need to create a template for our NGINX config that will contain the environment variable references.

# user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;

events {
	worker_connections 768;
	# multi_accept on;
}

http {

	##
	# Basic Settings
	##

	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;

	include /etc/nginx/mime.types;
	default_type application/octet-stream;

	##
	# SSL Settings
	##

	ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
	ssl_prefer_server_ciphers on;
	#ssl_password_file /etc/nginx/ssl_passwords.txt;

	##
	# Logging Settings
	##

	access_log /var/log/nginx/access.log;
	error_log /var/log/nginx/error.log;

	##
	# Gzip Settings
	##

	gzip on;
	gzip_disable "msie6";

	##
	# Virtual Host Configs
	##

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*;


  ##
  # define servers with port in internal network
  ##

	upstream config-server {
		server ${DNS_OCS_CONFIG_SERVER}:${OCS_CONFIG_SERVER_PORT_EXT};
	}

	upstream casm-server {
		server ${DNS_OCS_CASM_SERVER}:${OCS_CASM_SERVER_PORT_EXT};
	}

  ##
  # First, redirect all HTTP traffic to HTTPS
  ##
	server {
    listen ${NGINX_PORT_EXT} default_server;
    server_name _;

    location / {
      return 301 https://$${_X_}host$${_X_}request_uri;
    }
	}


  ##
  # redirect to upstreams based on domains
  ##

  # -- config-server
  server {
    listen ${NGINX_SEC_PORT_EXT} ssl http2;
    server_name ${OCS_CONFIG_SERVER_DOMAIN_NAME};

    location / {
      proxy_set_header X-Real-IP $${_X_}remote_addr;
      proxy_set_header X-Forwarded-For $${_X_}proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $${_X_}scheme;
      proxy_set_header Host $${_X_}http_host;
      proxy_set_header X-NginX-Proxy true;

      # proxy_pass http://[UPSTREAM_NAME]
      proxy_pass  http://config-server;
    }

    ssl_certificate /usr/share/nginx/ssl/fullchain.pem;
    ssl_certificate_key /usr/share/nginx/ssl/privkey.pem;
  }

  # -- api
  server {
    listen ${NGINX_SEC_PORT_EXT} ssl http2;
    server_name ${OCS_CASM_SERVER_DOMAIN_NAME};

    location / {
      proxy_set_header X-Real-IP $${_X_}remote_addr;
      proxy_set_header X-Forwarded-For $${_X_}proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $${_X_}scheme;
      proxy_set_header Host $${_X_}http_host;
      proxy_set_header X-NginX-Proxy true;

      # proxy_pass http://[UPSTREAM_NAME]
      proxy_pass  http://casm-server;
      }

      ssl_certificate /usr/share/nginx/ssl/fullchain.pem;
      ssl_certificate_key /usr/share/nginx/ssl/privkey.pem;
  }

}
$${_X_}<variable>, e.g. $${_X_}host is workaround to not replace $host with empty string as variable $host is not defined, as envsubst at the moment doesn’t support escaping of $ with some escape characters, e.g. $$.

We can now use our template to generate nginx.conf file which will be later passed to NGINX in docker-compose-infra.yml:

envsubst < ./nginx/nginx.conf.template > ./nginx/nginx.conf

This NGINX configuration provides secure routing for the specified endpoints.

Service section for nginx in docker-compose-infra.yml file looks like:

  # *** NGINX ***
  nginx:
    container_name: nginx
    image: nginx:1.21-alpine
    restart: always
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
      - "${SSL_DIR}:/usr/share/nginx/ssl"
    ports:
      - "${NGINX_PORT_EXT}:${NGINX_PORT_INT}"
      - "${NGINX_SEC_PORT_EXT}:${NGINX_SEC_PORT_INT}"
    networks:
      - ocs-app-network