Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HELP: Can you explain this a little more ? #48

Closed
basicBrogrammer opened this issue Dec 10, 2018 · 11 comments
Closed

HELP: Can you explain this a little more ? #48

basicBrogrammer opened this issue Dec 10, 2018 · 11 comments

Comments

@basicBrogrammer
Copy link

basicBrogrammer commented Dec 10, 2018

https://github.com/BretFisher/node-docker-good-defaults/blob/master/bin/www#L22

After getting through the docker-compose section of your class, I figured I'd try to get my local env running before continuing to docker swarm.

I used this repo as kind of a guide. My set up isn't complicated services = [nest.js, redis, postgres] (nest.js is a framework around express)

I'm also using yarn and nodemon installed locally.
CMD ['yarn', 'start:dev'] #=> nodemon

nodemon.json
{
  "watch": ["src"],
  "ext": "ts",
  "ignore": ["src/**/*.spec.ts", "src/graphql.schema.ts"],
  "exec": "ts-node -r tsconfig-paths/register src/main.ts"
}

docker-compose up works just find, but when I save a file it fails ....

nest_1      | [Nest] 45   - 12/10/2018, 1:11:09 PM   [RoutesResolver] AppController {/}: +124ms
nest_1      | [Nest] 45   - 12/10/2018, 1:11:09 PM   [RouterExplorer] Mapped {/, GET} route +11ms
nest_1      | [Nest] 45   - 12/10/2018, 1:11:12 PM   [NestApplication] Nest application successfully started +3203ms
nest_1      | Error: listen EADDRINUSE :::4000
nest_1      |     at Server.setupListenHandle [as _listen2] (net.js:1286:14)
nest_1      |     at listenInCluster (net.js:1334:12)
nest_1      |     at Server.listen (net.js:1421:7)
nest_1      |     at NestApplication.listen (/opt/app/node_modules/@nestjs/core/nest-application.js:205:25)
nest_1      | [nodemon] app crashed - waiting for file changes before starting...

Any ideas?

@BretFisher
Copy link
Owner

I'm also using yarn and nodemon installed locally.

Does this mean you're running them on host? Without your compose, npm/yarn and dockerfile's I'm not sure what the issue is.

@basicBrogrammer
Copy link
Author

Sorry no that means installed as devDeps instead of in the Dockerfile this may help
Also, I've seen something about needing to use the -L flag for nodemon ... that didn't help.
And I don't have the SIQUIT event handlers set up.

docker-compose.yml

version: '3.1'

services: # containers
  nest: # internal dns name
    build:
      context: .
      args:
        - NODE_ENV=development
    environment:
      REDIS_HOST: redis
      APP_SECRET: ${APP_SECRET}
      MTB_PROJECT_KEY: ${MTB_PROJECT_KEY}
      GOOGLE_MAPS_KEY: ${GOOGLE_MAPS_KEY}
    command: 'yarn start:dev'
    volumes:
      - .:/opt/app:delegated
      # bind-mounting these two files in will let you add packages during development without rebuilding
      # for example, to add bower to your app while developing, just install it inside the container
      # and then nodemon will restart. Your changes will last until you "docker-compose down" and will
      # be saved on host for next build
      # docker-compose exec node npm install --save bower
      - ./package.json:/opt/package.json
      - ./yarn.lock:/opt/yarn.lock
      # this is a workaround to prevent host node_modules from accidently getting mounted in container
      # in case you want to use node/npm both outside container for test/lint etc. and also inside container
      # this will overwrite the default node_modules dir in container so it won't conflict with our
      # /opt/node_modules location. Thanks to PR from @brnluiz
      - notused:/opt/app/node_modules
    ports:
      - 4000:4000
    depends_on:
      - redis
      - postgres

  redis:
    image: redis:5

  postgres:
    image: postgres:11.1
    environment:
      POSTGRES_PASSWORD: development-password
      POSTGRES_DB: mtb-nest
    volumes:
      - mtb-nest-postgres:/var/lib/postgresql/data

volumes:
  notused:
  mtb-nest-postgres:

Dockerfile

# pulled from https://github.com/BretFisher/node-docker-good-defaults
FROM node:10.14-alpine

