skip to Main Content

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:

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.<anonymous> (/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)

I’ve tried multiple ports (8080, 8000, 3000). I’ve set the user to root in the Docker image.

Here’s my setup:

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
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
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
const port = process.env.API_PORT || 3000
app.listen(port, () => console.log("Listening on " + port))

I’m at a complete loss trying to solve this, any help would be greatly appreciated.

2

Answers


  1. Looks like it’s not able just bind to the 3000 port. It could be any of:

    • Not binding to 0.0.0.0. You can try:

      app.listen('3000','0.0.0.0',()=>{
          console.log("server is listening on 3000 port");
      })
      
    • 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.

        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: [ "/bin/bash", "-c", "--" ] 👈
                  args: [ "while true; do sleep 30; done;" ] 👈
                  ports:
                    - containerPort: 3000
                  name: api
      

      Then you can connect to the pod and try to start your app

      kubectl exec -it <pod-name> bash
      

    ✌️

    Login or Signup to reply.
  2. Your issue is on environment variable conflicting with the service name.

    According to Kubernetes docs

    For a service named foo that maps to a Container named bar, the
    following variables are defined:

    FOO_SERVICE_HOST=<the host the service is running on>
    FOO_SERVICE_PORT=<the port the service is running on>
    

    Change either the service name or the environment variable

    For e.g. use API_PORT_NUMBER instead of API_PORT

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search