<p>I'm trying to use docker-compose and kubernetes as two different solutions to setup a Django API served by Gunicorn (as the web server) and Nginx (as the reverse proxy). Here are the key files:</p>

<p>default.tmpl (nginx) - this is converted to default.conf when the environment variable is filled in:</p>

<pre><code>upstream api {
    server ${UPSTREAM_SERVER};
}

server {
    listen 80;

    location / {
        proxy_pass http://api;
    }

    location /staticfiles {
        alias /app/static/;
    }
}
</code></pre>

<p>docker-compose.yaml:</p>

<pre><code>version: '3'
services:
  api-gunicorn:
    build: ./api
    command: gunicorn --bind=0.0.0.0:8000 api.wsgi:application
    volumes:
      - ./api:/app

  api-proxy:
    build: ./api-proxy
    command: /bin/bash -c "envsubst &lt; /etc/nginx/conf.d/default.tmpl &gt; /etc/nginx/conf.d/default.conf &amp;&amp; exec nginx -g 'daemon off;'"
    environment:
      - UPSTREAM_SERVER=api-gunicorn:8000
    ports:
      - 80:80
    volumes:
      - ./api/static:/app/static
    depends_on:
      - api-gunicorn
</code></pre>

<p>api-deployment.yaml (kubernetes):</p>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: release-name-myapp-api-proxy
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: myapp-api-proxy
  template:
    metadata:
      labels:
        app.kubernetes.io/name: myapp-api-proxy
    spec:
      containers:
        - name: myapp-api-gunicorn
          image: "helm-django_api-gunicorn:latest"
          imagePullPolicy: Never
          command:
            - "/bin/bash"
          args:
            - "-c"
            - "gunicorn --bind=0.0.0.0:8000 api.wsgi:application"
        - name: myapp-api-proxy
          image: "helm-django_api-proxy:latest"
          imagePullPolicy: Never
          command:
            - "/bin/bash"
          args:
            - "-c"
            - "envsubst &lt; /etc/nginx/conf.d/default.tmpl &gt; /etc/nginx/conf.d/default.conf &amp;&amp; exec nginx -g 'daemon off;'"
          env:
            - name: UPSTREAM_SERVER
              value: 127.0.0.1:8000
          volumeMounts:
            - mountPath: /app/static
              name: api-static-assets-on-host-mount
      volumes:
        - name: api-static-assets-on-host-mount
          hostPath:
            path: /Users/jonathan.metz/repos/personal/code-demos/kubernetes-demo/helm-django/api/static
</code></pre>

<p>My question involves the <code>UPSTREAM_SERVER</code> environment variable.</p>

<p>For <code>docker-compose.yaml</code>, the following values have worked for me:</p>

<ul>
<li>Setting it to the name of the gunicorn service and the port it's running on (in this case <code>api-gunicorn:8000</code>). This is the best way to do it (and how I've done it in the docker-compose file above) because I don't need to expose the <code>8000</code> port to the host machine.</li>
<li>Setting it to <code>MY_IP_ADDRESS:8000</code> as <a href="https://stackoverflow.com/questions/38346847/nginx-docker-container-502-bad-gateway-response">described in this SO post</a>. This method requires me to expose the <code>8000</code> port, which is not ideal.</li>
</ul>

<p>For <code>api-deployment.yaml</code>, only the following value has worked for me:</p>

<ul>
<li>Setting it to <code>localhost:8000</code>. <a href="https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/#networking" rel="nofollow noreferrer">Inside of a pod, all containers can communicate using localhost</a>.</li>
</ul>

<p>Are there any other values for <code>UPSTREAM_SERVER</code> that work here, especially in the kubernetes file? I feel like I should be able to point to the container's name and that should work.</p>

Johnny Metz
<p>You could create a <a href="https://kubernetes.io/docs/concepts/services-networking/service/" rel="nofollow noreferrer">service</a> to target container <em>myapp-api-gunicorn</em> but this will expose it  outside of the <code>pod</code>:</p>

<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Service
metadata:
  name: api-gunicorn-service
spec:
  selector:
    app.kubernetes.io/name: myapp-api-proxy
  ports:
    - protocol: TCP
      port: 8000
      targetPort: 8000
</code></pre>

<p>You might also use <a href="https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pods" rel="nofollow noreferrer">hostname and subdomain fields</a> inside a <code>pod</code> to take advantage of FQDN.</p>

<blockquote>
  <p>Currently when a pod is created, its hostname is the Pod’s  <code>metadata.name</code>  value.</p>
  
  <p>The Pod spec has an optional  <code>hostname</code>  field, which can be used to specify the Pod’s hostname. When specified, it takes precedence over the Pod’s name to be the hostname of the pod. For example, given a Pod with  <code>hostname</code>  set to “<code>my-host</code>”, the Pod will have its hostname set to “<code>my-host</code>”.</p>
  
  <p>The Pod spec also has an optional  <code>subdomain</code>  field which can be used to specify its subdomain. For example, a Pod with  <code>hostname</code>  set to “<code>foo</code>”, and  <code>subdomain</code>  set to “<code>bar</code>”, in namespace “<code>my-namespace</code>”, will have the fully qualified domain name (FQDN) “<code>foo.bar.my-namespace.svc.cluster-domain.example</code>”.</p>
</blockquote>

<p>Also here is a nice article from <a href="https://www.mirantis.com/" rel="nofollow noreferrer">Mirantis</a> which talks about <a href="https://www.mirantis.com/blog/multi-container-pods-and-container-communication-in-kubernetes/" rel="nofollow noreferrer">exposing multiple containers in a pod</a></p>
