<p>I'm trying to deploy my Dockerized React app to Kubernetes. I believe I've dockerized it correctly, but i'm having trouble accessing the exposed pod.</p>

<p>I don't have experience in Docker or Kubernetes, so any help would be appreciated.</p>

<p>My React app is just static files (from npm run build) being served from Tomcat.</p>

<p>My Dockerfile is below. In summary, I put my app in the Tomcat folder and expose port 8080.</p>

<pre><code>FROM private-docker-registry.com/repo/tomcat:latest

EXPOSE 8080:8080

# Copy build directory to Tomcat webapps directory
RUN mkdir -p /tomcat/webapps/app
COPY /build/sample-app /tomcat/webapps/app

# Create a symbolic link to ROOT -- this way app starts at root path 
(localhost:8080)

RUN ln -s /tomcat/webapps/app /tomcat/webapps/ROOT

# Start Tomcat
ENTRYPOINT ["catalina.sh", "run"]
</code></pre>

<p>I build and pushed the Docker image to the Private Docker Registry.
I verified that container runs correctly by running it like this:</p>

<pre><code>docker run -p 8080:8080 private-docker-registry.com/repo/sample-app:latest
</code></pre>

<p>Then, if I go to localhost:8080, I see the homepage of my React app.</p>

<p>Now, the trouble I'm having is deploying to Kubernetes and accessing the app externally.</p>

<p>Here's my deployment.yaml file:</p>

<pre><code>kind: Deployment
apiVersion: apps/v1beta2
metadata:
  name: sample-app
  namespace: dev
  labels:
    app: sample-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: sample-app
        image: private-docker-registry.com/repo/sample-app:latest
        ports:
        - containerPort: 8080
          protocol: TCP
      nodeSelector:
        TNTRole: luxkube
---
kind: Service
apiVersion: v1
metadata:
  name: sample-app
  labels:
    app: sample-app
spec:
  selector:
    app: sample-app
  type: NodePort
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
</code></pre>

<p>I created the deployment and service by running
    kubectl --namespace=dev create -f deployment.yaml</p>

<pre><code>Output of 'describe deployment'

    Name:                   sample-app
    Namespace:              dev
    CreationTimestamp:      Sat, 21 Jul 2018 12:27:30 -0400
    Labels:                 app=sample-app
    Annotations:            deployment.kubernetes.io/revision=1
    Selector:               app=sample-app
    Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=sample-app
      Containers:
       sample-app:
        Image:        private-docker-registry.com/repo/sample-app:latest
        Port:         8080/TCP
        Host Port:    0/TCP
        Environment:  &lt;none&gt;
        Mounts:       &lt;none&gt;
      Volumes:        &lt;none&gt;
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  &lt;none&gt;
    NewReplicaSet:   sample-app-bb6f59b9 (1/1 replicas created)
    Events:          &lt;none&gt;

Output of 'describe service'

Name:                     sample-app
Namespace:                fab-dev
Labels:                   app=sample-app
Annotations:              &lt;none&gt;
Selector:                 app=sample-app
Type:                     NodePort
IP:                       10.96.29.199
Port:                     &lt;unset&gt;  80/TCP
TargetPort:               8080/TCP
NodePort:                 &lt;unset&gt;  34604/TCP
Endpoints:                192.168.138.145:8080
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   &lt;none&gt;
</code></pre>

<p>Now I don't know which IP and port I should be using to access the app.
I have tried every combination but none has loaded my app. I believe the port should be 80, so if I just have the IP, i shuold be able to go to the browser and access the React app by going to http://.</p>

<p>Does anyone have suggestions?</p>

<p>The short version is that the Service is listening on the same TCP/IP port on every Node in your cluster (<code>34604</code>) as is shown in the output of <code>describe service</code>:</p>

<pre><code>NodePort:                 &lt;unset&gt;  34604
</code></pre>

<p>If you wish to access the application through a "nice" URL, you'll want a load balancer that can translate the hostname into the in-cluster IP and port combination. That's what an Ingress controller is designed to do, but it isn't the only way -- changing the Service to be <code>type: LoadBalancer</code> will do that for you, if you're running in a cloud environment where Kubernetes knows how to programmatically create load balancers for you.</p>
