Docker args in Docker compose does not pass into Dockerfile - docker

I am using the latest Docker Toolbox under Windows 10 to build the native image for Quarkus applciations.
$ docker -v
Docker version 19.03.1, build 74b1e89e8a
The docker-compose.yaml file:
version: '3.7' # specify docker-compose version
services:
blogdb:
image: postgres
ports:
- "5432:5432"
restart: always
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: blogdb
POSTGRES_USER: user
volumes:
- ./data:/var/lib/postgresql
post-service:
image: hantsy/quarkus-post-service
build:
context: ./backend
dockerfile: src/main/docker/Dockerfile.multistage
args:
- QUARKUS_DATASOURCE_URL
environment:
QUARKUS_DATASOURCE_URL: jdbc:postgresql://blogdb:5432/blogdb
ports:
- "8080:8080" #specify ports forewarding
depends_on:
- blogdb
And the Dockerfile:
## Stage 1 : build with maven builder image with native capabilities
FROM quay.io/quarkus/centos-quarkus-maven:19.1.1 AS build
ARG QUARKUS_DATASOURCE_URL
RUN echo "QUARKUS_DATASOURCE_URL>>>: $QUARKUS_DATASOURCE_URL"
ENV QUARKUS_DATASOURCE_URL $QUARKUS_DATASOURCE_URL
WORKDIR /usr/src/app
COPY pom.xml .
RUN mvn -U dependency:go-offline dependency:resolve-plugins -Pnative
COPY src/ /usr/src/app/src/
USER root
RUN chown -R quarkus /usr/src/app
USER quarkus
RUN mvn clean package -Pnative -Dquarkus.datasource.url=$QUARKUS_DATASOURCE_URL
## -DskipTests -Dmaven.test.skip=true
## Stage 2 : create the docker final image
FROM registry.access.redhat.com/ubi8/ubi-minimal
WORKDIR /work/
COPY --from=build /usr/src/app/target/*-runner /work/application
RUN chmod 775 /work
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
The echo always prints blank for the arg: QUARKUS_DATASOURCE_URL.
I have tried to change the args to QUARKUS_DATASOURCE_URL=${QUARKUS_DATASOURCE_URL}, it still prints blank.
It can not read the environment defined in docker-compose.yaml file as Docker docs described said.
If set value as a string directly, it workw, eg. QUARKUS_DATASOURCE_URL="test".

According to this, you need to follow window PowerShell syntax.
It seems that you must use $env:arg or %arg% when using PowerShell or cmd, but you must use $arg when using docker commands.
FROM microsoft/nanoserver
ARG QUARKUS_DATASOURCE_URL=some_default_value
RUN echo %QUARKUS_DATASOURCE_URL%
ENV QUARKUS_DATASOURCE_URL %QUARKUS_DATASOURCE_URL%
Can't get Docker to expand ARG define at head of file
It seems that you must use $env:arg or %arg% when using powershell or
cmd, but you must use $arg when using docker commands.

Related

i read old question but cant fix: docker Error: Unable to access jarfile

hi, I am new to docker and trying to containerize a simple spring boot application. The docker file is as below.
version:
win 11
docker desktop : newest version
dockerfile
FROM openjdk:8-jre-alpine
RUN mkdir app
WORKDIR /app
# Copy the jar to the production image from the builder stage.
COPY target/taco-cloud-*.jar app/taco-cloud.jar
# Run the web service on container startup.
EXPOSE 9090
CMD ["java", "-jar", "taco-cloud.jar"]
docker-compose
version: '2.4'
services:
mysql:
container_name: test-data
image: mysql:latest
networks:
- kell-network
restart: always
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=taco_cloud
- MYSQL_USER=kell
- MYSQL_PASSWORD=dskell0502
volumes:
- mysql-data:/var/lib/mysql
- ./schema.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "3307:3306"
web:
container_name: test-web
image: test:ver1
ports:
- "9090:9090"
depends_on:
- mysql
networks:
- kell-network
volumes:
mysql-data:
networks:
kell-network:
driver: bridge
when I am trying to run docker-compose, I am getting "Error: Unable to access jarfile taco-clound.jar"
test-web | Error: Unable to access jarfile taco-cloud.jar
I tried to edit the dockerfile but it still doesn't work
FROM maven:latest
RUN mkdir /app
WORKDIR /app
COPY . .
EXPOSE 8080
CMD ["mvn", "spring-boot:run"]
and
# Use the official maven/Java 8 image to create a build artifact: https://hub.docker.com/_/maven
FROM maven:3.5-jdk-8-alpine as builder
# Copy local code to the container image.
RUN mkdir app
WORKDIR /app
COPY pom.xml .
COPY src ./src
# Build a release artifact.
RUN mvn package -DskipTests
# Use the Official OpenJDK image for a lean production stage of our multi-stage build.
# https://hub.docker.com/_/openjdk
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM openjdk:8-jre-alpine
# Copy the jar to the production image from the builder stage.
COPY --from=builder target/taco-cloud-*.jar app/taco-cloud.jar
# Run the web service on container startup.
EXPOSE 9090
CMD ["java", "-jar", "taco-cloud.jar"]
WORKDIR /app
COPY target/taco-cloud-*.jar app/taco-cloud.jar
AFAIK COPY command don't support * wildcards. You have to know exact filename or rename it to taco-cloud.jar before building image and run COPY taco-cloud.jar ./taco-cloud.jar
Even if taco-cloud-*.jar will be copied, it will be copied into /app/app/taco-cloud.jar. Do you mean COPY {original_file} /app/taco-cloud.jar or COPY {original_file} ./taco-cloud.jar?

How to extend a Dockerfile?

I have a Dockerfile that is similar to all of my builds. It only differs in the EXPOSE <Port>.
Question: how could I create some kind of a template-dockerfile that I could simply reuse across all of my projects?
I must put the template dockerfile in another (gitlab) repository, some kind of "docker-commons".
For example (the exact details of the dockerfile are not important for my question);
Dockerfile:
# syntax=docker/dockerfile:1
FROM maven:3.8.4-eclipse-temurin-11 as build
COPY pom.xml .
COPY src src
RUN mvn package
RUN java -Djarmode=layertools -jar target/*.jar extract
FROM debian:buster-slim
COPY --from=build /extract/dependencies/ ./
COPY --from=build /extract/spring-boot-loader/ ./
COPY --from=build /extract/snapshot-dependencies/ ./
COPY --from=build /extract/application/ ./
EXPOSE 8090
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
From a programmers point of view, I want to create a "static base template" that I can pass the "port" parameter. Something like:
Dockerfile:
extends base_dockerfile
EXPOSE 8090
ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
Finally, I would then want to use that Dockerfile in different docker-compose.yml.
If the only params that change is the port you want to expose, you can override it whe you run the container. You don't need to expose a port in the Dockerfile, just bind it when you run the container.
https://docs.docker.com/engine/reference/builder/#expose
Using -p flag
docker run -p 80:80/tcp -p 80:80/udp ...
Or using ports in docker-compose (https://docs.docker.com/compose/networking/#configure-the-default-network)
version: "3.9"
services:
web:
build: .
ports:
- "8000:8090"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
Edit:
if you already have an image on a registry you can simply reference it
version: "3.9"
services:
web:
image:gitlab.simultech.it:4567/<project_path>
ports:
- "8000:8090"
db:
image: postgres
networks:
default:
# Use a custom driver
driver: custom-driver-1
docker run -p 80:80/tcp -p 80:80/udp gitlab.simultech.it:4567/<project_path>

How to build docker file for a VueJs application

I am new in docker. I've built an application with VueJs2 that interacts with an external API. I would like to run the application on docker.
Here is my docker-compose.yml file
version: '3'
services:
ew_cp:
image: vuejs_img
container_name: ew_cp
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
ports:
- '8080:8080'
Here is my Dockerfile:
FROM node:14.17.0-alpine as develop-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN yarn install
COPY . .
EXPOSE 8080
CMD ["node"]
Here is the building command I run to build my image an container.
docker-compose up -d
The image and container is building without error but when I run the container it stops immediately. So the container is not running.
Are the DockerFile and compose files set correctly?
First of all you run npm install and yarn install, which is doing the same thing, just using different package managers. Secondly you are using CMD ["node"] which does not start your vue application, so there is no job running and docker is shutting down.
For vue applicaton you normally want to build the app with static assets and then run a simple http server to serve the static content.
FROM node:lts-alpine
# install simple http server for serving static content
RUN npm install -g http-server
# make the 'app' folder the current working directory
WORKDIR /app
# copy 'package.json' to install dependencies
COPY package*.json ./
# install dependencies
RUN npm install
# copy files and folders to the current working directory (i.e. 'app' folder)
COPY . .
# build app for production with minification
RUN npm run build
EXPOSE 8080
CMD [ "http-server", "dist" ]
Your docker-compose file could be as simple as
version: "3.7"
services:
vue-app:
build:
context: .
dockerfile: Dockerfile
container_name: vue-app
restart: always
ports:
- "8080:8080"
networks:
- vue-network
networks:
vue-network:
driver: bridge
to run the service from docker-compose use command property in you docker-compose.yml.
services:
vue-app:
command: >
sh -c "yarn serve"
I'm not sure about the problem but by using command: tail -f /dev/null in your docker-compose file , it will keep up your container so you could track the error within it and find its problem. You could do that by running docker exec -it <CONTAINER-NAME> bash and track the error logs in your container.
version: '3'
services:
ew_cp:
image: vuejs_img
container_name: ew_cp
build:
context: .
dockerfile: Dockerfile
volumes:
- '.:/app'
- '/app/node_modules'
command: tail -f /dev/null
ports:
- '8080:8080'
In your Dockerfile you have to start your application e.g. npm run start or any other scripts that you are using for running your application in your package.json.

Pass ARG from docker-compose.yml to a docker image

So I have a NodeJS API which I have created, which contains a Private NPM package in the package.json.
I have the following Docker files in this project:
Dockerfile
FROM node:10
WORKDIR /usr/src/app
ARG NPM_TOKEN
COPY .npmrc ./
COPY package.json ./
RUN npm install
RUN rm -f ./.npmrc
COPY . .
CMD [ "npm", "start" ]
.npmrc
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
I have managed to build this API by running the command:
docker build --build-arg NPM_TOKEN=${MY_NPM_TOKEN} -t api:1.0.0 .
This successfully builds the image.
In my main application, I have a docker-compose.yml which I want to run this image.
version: '3' services: redis: container_name: redis image: redis:3.2.8 ports: - "6379:6379" volumes: - ./data:/data api: container_name: api image: api:1.0.0 build: context: . args: - NPM_TOKEN={MY_NPM_TOKEN} ports: - "3001:3001"
When I run docker-compose up it fails with the error:
Failed to replace env in config: ${NPM_TOKEN}
Does anyone have an idea, why my image is not taking in the ARG that is passed?
From my understanding, you are trying to pass the NPM_TOKEN arguments from the environment variable named MY_NPM_TOKEN.
However, there is an error in the syntax that you should update your docker-compose.yaml file
from - NPM_TOKEN={MY_NPM_TOKEN}
to - NPM_TOKEN=${MY_NPM_TOKEN}

Running Tomcat inside a Docker container - Container Exited at startup

I am learning Docker and trying to build a Dockerfile that will run a Tomcat using a docker-compose rather than docker.
The Dockerfile is as follows:
# Base the image on tomcat
FROM tomcat:7.0.82-jre7
WORKDIR /usr/local/tomcat
# Install updates & commands
RUN apt-get update && apt-get install -y vim
# Add some pre-set files
COPY tomcat-users.xml /usr/local/tomcat/conf
# Run the Tomcat on port 8080
EXPOSE 8080
# Start tomcat
# CMD ["bin/startup.sh", "run"]
The docker-compose.yml file is as follows:
version: '3'
services:
tomcat:
image: tomcat:7.0
build:
context: ./
dockerfile: Dockerfile
ports:
- 8888:8080
container_name: tomcat7
volumes:
- ./tomcat7:/usr/local/tomcat:rw
entrypoint: /bin/bash /usr/local/tomcat/bin/startup.sh
tty: true
The tomcat7 docker container starts but in exit mode.
Any idea how to make it run?

Resources