<p>I'm attempting to start my Express.js application on GKE, however no matter which port I specify, I always get an error like so:</p>
<pre><code>Error: listen EACCES: permission denied tcp://10.3.253.94:3000
    at Server.setupListenHandle [as _listen2] (net.js:1296:21)
    at listenInCluster (net.js:1361:12)
    at Server.listen (net.js:1458:5)
    at Function.listen (/srv/node_modules/express/lib/application.js:618:24)
    at Object.&lt;anonymous&gt; (/srv/src/index.js:42:5)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
    at Module.load (internal/modules/cjs/loader.js:985:32)
    at Function.Module._load (internal/modules/cjs/loader.js:878:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
</code></pre>
<p>I've tried multiple ports (8080, 8000, 3000). I've set the user to <code>root</code> in the Docker image.</p>
<p>Here's my setup:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: api
  name: api
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      containers:
        - image: gcr.io/ellioseven-kbp/journal-api:1.0.14
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 3000
          name: api
</code></pre>
<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    app: api
  name: api
  namespace: default
spec:
  ports:
    - port: 3000
      protocol: TCP
      targetPort: 3000
  selector:
    app: api
  type: NodePort
</code></pre>
<pre><code>FROM node:12-alpine
ENV PATH /srv/node_modules/.bin:$PATH
ENV API_PORT 3000
ENV REDIS_HOST redis
COPY . /srv
WORKDIR /srv
ENV PATH /srv/node_modules/.bin:$PATH
RUN yarn install
CMD yarn start
EXPOSE 3000
USER root
</code></pre>
<pre><code>const port = process.env.API_PORT || 3000
app.listen(port, () =&gt; console.log(&quot;Listening on &quot; + port))
</code></pre>
<p>I'm at a complete loss trying to solve this, any help would be greatly appreciated.</p>

<p>Looks like it's not able just bind to the <code>3000</code> port. It could be any of:</p>
<ul>
<li><p>Not binding to <code>0.0.0.0</code>. You can try:</p>
<pre class="lang-js prettyprint-override"><code>app.listen('3000','0.0.0.0',()=&gt;{
    console.log(&quot;server is listening on 3000 port&quot;);
})
</code></pre>
</li>
<li><p>You are running as non-privileged user in the container. See if you can start a test pod and run the command once it started.</p>
<pre class="lang-yaml prettyprint-override"><code>  apiVersion: apps/v1
  kind: Deployment
  metadata:
    labels:
      app: api
    name: api
    namespace: default
  spec:
    replicas: 1
    selector:
      matchLabels:
        app: api
    template:
      metadata:
        labels:
          app: api
      spec:
        dnsPolicy: ClusterFirst
        restartPolicy: Always
        containers:
          - image: gcr.io/ellioseven-kbp/journal-api:1.0.14
            imagePullPolicy: IfNotPresent
            command: [ &quot;/bin/bash&quot;, &quot;-c&quot;, &quot;--&quot; ] 👈
            args: [ &quot;while true; do sleep 30; done;&quot; ] 👈
            ports:
              - containerPort: 3000
            name: api
</code></pre>
<p>Then you can connect to the pod and try to start your app</p>
<pre class="lang-sh prettyprint-override"><code>kubectl exec -it &lt;pod-name&gt; bash
</code></pre>
</li>
</ul>
<p>✌️</p>