# set our node environment, either development or production
# defaults to production, compose overrides this to development on build and run
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV

# default to port 4000 for node, and 9229 and 9230 (tests) for debug
ARG PORT=4000
ENV PORT $PORT
EXPOSE $PORT 9229 9230

# you'll likely want the latest npm, regardless of node version, for speed and fixes
# but pin this version for the best stability
RUN npm i npm@latest -g

# install yarn with npm
RUN npm i [email protected] -g

# install dependencies first, in a different location for easier app bind mounting for local development
WORKDIR /opt
COPY package.json yarn.lock ./
# RUN npm install --no-optional && npm cache clean --force
RUN yarn install
ENV PATH /opt/node_modules/.bin:$PATH

# TODO
# check every 30s to ensure this service returns HTTP 200
# HEALTHCHECK --interval=30s CMD node healthcheck.js

# copy in our source code last, as it changes the most
WORKDIR /opt/app
COPY . /opt/app

# COPY docker-entrypoint.sh /usr/local/bin/
# ENTRYPOINT ["docker-entrypoint.sh"]

# the official node image provides an unprivileged user as a security best practice
# https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#non-root-user
USER node

# if you want to use npm start instead, then use `docker run --init in production`
# so that signals are passed properly. Note the code in index.js is needed to catch Docker signals
# using node here is still more graceful stopping then npm with --init afaik
# I still can't come up with a good production way to run with npm and graceful shutdown
CMD [ "yarn", "start:prod" ]

package.json

... 
"scripts": {
  "start:dev": "nodemon"
}
...

@basicBrogrammer
Copy link
Author

I guess my questions are:

  1. What is the deal with nodemon -L ?
  2. What about the SIQUITs? Does this both prod?
  3. What did you mean in your docker file comment above CMD docker run --init in production ?

Thanks for your help! I'll post here if i find the answer

@basicBrogrammer
Copy link
Author

I think this may be related remy/nodemon@735afd5

I'll wait for the latest release and see if it fixes it 👍

@BretFisher
Copy link
Owner

  1. you don't need -L on mac usually. it enabled nodemon to manually "ls" the directories for changed files, rather than waiting for file change events to be pushed from the host OS to nodemon, aka fsevent. It's there for Windows hosts running Docker for Windows, which when bind-mounting will share the code across a SMB file share which doesn't pass file events, thus needing manual checking by nodemon.
  2. I think you mean SIGQUIT, i.e. kernel signals? I recommend taking my advice and only launching node directly from Dockerfile/compose and not using yarn as startup. IMO it adds process complexity with no benefits. I would never recommend it in a Dockerfile for prod.
  3. By default node does not listen for signals, so you can either A. do what my example .js shows by capturing those signals and doing a proper shutdown, which is the best way for real world node... or a substitute is to use --init which will throw in tini to startup node, which will properly pass kernel signals to node inside a container (but won't let you manually control process/connection shutdown like my example does in code).

@BretFisher
Copy link
Owner

OK just pushed a commit to update nodemon. Nice catch.

@basicBrogrammer
Copy link
Author

Huh 🤔 So I upgraded nodemon ... didn't fix it. I also read that node:x-alpine didn't work well with nodemon ... changed my image to node:10.14 instead of node:10.14-alpine and 💥 it worked

Thanks for your help Bret! Now i can wrap up my app and move on to the swarm sections 😎

@BretFisher
Copy link
Owner

Great! Interesting, yea I keep using the default and not alpine because little issues like this keep creeping up and the default images keep getting smaller so it's not as big a deal to force alpine on anyone, hence this repo's still not using alpine by default.

@basicBrogrammer
Copy link
Author

I guess this issue can be closed 👍
I'm trying to dockerize my work project now in ruby/node/pg/memcache 🤔 i think that's it
Stuck on another issue.
Climb one mountain to start climbing another ⛰ lol

@BretFisher
Copy link
Owner

FYI looks like your issues with nodemon and alpine docker images is fixed.

@basicBrogrammer
Copy link
Author

Awesome! Time for those docker images to go on a Diet 🤣

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants