Makefile target output as input parameter to shell script - bash

I have following Makefile target defined:
.PHONY: docker-build
docker-build:
# Build Docker image
docker build \
--squash \
...
-t $(DOCKER_IMAGE):$(DOCKER_TAG) .
output:
#echo Docker Image: $(DOCKER_IMAGE):$(DOCKER_TAG)
I need to use the variables DOCKER_IMAGE and DOCKER_TAG as input for another script to run right after the make docker-build.
Do you have any idea how to do it? Thanks in advance.
I have tried many ways but can't get the output from Makefile to environment variables or even just to terminal.

Related

Run local script with arguments with docker

I am trying to run a local script with docker bash in windows PowerShell but not working.
My script part is another program, but the finally goal is to process a media file and zip it with the shell script.
The cmd: docker exec -it containername /bin/bash < myscript.sh -f fileone.mp4 -h output
I have an error in ps:
The '<' operator is reserved for future use.
The parameters (and also the files) are changing, if rerun the shell script, and after the script, processing is done it will create a zip file (what I need) with the output name, but random strings will be placed to the zipped filename too.
Anyone tried to use docker in that way in windows?
I figure out a solution for my own question. I just leave it here, if someone needs it.
The docker-compose file:
version: '3.8'
services:
somename:
build:
context: .
dockerfile: Dockerfile
container_name: 'name_if_you_need'
The dockerfile:
FROM debian:latest
# Install and/or config anything what you need
ADD . /newfolder
WORKDIR /newfolder
ENTRYPOINT [ "/newfolder/myscript.sh" ]
To call (with arguments and/or flags if your script need it): docker run --rm -v ${PWD}:/newfolder image_name -flag1 sample.mp4 -flag2 sample (no tty error, not need winpty)
Please note, if your script working with file or files, and you pass it via arguments like me, you need to copy them in your current folder before docker run
With this solution, if your script generates a file or files when/after executing, you will see them automatically in your current folder.

How to export hostname in make file and use in compose file

I am working on docker and docker-compose file, where I need hostname. I am also using Makefile to start container. but this container need hostname.
Following is my Makefile where I start command and subcommand that executes.
This command does not export MY_HOST var value from hostname -i.
start:
export MY_HOST=`hostname -i`
echo ${MY_HOST}
docker -f test.yml up -d
following is my docker-compose yml file where I want to use exported variable.
MyImage:
image:registry.test:latest
restart:always
environment:
MY_HOST=${MY_HOST}
What's wrong with this code? can someone help on this.
Unfortunately it is impossible to pass env variables from one Makefile command to another, because each line execute separately. But you can define variable and reuse it later this way:
MY_HOST := `hostname`
start:
MY_HOST=${MY_HOST}\
docker-compose run --rm shell env
docker-compose.yml
MyImage:
image:registry.test:latest
restart:always
environment:
- MY_HOST
https://www.gnu.org/software/make/manual/make.html#Values
also
https://makefiletutorial.com/#variables
and
pass env variables in make command in makefile

What that this line means in a make file `DOCKER := $(shell command -v docker)`

