Gatsby not rebuilding whenever mounted code changes - docker

I used the typical gatsby init given by the gatsby-cli. And, I wanted to use docker to automate even further.
.
|- src
|- gatsby-*.js
|- node_modules
|- Dockerfile
|- docker-compose.yml
|- package*.json
|- public
Here's my Dockerfile:
FROM node:12
# Add the package.json file and build the node_modules folder
WORKDIR /app
COPY ./package*.json ./
RUN mkdir node_modules && npm install
RUN npm install --global gatsby-cli && gatsby telemetry --disable
Here's my docker-compose.yml
version: '3.7'
services:
gatsby:
build:
context: .
dockerfile: Dockerfile
working_dir: /app
command: gatsby develop -H 0.0.0.0
ports:
- "8000:8000"
volumes:
- .:/app
- /app/node_modules/
The problem is that whenever I change anything locally and I have verified this through going inside the container to make sure the changes was copied to the container, the changes didn't trigger a build.
I have no problems with accessing the exposed port in my localhost. Anything that I did wrong? I have verified that the build does run but only once. There's no indication of errors during the build process only WARN stuff from npm installs which was also the case when I installed locally.

I think I wasn't using google keywords right. If only I used the word, recompile instead of rebuilding.
https://github.com/gatsbyjs/gatsby/issues/10836
This made it work for me.

Related

Nuxt 3 Docker doesn't recognize new pages, what am I doing wrong?

I have a problem with my Nuxt 3 project that I run with Docker (dev environment).
Nuxt 3 should automatically create routes when I create .vue files in pages directory, and that works when I run my project outside of Docker, but when I use Docker it doesn't recognize my files until I restart the container. Same thing happens when I try to delete files from pages directory, it doesn't recognize any changes until I restart the container. Weird thing is that this happens only in pages directory, in other directories everything works fine. Just to mention that hot reload works, I set up vite in nuxt.config.ts.
docker-compose.yaml
version: '3.8'
services:
nuxt:
build:
context: .
image: nuxt_dev
container_name: nuxt_dev
command: npm run dev
volumes:
- .:/app
- /app/node_modules
ports:
- "3000:3000"
- "24678:24678"
Dockerfile:
FROM node:16.14.2-alpine
WORKDIR /app
RUN apk update && apk upgrade
RUN apk add git
COPY ./package*.json /app/
RUN npm install && npm cache clean --force && npm run build
COPY . .
ENV PATH ./node_modules/.bin/:$PATH
ENV NUXT_HOST=0.0.0.0
ENV NUXT_PORT=3000
EXPOSE 3000
CMD ["npm", "run", "dev"]
I tried some things with Docker volumes, like to add a separate volume just for pages, like this:
./pages:app/pages
/pages:app/pages
app/pages
but as I thought, none of those things helped.
One more thing that is weird to me, when I created a .vue file in pages directory, I checked if it appeared in the container and it did. I'm not an expert in Docker nor in Nuxt, I just started to learn, so any help would be much appreciated.

Dockerfile for angular development not updating node_modules

