Docker commit image starts node repl instead of serving a website

Issue

Goal is to NOT use a Dockerfile but to create a container, modify a container, then commit an image based off the container. It is for a course I am giving feedback on and I can NOT use a Dockerfile.

I have a folder, node-test-application with the following on an Ubuntu machine:
package.json server.js

package.json

{
  "name": "docker_web_app",
  "version": "1.0.0",
  "description": "Node.js on Docker",
  "author": "First Last <first.last@example.com>",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.16.1"
  }
}

server.js

const express = require('express');
    
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
    
// App
const app = express();
app.get('/', (req, res) => {
  res.send('Hello World');
});
    
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);

So this is the order of operations I’m following from within node-test-application:
Run intermediate node container

docker run -d -t --name nodeint -p 3009:8080 node:16

copy files from

docker container cp . nodeint:/app

then I enter the container:

docker exec -it nodeint sh

Now inside the container, I cd into app directory:

cd app

My files are present:
package.json server.js

I run npm install:

npm install
added 57 packages, and audited 58 packages in 3s

7 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
npm notice 
npm notice New minor version of npm available! 8.11.0 -> 8.12.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.12.1
npm notice Run npm install -g npm@8.12.1 to update!
npm notice

I run npm start:

npm start
> docker_web_app@1.0.0 start
> node server.js

Running on http://0.0.0.0:8080

I go to IPADDRESS:3009
And it’s serving "Hello World" to the browser.

So now I ctrl+c then ctrl+d and I’m out of the container.

docker ps shows that the container is still running.

So I:

docker commit nodeint nodeapp:v1

and it returns the image ID

Now I expect to be able to run a container with the nodeapp:v1 image and have it serve me Hello World on the IPADDRESS:3010 port after I run the following command:

docker run -it --name nodeappcont -p 3010:8080 nodeapp:v1

but it gives me a node REPL:

Welcome to Node.js v16.15.1.
Type ".help" for more information.
> 

And when I navigate to IPADDRESS:3010 I get nothing. Just site can’t be reached.

When I run image history:

docker image history nodeapp:v1
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
ebf532979d69   3 minutes ago   node                                            5.83MB    
b59df4e04d61   2 days ago      /bin/sh -c #(nop)  CMD ["node"]                 0B        
<missing>      2 days ago      /bin/sh -c #(nop)  ENTRYPOINT ["docker-entry…   0B        
<missing>      2 days ago      /bin/sh -c #(nop) COPY file:4d192565a7220e13…   388B      
<missing>      2 days ago      /bin/sh -c set -ex   && for key in     6A010…   7.6MB     
<missing>      2 days ago      /bin/sh -c #(nop)  ENV YARN_VERSION=1.22.19     0B        
<missing>      2 days ago      /bin/sh -c ARCH= && dpkgArch="$(dpkg --print…   95.3MB    
<missing>      2 days ago      /bin/sh -c #(nop)  ENV NODE_VERSION=16.15.1     0B        
<missing>      12 days ago     /bin/sh -c groupadd --gid 1000 node   && use…   334kB     
<missing>      12 days ago     /bin/sh -c set -ex;  apt-get update;  apt-ge…   510MB     
<missing>      12 days ago     /bin/sh -c apt-get update && apt-get install…   146MB     
<missing>      12 days ago     /bin/sh -c set -ex;  if ! command -v gpg > /…   17.5MB    
<missing>      12 days ago     /bin/sh -c set -eux;  apt-get update;  apt-g…   16.5MB    
<missing>      12 days ago     /bin/sh -c #(nop)  CMD ["bash"]                 0B        
<missing>      12 days ago     /bin/sh -c #(nop) ADD file:5c5cde050dbdbd5c7…   114MB

So how do I create an node image from a container with changes that will serve a node app? Remember, without using a Dockerfile.

Solution

docker commit only saves the file system of the container. It doesn’t save any running processes.

You can change the working directory and the start command, by using the --change/-c option on docker commit to apply Dockerfile statements from the command line. In your case, you could do

docker commit -c 'WORKDIR /app' -c 'CMD npm start' nodeint nodeapp:v1

Then you can run it with

docker run -it --name nodeappcont -p 3010:8080 nodeapp:v1

and npm start will run in the /app directory.

Answered By – Hans Kilian

Answer Checked By – Marie Seifert (AngularFixing Admin)

Leave a Reply

Your email address will not be published.