Environment variables for build not visible in Dockerfile - npm

I've set an environment variable (NPM_TOKEN) for my repo in Docker Cloud to use when building my Dockerfile. However, the variable is always empty...
Tried both of these in Dockerfile:
RUN echo ${NPM_TOKEN}
and:
ARG NPM_TOKEN
RUN echo ${NPM_TOKEN}
Am I wrong in assuming that Docker Clouds environment variables for build does the same thing as --build-arg?

It took me along time, but you can use build hooks to set variables for automated builds!
https://docs.docker.com/docker-cloud/builds/advanced/#build-hook-examples

Related

Variable substitution is not happening inside Containerfile

Building a docker container
Using alpine as build image
The Containerfile receives VERSION as argument
It is set as image version
The same version is passed to dotnet publish command.
The passed version (which is a variable) in current context never gets substituted. Instead of substituted variable ${VARIABLE} is passed to dotnet publish command.
ARG VERSION
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build
ARG VERSION
RUN echo ${VERSION}
RUN echo ${VERSION} > image_version
WORKDIR /app
COPY . .
RUN dotnet restore
# TODO Pass the version as build command below.
RUN dotnet publish --version-suffix ${VERSION} --output /app/published-app
I tried different ways to do the variable substitution like below:
"$VERSION"
"$(VERSION)"
$VERSION ..... and many other ways I found in the internet. None of them worked. The argument passed is exactly what it is before the variable is substituted.
Thoughts on what may be causing this?

Variable Substitution with Bamboo in Dockerfile

My Dockerfile looks like the following:
from httpd:${bamboo.test.tag}
COPY index.html /usr/local/apache2/htdocs/
In Bamboo I have a task with the following script:
docker build --no-cache -t myproj/my .
When running the job, I get the following error:
build 26-Sep-2022 10:42:26 Step 1/2 : from httpd:${bamboo.test.tag}
error 26-Sep-2022 10:42:26 failed to process "httpd:${bamboo.test.tag}": missing ':' in substitution
How can I substitute the tag?
This is actually a problem with how you are using the dockerfile.
Docker will not expand environment variables inside your Dockerfile. You need to pass the environment value as a build argument in the docker build command then use the ARG keyword inside the Dockerfile.
Your Dockerfile would look like this:
ARG IMAGE_TAG
from httpd:${IMAGE_TAG}
COPY index.html /usr/local/apache2/htdocs/
And you would need to change you docker build command to:
docker build --no-cache --build-arg IMAGE_TAG=${bamboo.test.tag} -t myproj/my .
Check a more detailed explanation here

Bind path in singularity using container environment variable

I have a singularity container built with a scientific filesystem app.
I run the container with singularity run --app myapp image.sif and, accordingly, I have the environment variable SCIF_APPDATA=/scif/data/myapp set inside the container.
I'd like to bind a path using this environment variable. Something like:
singularity run -B /my/path/on/host/:$SCIF_APPDATA/input/
Unfortunately this does not work. I didn't manage to make singularity use as a mount path the environment variable with its "internal" value.
I have to explicitly pass the value of the environment variable:
singularity run -B /my/path/on/host/:/scif/data/myapp/input
Does anybody know how to use container environment variables in bind paths?
I don't think it is possible to directly use environment variables from inside the container in the bind statement. However, you can do it in two steps, first a call to singularity exec to get the value of the variable, then use it with singularity run:
SCIF_APPDATA=$(singularity exec ascisoftApp.sif bash -c "echo \$SCIF_APPDATA")
singularity run -B /my/path/on/host/:$SCIF_APPDATA/input/ ...
Don't forget the backslash to escape the $ in the echo command.
Note: Not sure why but it doesn't work for me when I directly use echo, hence the wrapping with bash -c.

How to make a Docker environment variable value to get a random id

I am looking to pass an environment variable which should get a random id.
Something like below.
ENV SERVICE_TAG= $uuid
In short, every time I run the container, I should get a random id for this environment variable inside the container.
Can anyone please suggest the way forward?
Thanks and regards,
Prasanth.
Add uuidgen package to the image. In case you are using alpine add
RUN apk add --no-cache util-linux
to the Dockerfile
Then in the entrypoint of your Dockerfile add
Below is a sample Dockerfile
FROM alpine:latest
RUN apk add --no-cache util-linux
ENTRYPOINT export UUID=`uuidgen` && echo $UUIDFROM alpine:latest
You should pass the environment variable from a docker run -env parameter generated uuid or guid from your shell, eg:
bash:
docker run --env SERVICE_TAG=$(uuidgen) yourimage
See more details at the official docker docs:
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e---env---env-file

Is there a way to define build stage in drone.yml?

I have some stages defined in drone.yml file. Is there a way to specify which stage need to be run through command line parameter? For example: below is my drone.yml file. I want to build buildOnContainer1 and buildOnContainer2 stage separately. So I am looking for a command such as drone exec buildOnContainer1. It only runs the command under buildOnContainer1.
buildOnContainer1:
image: container1
pull: true
commands:
- npm test:uat
buildOnContainer2:
image: container2
pull: true
commands:
- npm test:dev
My first thought to implement that granularity level of control is through environment variables.
Drone provides the ability to substitute environment variables at runtime. This gives us the ability to use dynamic build or commit details in our pipeline configuration.
You can pass environment variables to the command line and also to your Drone server using secrets. Check the Drone docs on ENV interpolation and docker exec command
You should build customized images for container1 and container2 to run the commands or skip them based on the values of specific environment variables.
A dirty example would be something like the following .drone.yml:
buildOnContainer1:
image: container1
pull: true
environment:
- SKIP=${skip.buildOnContainer1}
commands:
- ./myscript.sh test:uat
buildOnContainer2:
image: container2
pull: true
environment:
- SKIP=${skip.buildOnContainer2}
commands:
- ./mysqcrypt.sh test:dev
Your custom image should contain a mysqcript.sh bash script in your working directory. The script could check whether the value of the ENVAR SKIP is true or false. If true, it would do nothing. If false is would execute npm command with whatever args you had passed to the script.
Then you could execute the build locally:
drone exec --secret skip.buildOnContainer1=true --secret skip.buildOnContainer2=false