I'm using the following Dockerfile for development of an Angular project:
FROM node:18-alpine
WORKDIR /code
COPY package*.json /code/
RUN npm ci --quiet
It gets started with docker compose. My code folder is mounted as a volume so the development server inside the container detects changes when editing and keeps live updates going:
version: "3"
services:
ui:
build: ./PathOnHostWithProjectRepo
command: sh -c "npm start"
ports:
- 4200:4200
volumes:
- ./PathOnHostWithProjectRepo:/code
- node_modules:/code/node_modules
volumes:
node_modules:
node_modules gets created when the image is created and, to my understanding, would only update if my package.json is changed. However, today I updated package.json with a new dependency and it is not being installed inside of the volume. I have tried everything I can think of. docker compose down, docker system prune -a -f, and rebuilding. Every time the container starts there is an error that it cannot find the new dependency added. If I step into the container and inspect the node_modules folder the library isn't there. It is present on my host machine if I run npm install locally without Docker, so I know the package and imports must be correct.
With this setup your node_modules will never be updated. Docker will completely ignore any changes in your package.json file. You've told it that directory contains user data that must not be modified.
For the setup you show you don't need Docker at all. It's straightforward to install Node and OS package managers like Debian/Ubuntu APT or MacOS Homebrew generally have a prepackaged version. If you use Node directly then you won't have problems like this; everything will work normally.
If you must use Docker here, the most straightforward thing to do is to make sure all of your application code is in a subdirectory; then you can mount only the subdirectory containing the code and leave the image's node_volumes directory intact.
$ ls -F
Dockerfile
docker-compose.yml
node_modules/
package.json
package-lock.json
src/
# Dockerfile
FROM node:lts
WORKDIR /code
COPY package*.json ./
RUN npm ci
COPY src/ ./src/
# RUN npm build
CMD ["npm", "start"]
# docker-compose.yml
version: '3.8'
services:
ui:
build: .
ports:
- '4200:4200'
volumes:
- ./src:/code/src
Mounting only the src subdirectory avoids the trouble of storing node_modules in a named volume (or an anonymous one). If you change your package.json file you will need to re-run docker-compose build, but since you're directly using the library tree in your image then this will in fact get updated.
If you're going to deploy this image somewhere, remember to delete the volumes: block during your local integration testing so that you're actually running the image you're going to deploy, and not a hybrid of an image and your potentially-modified local code.

Docker and private packages with .npmrc

