<p>in Kube, i have one pod with two containers
* container 1: nginx reverse proxy
* container 2: myapp</p>

<p>for testing purpose, i also has a docker compose file, include the  two services
* service 1 nginx reverse proxy
* service 2: myapp</p>

<p>the issue is, in docker, the nginx upstream host is in the format of container name. In Kube, it is localhost.
Here is a code snipt:</p>

<pre><code>//for docker, nginx.conf
...
   upstream  web{
        server myapp:8080;
    }
....
            proxy_pass         http://web;

//for Kube, nginx.conf


   ...
    upstream  web{
        server localhost:8080;
    }
    ....

            proxy_pass         http://web;
    }
</code></pre>

<p>i would like to have one nginx.conf to support both kube and docker-compose.
one way i can thinkof is to pass an env run time variable, so i can sed the upstream host in the entrypoint.sh.</p>

<p>are there other ways to accomplish this?</p>

<p>thank you</p>

<p>I came across this question because we have the same issue.</p>

<p>I noticed the other answers suggested splitting nginx and the app-server into 2 different Services / Pods. Whilst that is certainly a solution, I rather like a self-contained Pod with both nginx and the app-server together. It works well for us, especially with php-fpm which can use a unix socket to communicate when in the same Pod which reduces internal http networking significantly.</p>

<p>Here is one idea:</p>

<p>Create a base nginx configuration file, for example, <code>proxy.conf</code> and setup docker to add it to the <code>conf.d</code> directory while building the image. The command is:</p>

<pre><code>ADD proxy.conf /etc/nginx/conf.d/proxy.conf
</code></pre>

<p>In the <code>proxy.conf</code>, omit the <code>upstream</code> configuration, leaving that for later. Create another file, a <code>run.sh</code> file and add it to the image using the <code>Dockerfile</code>. The file could be as follows:</p>

<pre class="lang-sh prettyprint-override"><code>#!/bin/sh

(echo "upstream theservice { server $UPSTREAM_NAME:$UPSTREAM_PORT; }" &amp;&amp; cat /etc/nginx/conf.d/proxy.conf) &gt; proxy.conf.new
mv proxy.conf.new /etc/nginx/conf.d/proxy.conf

nginx -g 'daemon off;'
</code></pre>

<p>Finally, run the nginx from the <code>run.sh</code> script. The <code>Dockerfile</code> command:</p>

<pre><code>CMD /bin/sh run.sh
</code></pre>

<p>The trick is that since the container is initialized like that, the configuration file does not get permanently written and the configuration is updated accordingly. Set the ENV vars appropriately depending on whether using from docker-compose or Kubernetes.</p>

<hr>

<p>Let me also share a less <em>proper</em> solution which is more <em>hacky</em> but also simpler...</p>

<p>In Kubernetes, we change the docker image CMD so that it modifies the nginx config before the container starts. We use <code>sed</code> to update the upstream name to <code>localhost</code> to make it compatible with Kubernetes Pod networking. In our case it looks like this:</p>

<pre><code>  - name: nginx
    image: our_custom_nginx:1.14-alpine
    command: ["/bin/ash"]
    args: ["-c", "sed -i 's/web/127.0.0.1/g' /etc/nginx/conf.d/default.conf &amp;&amp; exec nginx -g 'daemon off;'"]
</code></pre>

<p>While this workaround works, it breaks the immutable infrastructure principle, so may not be a good candidate for everyone.</p>
