What did I write incorrectly in the node.js service configurations in docker-compose.yml?

I raise a Drupal site on docker, namely - docker4drupal (a set of already created images: php, nginx, mariadb, etc.)

I need to create a subtheme based on Bootstrap 4 - Barrio SASS.
In the instructions on drupal.org writes that for this theme I need to install node.js, gulp, and all the required dependencies for gulp so that it can compile sass to css:
Installation | Bootstrap 4 SASS - Barrio Starter Kit | Drupal Wiki guide on Drupal.org

In docker-compose.yml, I wrote configurations like this for the node.js service:

node:
    image: wodby/node:$NODE_TAG
    container_name: "${PROJECT_NAME}_node"
    working_dir: /var/www/html/web/themes/custom/bootstrap_sass_bcnews
    labels:
    - "traefik.http.services.${PROJECT_NAME}_node.loadbalancer.server.port=3000"
    - "traefik.http.routers.${PROJECT_NAME}_node.rule=Host(`node.${PROJECT_BASE_URL}`)"
    expose:
    - "3000"
    volumes:
    - ./var/www/html/web/themes/custom/bootstrap_sass_bcnews:/var/www/html
    command: sh -c 'apt-get install python3-software-properties gnupg2 curl wget -y && curl -fsSL https://deb.nodesource.com/setup_12.x | sudo -E bash - && sudo apt-get install -y nodejs && cd /var/www/html/web/themes/custom/bootstrap_sass_bcnews && npm install --global gulp-cli && npm install'

The path to the Drupal project on my system: /home/perceval/Desktop/bcnews_project

The path to the theme in the container: /var/www/html/web/themes/custom/bootstrap_sass_bcnews

After running containers docker-compose up -d and checks docker ps, I see that the node.js container is not running:


In file docker-compose.yml I only edited three lines working_dir, volumes, command. And I suspect I wrote something wrong in the last two.

File .env:

### --- NODE ---

NODE_TAG=12-dev-0.84.0

What is the problem? And in general, did I write the commands correctly in the command line?

P.S. For ease of reading, I will write you the commands from the line written in the command: from the file docker-compose.yml here:

 sh -c 'apt-get install python3-software-properties gnupg2 curl wget -y &&
 curl -fsSL https://deb.nodesource.com/setup_12.x | sudo -E bash - &&
 sudo apt-get install -y nodejs &&
 cd /var/www/html/web/themes/custom/bootstrap_sass_bcnews && 
 npm install --global gulp-cli &&
 npm install'

Good evening!

Some points come into my mind that are strange here:

  • Install something should be in your Dockerfile used for creating your own image based on (in this case) wodby/node:12-dev-0.84.0 instead being used in your docker-compose.yml. Afterwards you can use your newly created image in your docker-compose.yml.

  • I have checked with docker run --rm -it wodby/node:12-dev-0.84.0 bash - this image uses apk instead of apt-get to install additional packages. If I remember correctly the syntax is (sudo) apk add <packagename>. Keep in mind that the package-names might be different to the ones you are used to use with apt-get.

  • Why do you try to install node into an image already containing node

Hope this helps to get some steps forward?

2 Likes

I was thinking about what you wrote:

Why do you try to install node into an image already containing node

In fact, if I have a node image, then why should I install a node. I do not install PHP when I have a PHP image.

Therefore, in the themes I wrote only the following commands:
command: sh -c 'cd /var/www/html/web/themes/custom/bootstrap_sass_bcnews && npm install --global gulp-cli && npm install && gulp'

But then I get errors:

perceval@Asus:~/Desktop/bcnews_project$ docker-compose logs node

Attaching to bcnews_node
bcnews_node | npm WARN deprecated urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
bcnews_node | npm WARN deprecated resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
bcnews_node | /home/node/.npm-global/bin/gulp -> /home/node/.npm-global/lib/node_modules/gulp-cli/bin/gulp.js
bcnews_node | + gulp-cli@2.3.0
bcnews_node | added 252 packages from 165 contributors in 23.752s
bcnews_node | npm WARN saveError ENOENT: no such file or directory, open '/var/www/html/web/themes/custom/bootstrap_sass_bcnews/package.json'
bcnews_node | npm WARN saveError EACCES: permission denied, open '/var/www/html/web/themes/custom/bootstrap_sass_bcnews/package-lock.json.3294245740'
bcnews_node | npm WARN enoent ENOENT: no such file or directory, open '/var/www/html/web/themes/custom/bootstrap_sass_bcnews/package.json'
bcnews_node | npm WARN bootstrap_sass_bcnews No description
bcnews_node | npm WARN bootstrap_sass_bcnews No repository field.
bcnews_node | npm WARN bootstrap_sass_bcnews No README data
bcnews_node | npm WARN bootstrap_sass_bcnews No license field.
bcnews_node | 
bcnews_node | up to date in 0.5s
bcnews_node | found 0 vulnerabilities
bcnews_node | 
bcnews_node | [18:19:30] Local gulp not found in /var/www/html/web/themes/custom/bootstrap_sass_bcnews
bcnews_node | [18:19:30] Try running: npm install gulp

You shouldn’t be using Compose to install things in your containers each time you start them. You should use Compose to orchestrate how containers work together, based on (custom) images. For that, Compose’s command is only meant to be used to replace/override the CMD from a Dockerfile (if even supported by the image’s ENTRYPOINT, if any). But not, say, to replace the Dockerfile RUN command(s).

So, you can use Compose’s command to change the way you start the container, not to install something every time the container is started. In other words, like already noted:

As for:

Your Compose command finishes after installing, so the container indeed stops, as expected.

Node.js by itself is just an interpreter for a programming language; it does not “run” anything unless being told so. The things you specified in command do not start anything after the installation is complete. Common usage would be to start a web server using some server-side JavaScript code. That is then typically configured in Dockerfile using CMD, or overridden in docker-compose.yml using command.

As wodby/node provides no documentation I have no idea what that does. (It could be mining crypto currency for all we know.) But for the official node image, one could use command: "node my-server.js" or command: "npm start" in Compose, or use CMD ["node", "my-server.js"] or CMD ["npm", "start"] in a Dockerfile. That all depends on the application you’re trying to run though. Nice read: Building Efficient Dockerfiles - Node.js.

(Aside, please don’t post the same thing in multiple places. Success!)

Solution:

  1. Node.js image uses apk instead of apt-get to install additional packages.
  2. This image already containing node.js. I don’t need to write a node.js installation command in command: line.
    Here’s how the node service configuration should look like:
  node:
    image: wodby/node:$NODE_TAG
    container_name: "${PROJECT_NAME}_node"
    working_dir: /var/www/html/web/themes/custom/bcnews_bootstrap_sass
    labels:
    - "traefik.http.services.${PROJECT_NAME}_node.loadbalancer.server.port=3000"
    - "traefik.http.routers.${PROJECT_NAME}_node.rule=Host(`node.${PROJECT_BASE_URL}`)"
    expose:
    - "3000"
    volumes:
    - ./:/var/www/html:cached
    command: sh -c 'cd /var/www/html/web/themes/custom/bcnews_bootstrap_sass && npm init --yes && npm install --global gulp-cli && npm install --save-dev gulp && npm install && gulp'