I am using a .npmrc file to configure a private repo (font-awesome-pro).
It works well without docker.
But with docker, the npm install fails:
npm ERR! code E401
npm ERR! 404 401 Unauthorized: #fortawesome/fontawesome-pro-light#https://npm.fontawesome.com/7D46BEC2-1565-40B5-B5FC-D40C724E60C6/#fortawesome/fontawesome-pro-light/-/fontawesome-pro-light-5.0.12.tgz
I have read the doc from NPM : Docker and private packages, but I don't know how to apply it with docker-compose.yml and I not sure passing variables is the solution (?).
Is it possible that the .npmrc file is not read during installation inside the docker instance ? Am I missing something ?
Here is my docker-compose.yaml :
version: '2.1'
services:
app:
image: node:8.9.4
# restart: always
container_name: jc-vc
environment:
- APP_ENV=${JC_ENV:-dev}
- HOST=0.0.0.0
- BASE_URL=${JC_BASE_URL}
- BROWSER_BASE_URL=${JC_BROWSER_BASE_URL}
working_dir: /usr/src/app
volumes:
- ${DOCKER_PATH}/jc/vc/app:/usr/src/app
command: npm install
# command: npm run dev
# command: npm run lintfix
# command: npm run build
# command: npm start
expose:
- 3000
nginx:
image: nginx
logging:
driver: none
# restart: always
volumes:
- ${DOCKER_PATH}/jc/vc/nginx/www:/usr/share/nginx/html
- ${DOCKER_PATH}/jc/vc/nginx/default.${JC_ENV:-dev}.conf:/etc/nginx/nginx.conf
- ${DOCKER_PATH}/jc/vc/nginx/.htpasswd:/etc/nginx/.htpasswd
- ${DOCKER_PATH}/jc/letsencrypt:/etc/letsencrypt
container_name: jc-nginx-vc
depends_on:
- app
ports:
- ${PORT_80:-4020}:${PORT_80:-4020}
- ${PORT_443:-4021}:${PORT_443:-4021}
and my .npmrc (with replaced token) :
#fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX
The correct way to fix this, as documented in the link you reference, is to use arg variables in the dockerfile. I think the bit you're missing is how to do this in compose:
version: "3"
services:
myapp:
build:
context: "."
args:
NPM_TOKEN: "s3kr!t"
You need to reference this argument in your dockerfile and create a .npmrc file in the root of your project:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
I like to generate this in the dockerfile to minimise the risk of exposure (but, be aware, the token is still stored in the image's layers), so it would look something like this:
FROM node:current-buster-slim
ARG NPM_TOKEN
WORKDIR /app
COPY package.json /app/package.json
RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > /app/.npmrc && \
npm install && \
rm -f /app/.npmrc
COPY . /app/
CMD npm start
You can then run docker-compose build myapp and get a good result. This solution still suffers from having the secret in your compose file and in the docker images, but this is only a sketch for SO. In the real world you'd not want to put your secrets in your source-files so realistically you'd replace the secret with a dynamic secret that has a short Time To Live (TTL) and a single-use policy (and you'd probably want to use Hashicorp Vault to help with that).
In the root directory of your project, create a custom .npmrc file with the following contents:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
Now add these commands to Dockerfile
COPY .npmrc .npmrc
COPY package.json package.json
RUN npm install
RUN rm -f .npmrc
That should fix the issue, hope that helps
package-lock.json needs to be re-generate with the new .npmrc file. Delete it package-lock.json and recreate it with npm install then redeploy the image.

Docker + node_modules: receiving error for local dependency while trying to run Dockerfile

I am working on creating a docker container for a node.js microservice and am running into an issue with a local dependency from another folder.
I added the dependency to the node_modules folder using:
npm install -S ../dependency1(module name).
This also added an entry in the package.json as follows:
"dependency1": "file:../dependency1".
When I run the docker-compose up -d command, I receive an error indicating the folowing:
npm ERR! Could not install from "../dependency1" as it does not contain a package.json file.
Dockerfile:
FROM node:latest
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm install
CMD [ "npm", "start" ]
EXPOSE 3000
docker-compose.yml:
customer:
container_name: "app_customer"
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/usr/src/app/
- /usr/src/app/node_modules
ports:
- "3000:3000"
depends_on:
- mongo
- rabbitmq
I found articles outlining an issue with symlinks in a node_modules folder and docker and a few outlining this issue but none seem to provide a solution to this problem. I am looking for a solution to this problem or a really good workaround.
A Docker build can't reference files outside of the build context, which is the . defined in the docker-compose.yml file.
docker build creates a tar bundle of all the files in a build context and sends that to the Docker daemon for the build. Anything outside the context directory doesn't exist to the build.
You could move your build context with context: ../ to the parent directory and shuffle all the paths you reference in the Dockerfile to match. Just be careful not to make the build context to large as it can slow down the build process.
The other option is to publish the private npm modules to a scope, possible on a private npm registry that you and the build server have access to and install the dependencies normally.

Lift Sails inside Docker container

I know there are multiple examples (actually only a few) out there, and I've looked into some and tried to apply them to my case but then when I try to lift the container (docker-compose up) I end up with more or less the same error every time.
My folder structure is:
sails-project
--app
----api
----config
----node_modules
----.sailsrc
----app.js
----package.json
--docker-compose.yml
--Dockerfile
The docker-compose.yml file:
sails:
build: .
ports:
- "8001:80"
links:
- postgres
volumes:
- ./app:/app
environment:
- NODE_ENV=development
command: node app
postgres:
image: postgres:latest
ports:
- "8002:5432"
And the Dockerfile:
FROM node:0.12.3
RUN mkdir /app
WORKDIR /app
# the dependencies are already installed in the local copy of the project, so
# they will be copied to the container
ADD app /app
CMD ["/app/app.js", "--no-daemon"]
RUN cd /app; npm i
I tried also having RUN npm i -g sails instead (in the Dockerfile) and command:sails lift, but I'm getting:
Naturally, I tried different configurations of the Dockerfile and then with different commands (node app, sails lift, npm start, etc...), but constantly ending up with the same error. Any ideas?
By using command: node app you are overriding the command CMD ["/app/app.js", "--no-daemon"] which as a consequence will have no effect. WORKDIR /app will create an app folder so you don't have to RUN mkdir /app. And most important you have to RUN cd /app; npm i before CMD ["/app/app.js", "--no-daemon"]. NPM dependencies have to be installed before you start your app.

Resources