$(shell command -v docker) What command means? it's being used in a Makefile.
I saw this in a github repository that I'm trying to understand.
It looks like it's setting a variable with a command to test if docker is installed, and stop the build if its not, the problem is this that I don't have a command installed and I tryed to install command in ubuntu but it can't find it, looking on internet how to install this commad command seems realy difficult because of its name, how to install command in linux/ubuntu didn't bring anything useful, also search for this being using on Makefiles trying to get some clue but nothing so far.
Running the build command seems to work becuse it build the image and yes I have docker installed, but still getting that message in the terminal make: command: Command not found
Any idea?
make build output (trucated):
$ make build
make: command: Command not found
make: command: Command not found
docker build -t codelytv/typescript-ddd-skeleton:dev .
Sending build context to Docker daemon 1.023MB
.....
This is the Makefile:
.PHONY = default deps build test start clean start-database
IMAGE_NAME := codelytv/typescript-ddd-skeleton
SERVICE_NAME := app
# Test if the dependencies we need to run this Makefile are installed
DOCKER := $(shell command -v docker)
DOCKER_COMPOSE := $(shell command -v docker-compose)
deps:
ifndef DOCKER
#echo "Docker is not available. Please install docker"
#exit 1
endif
ifndef DOCKER_COMPOSE
#echo "docker-compose is not available. Please install docker-compose"
#exit 1
endif
default: build
# Build image
build:
docker build -t $(IMAGE_NAME):dev .
# Run tests
test: build
docker-compose run --rm $(SERVICE_NAME) bash -c 'npm run build && npm run test'
# Start the application
start: build
docker-compose up $(SERVICE_NAME) && docker-compose down
# Clean containers
clean:
docker-compose down --rmi local --volumes --remove-orphans
# Start mongodb container in background
start_database:
docker-compose up -d mongo
What it means is that the person who wrote this makefile wasn't careful enough to write it in a portable way.
The command command is part of the shell (which is why you won't see it if you look for it in the GNU make manual). Not only that, it's part of the bash shell specifically: it is not a POSIX sh standard command. The bash man page says:
command [-pVv] command [arg ...]
Run command with args suppressing the normal shell function
lookup. Only builtin commands or commands found in the PATH are
executed.
Basically, running command docker ... means that any shell alias or function named docker is ignored, and only the actual docker command is run.
However, GNU make always runs /bin/sh as its shell, including for both recipes and for the $(shell ...) function.
So, if you're on a system (such as Red Hat or CentOS or Fedora GNU/Linux) where the /bin/sh is a link to the bash shell, then the above command will work.
However, if you're on a system (such as Debian or Ubuntu GNU/Linux) where the /bin/sh is a link to a simpler POSIX shell such as dash, then the above command will not work.
In reality, this is not needed because there won't be any shell aliases or functions defined in the shell that make invokes, regardless. However, if the author wants to use bash shell features in their makefiles and allow them to work, they also need to tell make to use bash as its shell, by adding this to their makefile:
SHELL := /bin/bash
(of course this assumes that the user has a /bin/bash on their system, but...)

output information with a docker build

I have a Dockerfile like this:
FROM centos:7 as builder
LABEL maintainer="seanchann <seanchann#test.com>"
COPY ./build.sh /build.sh
RUN source /build.sh; \
build_lib ""
then in my build_lib function. it calls Makefile to build a c lib. but there not have any output information from the function of build_lib. how to enable output from make in build_lib
build.sh:
function build_lib(){
cd /mysource/
make
}
Make sure to COPY build.sh first into your image:
COPY build.sh /
Then you can try and run it.
Your docker build should be done in a dedicated folder where there is only your Dockerfile and build.sh script, in order to limit the docker build context volume.
you need to have the source present for build to run
COPY mysource mysource/
you should see build.sh failed in your docker build output
when make runs correctly you will see the make output run in stdout
if you want to catch this to a file use tee
e.g.
docker build -t mycontainer . | tee output.file

docker run script which exports env variables

I've search some of the questions already like docker ENV vs RUN export, which explains differences between those commands, but didn't help in solving my problem.
For example I have a script called myscript:
#!/bin/bash
export PLATFORM_HOME="$(pwd)"
And have following lines in Dockerfile:
...
COPY myscript.sh /
RUN ./myscript.sh
I've also tried to use ENTRYPOINT instead of RUN or declaring variable before calling the script, all that with no success.
What I want to achieve is that PLATFORM_HOME can be referenced from other Dockerfiles which use that one as a base. How to do it ?
There's no way to export a variable from a script to a child image. As a general rule, environment variables travel down, never up to a parent.
ENV will persist in the build environment and to child images and containers.
Dockerfile
FROM busybox
ENV PLATFORM_HOME test
RUN echo $PLATFORM_HOME
Dockerfile.child
FROM me/platform
RUN echo $PLATFORM_HOME
CMD ["sh", "-c", "echo $PLATFORM_HOME"]
Build the parent
docker build -t me/platform .
Then build the child:
→ docker build -f Dockerfile.child -t me/platform-test .
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM me/platform
---> 539b52190af4
Step 2/3 : RUN echo $PLATFORM_HOME
---> Using cache
---> 40e0bfa872ed
Step 3/3 : CMD sh -c echo $PLATFORM_HOME
---> Using cache
---> 0c0e842f99fd
Successfully built 0c0e842f99fd
Successfully tagged me/platform-test:latest
Then run
→ docker run --rm me/platform-test
test
I think export sets the environment variables for the child processes. So it really doesn't matter if you do RUN or ENTRYPOINT. In reading linux source command not working when building Dockerfile, I feel source command cannot help either.
You need to use ENV if you want to set the environment variables in Dockerfile.
Just use ENV PLATFORM_HOME=$(pwd) in your Dockerfile. Variable will be accessible in every container you will create from the Dockerfile.

Resources