How to extend a Dockerfile? - docker

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>

Related

Dockerfile permission for volume

FROM --platform=$BUILDPLATFORM maven:3.8.5-eclipse-temurin-17 AS builder
WORKDIR /server
COPY pom.xml /server/pom.xml
RUN mvn dependency:go-offline
COPY src /server/src
RUN mvn install
# install Docker tools (cli, buildx, compose)
COPY --from=gloursdocker/docker / /
CMD ["mvn", "spring-boot:run"]
FROM builder as prepare-production
RUN mkdir -p target/dependency
WORKDIR /server/target/dependency
RUN jar -xf ../*.jar
FROM eclipse-temurin:17-jre-focal
EXPOSE 8080
VOLUME /app
ARG DEPENDENCY=/server/target/dependency
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=prepare-production ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.server.backend.BackendApplicaiton"]
and I need to save the files in /app to the /opt/containers/backend directory (absolute). Code bellow is my docker compose file.
version: "3.9"
services:
backend:
container_name: "backend"
build: backend
environment:
- ${MSSQL_PASSWORD}
ports:
- 3000:8080
volumes:
- /opt/containers/backend:/app
networks:
- backend
networks:
backend:
name: backend
driver: bridge
internal: false
if I run this and create volume in docker, everything works, files are saved inside docker volume, but when I set absolute path as in the docker compose file, directory is empty and app does not run. I am sure the error is in permissions, but I cant figured it out where and I could not find any solutions :(
Thank you for all your replies and help.

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?

Problem with img reference in docker-compose

Hello i tried to build docker-compose in my project with these structure file:
app/
-front-end/src/Components
-back-end/images
but when i run build i have these error with img relative url:
frontend_1 | Module not found: Can't resolve '../../../../../back-end/images'
And these is my docker-compose file:
version: '2'
services:
backend:
network_mode: host
build: ./back-end/
ports:
- "6200:6200"
volumes:
- ./back-end:/usr/src/app
frontend:
build: ./front-end/
ports:
- "3000:3000"
volumes:
- ./front-end:/usr/src/app
depends_on:
- backend
My frontend Dockerfile:
FROM node:10.15.3
RUN mkdir -p /usr/src/app
WORKDIR /TuKanasta
EXPOSE 3000
CMD ["npm", "start"]
the backend Dockerfile:
FROM node:10.15.3
RUN mkdir -p /usr/src/app
WORKDIR /TuKanasta
RUN npm install -g nodemon
EXPOSE 4000
CMD [ "npm", "start" ]
Note: My project run 100 % without docker.
volumes:
- ./back-end:/usr/src/app
...
volumes:
- ./front-end:/usr/src/app
If set in the same image, the second bind mount volume would overwrite the first /usr/src/app content, as illustrated in gladiusio/gladius-archive-node issue 4.
If set in two different images, /usr/src/app in frontend1 would not be able to see back-end, copied in /usr/src/app separate volume of backend service.
Declaring the volume as external might help, as illustrated in this thread.
Or copying into an existing volume (shown here)

Docker args in Docker compose does not pass into Dockerfile

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.

Connect python with h2o that runs in docker, but ipv4 for h2o changes

I'm new to docker and I'm trying to run h2o in docker and then use python to connect to it.
I have folder with:
model-generator folder in which I have the python script and Dockerfile to build an image
h2o-start folder in which I have h2o.jar file and Dockerfile to start that jar
docker-compose.yml file with:
version: "3"
services:
h2o-start:
image: milanpanic2/h2o-start
build:
context: ./h2o-start
restart: always
model-generator:
image: milanpanic2/model-generator
build:
context: ./model-generator
restart: always
My python script contains:
import h2o
h2o.connect(ip='172.19.0.3', port='54321')
When I run docker-compose up it gives me an error that python can't connect, because there isn't anything on 172.19.0.3
Dockerfile for python
FROM python:2.7-slim
WORKDIR /app
ADD . /app
RUN pip install > --trusted-host pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
CMD ["python", "passhash.py"]
Dockerfile for h2o
FROM openjdk:8
ADD h2o.jar h2o.jar
EXPOSE 54321 EXPOSE 54322
ENTRYPOINT ["java", "-jar", "h2o.jar"]
Try to start container exposing port 54321: add to your h2o-start: in docker-compose file:
ports:
- "54321:54321"
- "54322:54322"

Resources