Step1: I have created a local docker image of one NodeJS app.
Here is the dockerfile for this app -
FROM node:8
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
#EXPOSE 8080
CMD [ "npm", "start" ]
**Step 2:**Then I built a docker image for this Node app. Here is the build command output -
C:\Users\shibathethinker\Documents\GitHub\NodeProjects\API_Proxy_ABN>docker build -t api-proxy .
Sending build context to Docker daemon 8.637MB
Step 1/6 : FROM node:8
---> 0bf36d7ccc1e
Step 2/6 : WORKDIR /usr/src/app
---> Running in 7187d65639f1
Removing intermediate container 7187d65639f1
---> 0e34dc93439c
Step 3/6 : COPY package*.json ./
---> 47c0d0ca8c77
Step 4/6 : RUN npm install
---> Running in d7e5163371df
npm WARN api_proxy#1.0.0 No repository field.
added 98 packages from 91 contributors and audited 194 packages in 8.598s
found 0 vulnerabilities
Removing intermediate container d7e5163371df
---> 72da705ae792
Step 5/6 : COPY . .
---> 0293df6aa27d
Step 6/6 : CMD [ "npm", "start" ]
---> Running in 251e98c0a0ae
Removing intermediate container 251e98c0a0ae
---> a92d8a95b8cd
Successfully built a92d8a95b8cd
Successfully tagged api-proxy:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.
**Step 3:**Then, I wanted to use this docker image in another 'React' app.
Here is the Dockerfile of the app -
FROM api-proxy:latest
WORKDIR /app
RUN npm install
CMD [ "npm", "start" ]
# stage: 2 — the production environment
FROM nginx:alpine
#COPY —from=react-build /app/build /usr/share/nginx/html
#COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY /build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Step4: Now I built and ran this docker image generated on step 3.
Question:
It looks like the node app is not running on the newly created docker container.
If I 'ssh' into the docker container I can not see any node server running there.
I also could not find the WORKDIR (/usr/src/app) created in the step1 in this container.
What I am doing wrong?
Please let me know if I can clarify further.
You are doing a multi-stage docker build.You are building your application using nodejs (download dependencies and minification build) and copying and running it on nginx web server.
Nodejs server can be in its own independent container, which i think you have already done. The client would actually be a webserver for e.g. nginx, apache etc. that would serve the build of your react app. In the end, you will have 2 containers running: 1 for nodejs server and 1 for nginx webserver.
To place the build of your react app into this nginx webserver, you will use multi-stage build. In the first stage you will build your react app and in the second stage you will use nginx image and copy the react build from the first stage into the html folder of the nginx image.
Related
i do not understand why docker cannot get my angular build folder in container.
Can you see that to help me?
If i build with docker compose command i have this error.
Below are all the steps to build my image and launch my container until the error.
WARNING: The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Building linking-front
Sending build context to Docker daemon 425.6MB
Step 1/9 : FROM node:16.19.0 AS build
---> b22f8aab05da
Step 2/9 : WORKDIR /usr/src/app
---> Using cache
---> 5e2431455b65
Step 3/9 : COPY package.json package-lock.json ./
---> Using cache
---> 11d677269b0e
Step 4/9 : RUN npm install
---> Using cache
---> b5544be9159b
Step 5/9 : COPY . .
---> Using cache
---> 3403bfda57ca
Step 6/9 : RUN npm run build
---> Using cache
---> ae8e7960ac33
Step 7/9 : FROM nginx:1.23.3-alpine
---> 2bc7edbc3cf2
Step 8/9 : COPY nginx.conf /etc/nginx/nginx.conf
---> Using cache
---> beca38c7be94
Step 9/9 : COPY --from=build /usr/src/app/dist/linkingEducationSecurity-front /usr/share/nginx/html
COPY failed: stat usr/src/app/dist/linkingEducationSecurity-front: file does not exist
ERROR: Service 'linking-front' failed to build : Build failed
### STAGE 1: Build ###
FROM node:16.19.0 AS build
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
### STAGE 2: Run ###
FROM nginx:1.23.3-alpine
COPY nginx.conf /etc/nginx/nginx.conf
COPY --from=build /usr/src/app/dist/linkingEducationSecurity-front /usr/share/nginx/html
I use also docker-compose
version: '3.9'
services:
linking-front:
build: ./linkingEducationSecurity-front/
ports:
- "8080:80"
volumes:
- type: bind
source: ./linkingEducationSecurity-front/src/
target: /app/src
since in the comments you tried to do RUN cd dist && ls which gave you this output :
Step 7/10 : RUN cd dist && ls ---> Running in e8f002e82f3a linking-education-security-front
The steps and dockerfile are perfect. the COPY command from build folder is missing its spell
update this line :
COPY --from=build /usr/src/app/dist/linkingEducationSecurity-front /usr/share/nginx/html
to this :
COPY --from=build /usr/src/app/dist/linking-education-security-front /usr/share/nginx/html
and try rebuilding , this might work.
The Dockerfile uses the COPY --from command from the other build Node layer, but the generated directory is not found.
Note 1: This Dockerfile works locally on my machine doing builds normally.
Note 2: In the execution log it mentions the removal of an intermediate container, is that it? Would it be possible to preserve this container so that the copy works?
FROM node:16.16 as build
# USER node
WORKDIR /app
COPY package.json /app
RUN npm install --location=global npm#latest && npm install --silent
COPY . .
ARG SCRIPT
ENV SCRIPT=$SCRIPT
ARG API_URL
ENV API_URL=$API_URL
ARG API_SERVER
ENV API_SERVER=$API_SERVER
CMD ["/bin/sh", "-c", "envsubst < src/proxy.conf.template.js > src/proxy.conf.js"]
RUN npm run ${SCRIPT}
FROM nginx:1.23
VOLUME /var/cache/nginx
EXPOSE 80
COPY --from=build /app/dist/siai-spa /usr/share/nginx/html
COPY ./config/nginx-template.conf /etc/nginx/nginx-template.conf
b9ed43dcc388: Pull complete
Digest: sha256:db345982a2f2a4257c6f699a499feb1d79451a1305e8022f16456ddc3ad6b94c
Status: Downloaded newer image for nginx:1.23
---> 41b0e86104ba
Step 15/24 : VOLUME /var/cache/nginx
---> Running in dc0e24ae6e51
Removing intermediate container dc0e24ae6e51
---> 3b2799dad197
Step 16/24 : EXPOSE 80
---> Running in f30edd617285
Removing intermediate container f30edd617285
---> 21985745ce49
Step 17/24 : COPY --from=build /app/dist/siai-spa /usr/share/nginx/html
COPY failed: stat app/dist/siai-spa: file does not exist
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 1
I guess, you should use CMD instead of RUN while npm run ${SCRIPT} as this needs to be executed during container running time rather than image build time.
Solved problem!
The difference was that locally I used docker-compose which captures the build arguments from the .env file. The npm run command did not override the ${SCRIPT} variable as the docker command does not use the env file, required to pass through the --build-arg parameters.
I have made the following dockerfile to contain my node js application, the problem is that an error appears when building the dockerfile:
Sending build context to Docker daemon 2.048kB
Step 1/7 : FROM node:10
---> 0d5ae56139bd
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> 5bfc0405d8fa
Step 3/7 : COPY package.json ./
COPY failed: stat /var/lib/docker/tmp/docker-
builder803334317/package.json: no such file or directory
this is my dockerfile:
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
i executed the command:
sudo docker build - < Dockerfile
into my root project folder.
My project folder is simple, like this:
-Project
-app.js
-Dockerfile
-package.json
-package-lock.json
-README.md
I am doing something wrong?
When you use the Dockerfile-on-stdin syntax
sudo docker build - < Dockerfile
the build sequence runs in a context that only has the Dockerfile, and no other files on disk.
The directory layout you show is pretty typical, and pointing docker build at that directory should work better
sudo docker build .
(This is the same rule as the "Dockerfiles can't access files in parent directories" rule, but instead of giving the current directory as the base directory to Docker, you're giving no directory at all, so it can't even access files in the current directory.)
For unknown reason build failed on Docker Hub when it trying to copy from a just built target into the same Dockerfile. When, I try on local machine (Fedora 27, Docker CE 17.12), the build succeed.
Here the failed build log : https://hub.docker.com/r/emmanuelgautier/react-app/builds/bsygsbahuzdxfbsqr5r9er4/
Folder /usr/src/app/build doesn't exist in the second image because according to documentation:
CMD does not execute anything at build time, but specifies the
intended command for the image.
RUN should be used instead of CMD where yarn build command executes.
The correct Dockerfile is:
## Development environment target
FROM node as dev-env
WORKDIR /usr/src/app
COPY [ "package*.json", "yarn.lock", "./" ]
RUN yarn install
COPY . .
EXPOSE 3000
ENTRYPOINT [ "./docker-entrypoint.sh" ]
## Build environment target
FROM node as build-env
WORKDIR /usr/src/app
COPY [ "package*.json", "yarn.lock", "./" ]
RUN yarn install --production
COPY . .
RUN yarn build
## Production environement target
FROM nginx as production-env
LABEL MAINTAINER Emmanuel Gautier <docker#emmanuelgautier.fr>
COPY --from=1 /usr/src/app/build /usr/share/nginx/html
EXPOSE 443 80
I'm playing around with Google's Dart docker image. I'm trying to build a Hello World app that listens on port 80. I'm running it on Ubuntu Server 14 on Azure.
If I run the google/dart-hello, it all works fine, and I can connect on port 8080.
The google/dart-hello image is based on the google/dart-runtime image, which is in turn, based on google/dart. The base image adds Dart; google/dart-runtime adds a Dockerfile which expects to execute bin/server.dart and expose port 8080, and google/dart-hello supplies the bin/server.dart (and pubspec.yaml) to make it work. google/dart-runtime isn't useful on its own, because it doesn't contain a bin/server.dart or pubspec.yaml.
So, google/dart-runtime is a good base if your server is at bin/server.dart and you want to listen on port 8080. As I want to listen on port 80, I'm using the google/dart image as a base, hoping to squash what's in google/dart-runtime and google/dart-hello into my container, but changed to port 80.
You can find the sources repos for the three Google images here:
google/dart
google/dart-runtime (Dockerfile)
google/dart-hello (Dockerfile)
So, I've taken the Dockerfile from google/dart-runtime and the files from google/dart-hello, so I have the following:
FROM google/dart
WORKDIR /app
ONBUILD ADD pubspec.yaml /app/
ONBUILD ADD pubspec.lock /app/
ONBUILD RUN pub get
ONBUILD ADD . /app
ONBUILD RUN pub get
CMD []
ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
EXPOSE 80
In the same directory as this Dockerfile, I have the following files:
bin/server.dart
pubspec.yaml
pubspec.lock
I'm building the image with:
sudo docker build --no-cache -t dart-test .
And here's the output:
danny#linux:~/dart_test$ sudo docker build --no-cache -t dart-test .
Sending build context to Docker daemon 5.632 kB
Sending build context to Docker daemon
Step 0 : FROM google/dart
---> cd92c7fff717
Step 1 : WORKDIR /app
---> Running in d163d2597eba
---> 2802d6769b76
Removing intermediate container d163d2597eba
Step 2 : ONBUILD ADD pubspec.yaml /app/
---> Running in 7b8be2a481c2
---> 096cbe12a2cd
Removing intermediate container 7b8be2a481c2
Step 3 : ONBUILD ADD pubspec.lock /app/
---> Running in 6ae0243b0dee
---> 80f20ebafa87
Removing intermediate container 6ae0243b0dee
Step 4 : ONBUILD RUN pub get
---> Running in 621d4ce5c7f1
---> 89a509d41b11
Removing intermediate container 621d4ce5c7f1
Step 5 : ONBUILD ADD . /app
---> Running in 4de26a33487f
---> b69c65f12441
Removing intermediate container 4de26a33487f
Step 6 : ONBUILD RUN pub get
---> Running in f7cc689f6f81
---> 2ccc79ea6d04
Removing intermediate container f7cc689f6f81
Step 7 : CMD []
---> Running in 10bd31eb6679
---> f828267f00b5
Removing intermediate container 10bd31eb6679
Step 8 : ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
---> Running in 013d3ca0f25d
---> a63b59f9fd05
Removing intermediate container 013d3ca0f25d
Step 9 : EXPOSE 80
---> Running in 4301c572e598
---> 75a4317c135c
Removing intermediate container 4301c572e598
Successfully built 75a4317c135c
However, if I try to run this (using sudo docker run --rm -i -t dart-test), I get the following error:
danny#linux:~/dart_test$ sudo docker run -i -t --rm dart-test
Unhandled exception:
Uncaught Error: FileSystemException: Cannot open file, path = '/app/bin/server.dart' (OS Error: No such file or directory, errno = 2)
If I replace the dart execution in the Dockerfile with /bin/bash instead, then when I build and run, I get put into bash at /app/ but the folder is empty.
I've tried this with both the 0.9(?) version and 1.2 (one that came from apt-get docker.io and the other from the more-involved instructions on the Docker website), since I noticed a mention of an ADD fix in the release notes. Both do the same.
I can find lots of info online that people often pipe Dockerfile into STDIN which means there's no context, but you can see in my output that 5KB of data is being sent; though it's possible this is just the Dockerfile and nothing else I guess? They are in the same directory, here's a listing:
danny#linux:~/dart_test$ dir
bin Dockerfile pubspec.lock pubspec.yaml
The ONBUILD instruction is only useful when you create a base image that will be used later by another Dockerfile (see the documentation).
Here because you write the final Dockerfile, you just need to remove the ONBUILD instructions (but keep the raw instructions ADD, RUN, etc).
In your Dockerfile you need to remove the ONBUILD prefixes from your instructions. The ONBUILD prefix is a way to defer execution of certain instructions until this image is referenced by another Dockerfile. Those instructions are stored as part of the metadata for the image that you created but the instructions themselves are not executed until that image is referenced in the FROM field of another Dockerfile.
What you really want is this:
FROM google/dart
WORKDIR /app
ADD pubspec.yaml /app/
ADD pubspec.lock /app/
RUN pub get
ADD . /app
RUN pub get
CMD []
ENTRYPOINT ["/usr/bin/dart", "/app/bin/server.dart"]
EXPOSE 80
The docker image google/dart-runtime is intended to be a base image for your Dart server application. So in your project the Dockerfile should have just the following content
FROM google/dart-runtime
The when you run docker build the ONBUILD commands in the base image will be executed.
If you look at the Dockerfile for google/dart-hello you will see that it has just that one line.