Docker image custom nginx.conf

7/27/2018

I am fairly new to this, I don't know if I am heading in the right direction or not. I have a custom nginx.conf that works fine, I am now trying to build a docker image with it so that I can run it as a container in kuberentes.

Here is my nginx.conf

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}


stream {
    #define the various upstreams
    upstream app_1 {
        server 192.168.122.206:5678;
    }

    upstream app_2 {
        server 192.168.122.206:9000;
    }   
    #map source port to upstream
    map $remote_port $backend_svr {
        1234 "app_1";
        1235 "app_2";
    }
    #all udp traffic received on 8000, depending on source it will be redirected
    server {
        listen 8000 udp;
        proxy_pass $backend_svr;
    }

}

On my virtual machine I have /home/asvilla/docker-files/nginx-udp/Dockerfile which contains

FROM nginx
RUN chmod +w /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/nginx.conf
RUN cat /etc/nginx/nginx.conf

I build it using

docker build -t "custom_nginx:dockerfile" .

The nginx container should redirect udp traffic incoming on port 8000 to either port 5678 or port 9000 depending on the source of the udp packet.

I run with docker run 'image-id' but it doesn't function as expected. Running docker ps shows "PORTS 80/tcp " and "COMMAND nginx-g daemon of ..."

Any pointers on what these mean. nginx by default binds tcp to port 80 but I have changed the nginx.conf, the cat command I run shows that the file is updated.

I am assuming that I have to expose the ports in the nginx.conf somehow. Any help much appreciated.

-- alexv9
docker
kubernetes
nginx

3 Answers

7/27/2018

You must publish the port at runtime like this: docker run -p 8000:8000 image-id.

-- user801247
Source: StackOverflow

7/27/2018

If your end goal is to run this in Kubernetes, your easiest path will be to put this config file into a ConfigMap and just configure your Deployment to run the standard nginx image. (In plain Docker, you can use docker run -v to inject the config file into the container at runtime to similar effect.)

It doesn't really matter what port nginx listens on inside the container. If the stock nginx container expects to listen on the standard HTTP port 80 (and it looks like its Dockerfile has an EXPOSE 80 directive) then you can embrace that and listen 80 in your nginx config (over TCP, not UDP). Then in your Kubernetes deployment you can specify that as a container port, and if you want to map it to something else, you can do that in the Service that wraps this. (In plain Docker, if you want host port 8000 to avoid conflicting with other things, docker run -p8000:80.)

In terms of best practices I'd discourage directly writing IP addresses into config files. If it's a persistent server outside your cluster, you can set up a DNS server in your network to resolve its hostname, or get a cloud service like Amazon's Route 53 to do it for you. If it's in Kubernetes, use the service's DNS name, backend.default.svc.cluster.local. Even if you really have only an IP address, creating an ExternalName service will help you if the service ever moves.

Assuming you have the config file in a ConfigMap, your Deployment would look very much like the sample Deployment in the Kubernetes documentation (it even runs an nginx:1.7.9 container publishing port 80).

-- David Maze
Source: StackOverflow

7/27/2018

In your Dockerfile you need to add EXPOSE

FROM nginx
RUN chmod +w /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/nginx.conf
RUN cat /etc/nginx/nginx.conf

EXPOSE 8000

Then when you run it you execute: docker run -p 8000:8000 custom_nginx:dockerfile

-- Mike Tung
Source: StackOverflow