I want to create a dockerfile which contains 2 stages. The first stage is to set up a MySQL server and the second stage is to start a backend service that accesses the server. The problem is that the backend service stops when no MySQL server is available. Is there a way to make the stage dependent on the first stage being started? what is a little strange is that when i create the dockerfile with the database at the top, the log of the backend is displayed. If the backend is on top, the log of the MySQL is displayed when starting.
Actual Dockerfile:
FROM mysql:latest AS BackendDatabase
RUN chown -R mysql:root /var/lib/mysql/
ARG MYSQL_DATABASE="DienstplanverwaltungDatabase"
ARG MYSQL_USER="user"
ARG MYSQL_PASSWORD="password"
ARG MYSQL_ROOT_PASSWORD="password"
ENV MYSQL_DATABASE=$MYSQL_DATABASE
ENV MYSQL_USER=$MYSQL_USER
ENV MYSQL_PASSWORD=$MYSQL_PASSWORD
ENV MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
EXPOSE 3306
FROM openjdk:10-jre-slim AS Backend
LABEL description="Backend Dienstplanverwaltung"
LABEL maintainer="Martin"
COPY ./SpringDienstplanverwaltung/build/libs/dienstplanverwaltung-0.0.1-SNAPSHOT.jar /usr/local/app.jar
EXPOSE 8080
ENTRYPOINT java -jar /usr/local/app.jar
CodePudding user response:
actually you need Docker-composer of two containers. One for Mysql one for java app. Multistage is mostly for cases like #1 build something, for example java or Go. #2 create second image and copy results of build. The general idea is to keep the second stage clean. We do not need to build tools, only results in second stage. please see example:
FROM
Learn more about the "FROM" Dockerfile command.
golang:1.16
WORKDIR /go/src/github.com/alexellis/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go ./
RUN CGO_ENABLED=0 go build -a -installsuffix cgo -o app .
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=0 /go/src/github.com/alexellis/href-counter/app ./
CMD ["./app"]
CodePudding user response:
Okay you seem to be a little confused with various things here. First of all, multi-stage builds are for building an application that needs some kind of build/compiling process, copying that build into another container with fewer dependencies and with just the executable, so in this context, trying to run a database in a multistage build makes no sense at all, due to the fact that building the container does not run it.
Now, you want to have a multi stage to build the java app and then copy that build into another container and then run it. Also, when you are running that container you need a mysql database, using docker-compose is a good tool for that, like this example:
version: '3.8'
services:
db:
image: mysql:8.0
cap_add:
- SYS_NICE
restart: always
environment:
- MYSQL_DATABASE=mydatabase
- MYSQL_ROOT_PASSWORD=mypassword
ports:
- '3306:3306'
volumes:
- db:/var/lib/mysql
# - ./db/init.sql:/docker-entrypoint-initdb.d/init.sql
api:
container_name: your-backend
build:
context: .
image: your-backend
depends_on:
- db
ports:
- 8080:8080
environment:
ENV_VAR_EXAMPLE: example
links:
- db
volumes:
db:
driver: local
Also, an example multi-stage Dockerfile for java applications:
# First stage: complete build environment
FROM maven:3.5.0-jdk-8-alpine AS builder
# add pom.xml and source code
ADD ./pom.xml pom.xml
ADD ./src src/
# package jar
RUN mvn clean package
# Second stage: minimal runtime environment
From openjdk:8-jre-alpine
# copy jar from the first stage
COPY --from=builder target/my-app-1.0-SNAPSHOT.jar my-app-1.0-SNAPSHOT.jar
EXPOSE 8080
CMD ["java", "-jar", "my-app-1.0-SNAPSHOT.jar"]