I have the following Dockerfile.PROD, that builds my Nodejs application to then be copied over the Nginx.
I am trying to pass credentials using build arguments to Docker to then use inside a sed command to create a .env file for Nodejs use.
My Dockerfile.PROD
# build environment
FROM node:12.5.0-alpine as build
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
COPY DEFAULT.env ./.env
RUN sed -i "s/access-key/$REACT_APP_ACCESS_KEY_ID/" ./.env
RUN sed -i "s/secret-key/$REACT_APP_SECRET_ACCESS_KEY/" ./.env
RUN npm ci --silent
RUN npm install react-scripts#3.4.1 -g --silent
COPY . ./
RUN npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=build /app/build /usr/share/nginx/html
# new
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
My DEFAULT.env file
REACT_APP_ACCESS_KEY_ID="access-key"
REACT_APP_SECRET_ACCESS_KEY="secret-key"
My Build command used
docker build -f Dockerfile.prod --build-arg REACT_APP_ACCESS_KEY_ID=ABCDEFGHZXCV --build-arg REACT_APP_SECRET_ACCESS_KEY=ABCDEFGHZXCVhdhjshdjsdf9889 -t test:prod .
The build command keeps warning:
One or more build-args [REACT_APP_ACCESS_KEY_ID
REACT_APP_SECRET_ACCESS_KEY] were not consumed.
For some reason the sed command is not picking them up, so must be sed syntax. I am open to other possibilities of creating the .env file.
You need to define arguments inside your Dockerfile before it's usage, using ARG:
https://docs.docker.com/engine/reference/builder/#arg
Related
how to compile golang project with docker container? I want to compile and retrieve the project build, using docker cli
sample docker command
docker run -v $(pwd)/:/app -w /app -v $SSH_AUTH_SOCK:/tmp/ssh_auth.sock -e SSH_AUTH_SOCK=/tmp/ssh_auth.sock --name golanguser golang:1.17 sh -c "export GOPRIVATE=https://user:pass#bitbucket.org/repo/ && go build -o main bitbucket.org/repo/source"
Building a go project is usually done in a multi-stage build
# syntax=docker/dockerfile:1
##
## Build
##
FROM golang:1.16-buster AS build
WORKDIR /app
COPY go.mod ./
COPY go.sum ./
RUN go mod download
COPY *.go ./
RUN go build -o /docker-gs-ping
##
## Deploy
##
FROM gcr.io/distroless/base-debian10
WORKDIR /
COPY --from=build /docker-gs-ping /docker-gs-ping
EXPOSE 8080
USER nonroot:nonroot
ENTRYPOINT ["/docker-gs-ping"]
With:
docker build -t docker-gs-ping:multistage -f Dockerfile.multistage .
That way, you can deploy the built application in the image of your choice, resulting in a markedly smaller image size to run.
I need to execute a shell script from within Docker. I am not as proficient in Docker or in scripting as I would like to be. The script has no effect and does not print anything to the screen. I do not believe that it is being called.
What am I doing wrong here?
The script should be run as the entrypoint command.
The Script
#!/usr/bin/env bash
set -Ex
function apply_path {
echo "Check that we have ENVIRONMENT_VAR vars"
test -n "$ENVIRONMENT_VAR"
find /usr/src/app/.next \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i "s#NEXT_PUBLIC_ENVIRONMENT_VAR#$ENVIRONMENT_VAR#g"
}
apply_path
echo "Starting Nextjs"
exec "$#"
The docker file
ARG NODE_VERSION=14.4.0-alpine
###
# STAGE 1: Base
###
FROM node:$NODE_VERSION as base
ENV NODE_PATH=/src
WORKDIR $NODE_PATH
###
# STAGE 2: Build
###
FROM base as build
COPY package.json package-lock.json .npmrc ./
RUN npm i
COPY . ./
RUN NEXT_PUBLIC_ENVIRONMENT_VAR=BUILD npm run build
# Permisions to execute script
RUN ["chmod", "+x", "./entrypoint.sh"]
ENTRYPOINT ["./entrypoint.sh"]
###
# STAGE 3: Production
###
FROM node:$NODE_VERSION
ENV NODE_PATH=/src
ENV APP_PORT=3000
WORKDIR $NODE_PATH
COPY --from=build $NODE_PATH/.next ./.next
COPY --from=build $NODE_PATH/node_modules ./node_modules
COPY --from=build $NODE_PATH/src ./src
COPY --from=build $NODE_PATH/package.json ./
COPY --from=build $NODE_PATH/.babelrc ./
COPY --from=build $NODE_PATH/LICENSE ./
EXPOSE $APP_PORT
CMD npm start
When you have a multi-stage Docker build, the end result of that is only the results starting from the final FROM line. While you're setting that script as an ENTRYPOINT, it's in a previous build stage that's not getting used. ENTRYPOINT (and CMD) don't run at image build time, only when the built image is eventually run.
The easiest way to address this is to COPY the script directly into the final build stage:
# STAGE 3: Production
FROM node:$NODE_VERSION
...
COPY entrypoint.sh .
ENTRYPOINT ["./entrypoint.sh"]
CMD npm start
I hava a custom Dockerfile that setup and builds a project of mine.
But now I haven't beeing able to place that into a folder of the host. Here the script and docker file...
Command
sudo docker build --output type=local,dest=./build/server/server -f ./build/scripts/Dockerfile.server ./server
Dockerfile
FROM node:14 AS build-stage
WORKDIR /usr/src/project
RUN npm i nexe#3.3.7 -g
COPY package*.json ./
RUN npm install --only=production
COPY . .
RUN nexe server.js -t linux-x64-12.14.1
FROM scratch AS export-stage
COPY --from=build-stage /usr/src/project/server /
The docker buildkit needs to be enabled before running the build command:
export DOCKER_BUILDKIT=1
You are setting up the context wrong. The command should be:
sudo docker build --output type=local,dest=./build/server/server -f ./build/scripts/Dockerfile.server .
The dot at the end sets the build context to current directory structure.
I'm passing a build argument into: docker build --build-arg RUNTIME=test
In my Dockerfile I want to use the argument's value in the CMD:
CMD ["npm", "run", "start:${RUNTIME}"]
Doing so results in this error: npm ERR! missing script: start:${RUNTIME} - it's not expanding the variable
I read through this post: Use environment variables in CMD
So I tried doing: CMD ["sh", "-c", "npm run start:${RUNTIME}"] - I end up with this error: /bin/sh: [sh,: not found
Both errors occur when I run the built container.
I'm using the node alpine image as a base. Anyone have ideas how to get the argument value to expand within CMD? Thanks in advance!
full Dockerfile:
FROM node:10.15.0-alpine as builder
ARG RUNTIME_ENV=test
RUN mkdir -p /usr/app
WORKDIR /usr/app
COPY . .
RUN npm ci
RUN npm run build
FROM node:10.15.0-alpine
COPY --from=builder /usr/app/.npmrc /usr/app/package*.json /usr/app/server.js ./
COPY --from=builder /usr/app/config ./config
COPY --from=builder /usr/app/build ./build
RUN npm ci --only=production
EXPOSE 3000
CMD ["npm", "run", "start:${RUNTIME_ENV}"]
Update:
Just for clarity there were two problems I was running into.
1. The problem as described by Samuel P.
2. ENV values are not carried between containers (multi-stage)
Here's the working Dockerfile where I'm able to expand environment variables in CMD:
# Here we set the build-arg as an environment variable.
# Setting this in the base image allows each build stage to access it
FROM node:10.15.0-alpine as base
ARG ENV
ENV RUNTIME_ENV=${ENV}
FROM base as builder
RUN mkdir -p /usr/app
WORKDIR /usr/app
COPY . .
RUN npm ci && npm run build
FROM base
COPY --from=builder /usr/app/.npmrc /usr/app/package*.json /usr/app/server.js ./
COPY --from=builder /usr/app/config ./config
COPY --from=builder /usr/app/build ./build
RUN npm ci --only=production
EXPOSE 3000
CMD npm run start:${RUNTIME_ENV}
The problem here is that ARG params are available only during image build.
The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag.
https://docs.docker.com/engine/reference/builder/#arg
CMD is executed at container startup where ARG variables aren't available anymore.
ENV variables are available during build and also in the container:
The environment variables set using ENV will persist when a container is run from the resulting image.
https://docs.docker.com/engine/reference/builder/#env
To solve your problem you should transfer the ARG variable to an ENV variable.
add the following line before your CMD:
ENV RUNTIME_ENV ${RUNTIME_ENV}
If you want to provide a default value you can use the following:
ENV RUNTIME_ENV ${RUNTIME_ENV:default_value}
Here are some more details about the usage of ARG and ENV from the docker docs.
We have an angular app we are trying to run in docker nginx.
I have to run a script on startup that uses an environment variableto replace the app url for each stage. This is needed to connect to the backend.
We do not wish to build the container for each stage. The container will run in Azure docker.
For now i am running it locally. It executes my script and then the app shuts down.
The Docker File:
FROM node:8.11.2-alpine as node
LABEL author="My Online Presence"
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:1.13.12-alpine
COPY /certificates /etc/nginx/
COPY --from=node /usr/src/app/dist /usr/share/nginx/html
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
ADD run.sh /usr/share/nginx/html/run.sh
RUN apk add --update bash && rm -rf /var/cache/apk/*
RUN chmod +x /usr/share/nginx/html/run.sh
ENTRYPOINT ["/usr/share/nginx/html/run.sh"]
CMD ["nginx", "-g", "daemon off;"]
The run.sh file
#!/bin/sh
FILE_NAME=$(find . -name "main*.js")
sed -i "s/localhost\:4200/${DIGITISE_URL}/g" $FILE_NAME
echo 'File updated with correct url'
i use
docker build -t digitise .
and then
docker run -p 80:80 -p 443:443 -e DIGITISE_URL=digitise.co.za digitise
I got it working simply by adding
exec "$#"
to the end of my script being run
You can also start nginx service in your script.