Home > other >  Dockerising a node serverless app returns directory listing only
Dockerising a node serverless app returns directory listing only

Time:08-31

Noob NodeJS/Docker question here.

I've written a node.js serverless project in an Ubuntu environment. I'm now trying to dockerise it.

The project has the following in the scripts section of package.js:

  "scripts": {
    "dev": "node --inspect $(npm bin)/sls offline start",
    "docker": "node $(npm bin)/sls offline start --host 0.0.0.0"
  }

Running npm run dev in my Ubuntu environment (22.04.1 LTS, node version 18.8.0) works fine, no issues. The API starts up and the project executes as expected.

I have the following in a Dockerfile:

FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

RUN export SLS_DEBUG=* 

# Node 18x, https://github.com/nodesource/distributions
RUN apt-get update && \ 
    apt-get upgrade -y && \
    apt-get install openjdk-11-jdk -y && \
    apt install curl -y && \
    curl -sL https://deb.nodesource.com/setup_current.x | bash - && \
    apt install nodejs -y 

ADD ./ /app
WORKDIR /app

RUN npm install

# Serverless port
EXPOSE 3000
# NodeJS debug port
EXPOSE 9229

CMD npm run docker

I'm using the Ubuntu image and the node distribution to try and get the container as close as possible to my dev environment. The image builds successfully.

When running the built image, I just get the directory listing of the container, like:

./
 ├─lambda_funcs/
 │ └─test_func( )/
 ├─models/
 │ └─user.js
 ├─node_modules/
 │ ├─2-thenable( )/
...etc

I'm happy to try using the node image as a base, but I don't understand why the docker image is doing something different than my dev environment. I don't even really understand why the directory listing is being output, other than assuming Node is having trouble finding the serverless module. But the package and package-lock files are being copied across, and I can see the serverless,serverless-offline and sls packages in the dependencies listing.

A Hello World Node app runs fine in the container, so it seems to be something to do with serverless itself?

Any help appreciated. Thanks

EDIT:

To be clear, I am expecting a serverless API to be run and accessible on port 3000 using the following serverless template:

service: My Service
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x
  stage: dev
  environment:
    cowenv: dev

functions:
  my_test:
    name: test_func
    handler: lambda_funcs/test_func/index.handler
    events:
      - httpApi:
          path: /test
          method: get

  mysql:
    stages:
      - dev
    start:
      docker: true
      port: 8000
      inMemory: true
      migrate: true
      seed: false
      convertEmptyValues: true
      noStart: true

package:
    individually: true

plugins:
  - serverless-offline

npm run docker is the command I am using in the Dockerfile as an alias for node $(npm bin)/sls offline start --host 0.0.0.0

test_func should talk to the database and return some values.

CodePudding user response:

Not sure why you install the OS image. Just install Node.js image instead.

Dockerfile example:

FROM node:16.16.0

WORKDIR /app

COPY package.json .
RUN yarn install
COPY . .

And then you specify ENV commands ports volumes in your docker-compose file

CodePudding user response:

So in this case it seems like Node was interpreting node $(npm bin)/sls offline start --host 0.0.0.0 as, "run the sls library" aka the structured list library: https://www.npmjs.com/package/sls which means it was displaying exactly what was expected.

If I uninstall sls (not sure how it got installed), running the container outputs:

> node $(npm bin)/sls offline

/app/node_modules/.bin/sls:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^

SyntaxError: missing ) after argument list

I stumbled across https://forum.serverless.com/t/possible-to-run-serverless-in-a-docker-container/5764, more specifically slinkardbrandon's answer. Essentially he uses a direct link to the serverless libraries within the Docker environment as parameters to CMD (a Gist is linked here):

CMD ["node", "./node_modules/serverless/bin/serverless.js", "offline", "start",  "--host", "0.0.0.0"]

Why doesn't it work otherwise? Why have I seen sls offline being used in other docker containers with no issues? Who knows! I suspect gremlins.

But at least my application works now. I incidentally also did the rewrite to use node as a base image, so my Dockerfile is a lot cleaner. Thanks to all for your help.

  • Related