My question is related to docker-compose, I need to create a new docker-compose.yml file only for this purpose: to run 3 docker build commands:
docker build --target node-sdk -f ./Dockerfile.sdk -t casino-node-sdk:12.16.3 .
How can I do this as I don't really have services to run, context or images?
What I've tried
version: "3.8"
services:
build:
command: docker build --target node-sdk -f ./Dockerfile.sdk -t casino-node-sdk:12.16.3 .
command: docker build --target node-sdk-ssh -f ./Dockerfile.sdk -t casino-node-sdk-ssh:12.16.3 .
command: docker build --target node-run -f ./Dockerfile.sdk -t casino-node-run:12.16.3 .
Error
Service build has neither an image nor a build context specified. At least one must be provided.
Could you please help me with some ideas? I am a beginner at this.
For example: Let us assume, this is the content of the DockerFile you are having. Aliases are given as base, dev and prod.
DockerFile
FROM python:3.6 as base
RUN apt-get update && apt-get upgrade -y
RUN pip install pipenv pip
COPY Pipfile ./
# some more common configuration...
FROM base as dev
RUN pipenv install --system --skip-lock --dev
ENV FLASK_ENV development
ENV FLASK_DEBUG 1
FROM base as prod
RUN pipenv install --system --skip-lock
ENV FLASK_ENV production
docker-compose.yml
version: '3.8'
services:
app1:
build:
context: ./dir
dockerfile: Dockerfile
target: base
app2:
build:
context: ./dir
dockerfile: Dockerfile
target: dev
app3:
build:
context: ./dir
dockerfile: Dockerfile
target: prod
Here prod is the stage alias that you are using in the DockerFile. It can be base, dev, prod.
Related
I have this Dockerfile
FROM node:15.11.0-alpine
#ENVIRONNEMENT
ENV GLIB_PACKAGE_BASE_URL https://github.com/sgerrand/alpine-pkg-glibc/releases/download
ENV GLIB_VERSION 2.25-r0
ENV JAVA_HOME /usr/lib/jvm/java-1.8-openjdk
ENV GRADLE_HOME /usr/local/gradle
ENV GRADLE_VERSION 4.4
ENV ANDROID_HOME /usr/local/android-sdk-linux
ENV ANDRDOID_TOOLS_VERSION r25.2.5
ENV ANDROID_API_LEVELS android-26
ENV ANDROID_BUILD_TOOLS_VERSION 26.0.2
ENV IONIC_VERSION 5
ENV PATH ${GRADLE_HOME}/bin:${JAVA_HOME}/bin:${ANDROID_HOME}/tools:$ANDROID_HOME/platform-tools:$PATH
# INSTALL JAVA
RUN apk update ...
# INSTALL IONIC AND CORDOVA
RUN npm install -g cordova ionic#${IONIC_VERSION}
#INSTALL Graddle
RUN mkdir -p ${GRADLE_HOME} ...
# INSTALL ANDROID
RUN mkdir -p ${ANDROID_HOME} ...
# INSTALL GLIBC
RUN curl -L ...
# CONFIGURATION
RUN echo y | android update sdk --no-ui -a --filter platform-tools,${ANDROID_API_LEVELS},build-tools-${ANDROID_BUILD_TOOLS_VERSION}
# Make license agreement
RUN mkdir $ANDROID_HOME/licenses ...
#FILES DELETION
RUN rm -rf /tmp/* /var/cache/apk/*
WORKDIR /usr/app
RUN npm install
COPY ./ /usr/app
I am building it with CMD:
docker build -t <image-name> .
I have this docker-compose.yml file:
version: '3.6'
services:
app:
container_name: karma5_ionic
build:
context: .
dockerfile: Dockerfile
ports:
- '8100:8100'
- '35729:35729'
command: ionic serve --external
I run the following command:
sudo docker-compose up -d
The application is displaying fine in the browser in localhost:8100
Problem:
When I make changes, there is no hot reload.
localhost:35729 might be temporarily down or it may have moved permanently to a new web address.
Or localhost:35729 the connections was reset
The only way that i can see changes is if I
run docker-compose build
docker-compose up -d again
To whom it may concern:
I just needed to add
volumes:
- "./:/usr/app"
Whole docker-compose.yml file:
version: '3.6'
services:
app:
container_name: karma5_ionic
build:
context: .
dockerfile: Dockerfile
volumes:
- "./:/usr/app"
ports:
- '8100:8100'
- '35729:35729'
command: ionic serve --external
I would like to configure a CI such as TravisCI to build my application from Docker. My application has two part: Javascript and Python.
I thought to use docker-compose to do this:
version: '3'
services:
node:
image: node:12.8.0-buster
volumes:
- .:/srv
python:
image: python:3.7.4-buster
volumes:
- .:/src
I would like to have a Makefile such as:
all: foo bar
foo:
docker-compose exec node /bin/bash -c ' \
cd /workdir; \
npm install; \
npm run build'
bar:
docker-compose exec python /bin/bash -c ' \
cd /workdir; \
pip install sphinx; \
make html'
Is this correct to use docker compose like this? And what should I change to make it work?
docker compose not only support container run, but also image build, see this.
So, for your scenario, you should add your package build in Dockerfile and exeucte it with docker-compose up -d --build which will first build out a docker image then start the service base on the new docker image.
A simple fake code is as next, note next is just to explain the main idea, not a fully workable example, you need to add your stuff base on your real situation.
Dockerfile.node:
FROM node:12.8.0-buster
# Add related to build
ADD . /srv
# Add all package install
RUN cd /workdir && npm install && npm run build
# Others
......
Dockerfile.python:
FROM python:3.7.4-buster
# Add related to build
ADD . /srv
# Add all package install
RUN cd /workdir && pip install sphinx && make html
# Others
......
docker-compose.yaml:
version: '3'
services:
node:
build:
context: .
dockerfile: Dockerfile.node
volumes:
- .:/srv
python:
build:
context: .
dockerfile: Dockerfile.python
volumes:
- .:/src
I installed Go on Ubuntu 16.04. This is my GOPATH=/home/{username}/work.
I created a project into /home/{username}/work/src.
This is my project folder hierarchy.
project-name
services
configuration
api
main.go
Dockerfile
bff
api
main.go
Dockerfile
docker-compose.yml
favicon.ico
README.md
I can build and run with my dockerfile but I can't build and up with docker-compose.
I couldn't find any solution.
Configuration service dockerfile:
FROM golang:1.11.1-alpine3.8 as builder
RUN apk update && apk add git && go get gopkg.in/natefinch/lumberjack.v2
RUN mkdir -p /go/src/project-name/services/configuration
RUN CGO_ENABLED=0
RUN GOOS=linux
ADD . /go/src/project-name/services/configuration
ENV GOPATH /go
WORKDIR /go/src/project-name/services/configuration/api
RUN go get
RUN go build
FROM alpine
RUN apk update
RUN apk add curl
RUN mkdir -p /app
COPY --from=builder /go/src/project-name/services/configuration/api/ /app/
RUN chmod +x /app/api
WORKDIR /app
EXPOSE 5001
ENTRYPOINT ["/app/api"]
It works with dockerfile.
This is my docker-compose file:
version: '3.4'
services:
bff:
image: project-name/bff:${TAG:-latest}
build:
context: .
dockerfile: services/bff/Dockerfile
ports:
- "5000:5000"
container_name: bff
depends_on:
- configuration
configuration:
image: project-name/configuration:${TAG:-latest}
build:
context: .
dockerfile: services/configuration/Dockerfile
ports:
- "5001:5001"
container_name: configuration
It didn't work.
When the “run go get” command runs, it gives an error, the error is:
can't load package: package project-name/services/configuration/api: no Go files in /go/src/project-name/services/configuration/api
ERROR: Service 'configuration' failed to build: The command '/bin/sh -c go get' returned a non-zero code: 1
In your Dockerfile, you say
ADD . /go/src/project-name/services/configuration
which expects the build context directory on the host to contain the source files. But your docker-compose.yml file says
build:
context: .
dockerfile: services/configuration/Dockerfile
where the context directory is the root of your source control tree, not the specific Go source directory you're trying to build. If you change this to
build:
context: services/configuration
# Default value of "dockerfile: Dockerfile" will be right
it will likely work better.
In plain Docker commands, your current docker-compose.yml file says the equivalent of
cd $GOPATH/src/project-name
docker build -f services/configuration/Dockerfile .
But you're probably actually running
cd $GOPATH/src/project-name/services/configuration
docker build .
and what directory is the current directory matters.
How can I specify multi-stage build with in a docker-compose.yml?
For each variant (e.g. dev, prod...) I have a multi-stage build with 2 docker files:
dev: Dockerfile.base + Dockerfile.dev
or prod: Dockerfile.base + Dockerfile.prod
File Dockerfile.base (common for all variants):
FROM python:3.6
RUN apt-get update && apt-get upgrade -y
RUN pip install pipenv pip
COPY Pipfile ./
# some more common configuration...
File Dockerfile.dev:
FROM flaskapp:base
RUN pipenv install --system --skip-lock --dev
ENV FLASK_ENV development
ENV FLASK_DEBUG 1
File Dockerfile.prod:
FROM flaskapp:base
RUN pipenv install --system --skip-lock
ENV FLASK_ENV production
Without docker-compose, I can build as:
# Building dev
docker build --tag flaskapp:base -f Dockerfile.base .
docker build --tag flaskapp:dev -f Dockerfile.dev .
# or building prod
docker build --tag flaskapp:base -f Dockerfile.base .
docker build --tag flaskapp:dev -f Dockerfile.dev .
According to the compose-file doc, I can specify a Dockerfile to build.
# docker-compose.yml
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
But how can I specify 2 Dockerfiles in docker-compose.yml (for multi-stage build)?
As mentioned in the comments, a multi-stage build involves a single Dockerfile to perform multiple stages. What you have is a common base image.
You could convert these to a non-traditional multi-stage build with a syntax like (I say non-traditional because you do not perform any copying between the layers and instead use just the from line to pick from a prior stage):
FROM python:3.6 as base
RUN apt-get update && apt-get upgrade -y
RUN pip install pipenv pip
COPY Pipfile ./
# some more common configuration...
FROM base as dev
RUN pipenv install --system --skip-lock --dev
ENV FLASK_ENV development
ENV FLASK_DEBUG 1
FROM base as prod
RUN pipenv install --system --skip-lock
ENV FLASK_ENV production
Then you can build one stage or another using the --target syntax to build, or a compose file like:
# docker-compose.yml
version: '3.4'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile
target: prod
The biggest downside is the current build engine will go through every stage until it reaches the target. Build caching can mean that's only a sub-second process. And BuildKit which is coming out of experimental in 18.09 and will need upstream support from docker-compose will be more intelligent about only running the needed commands to get your desired target built.
All that said, I believe this is trying to fit a square peg in a round hole. The docker-compose developer is encouraging users to move away from doing the build within the compose file itself since it's not supported in swarm mode. Instead, the recommended solution is to perform builds with a CI/CD build server, and push those images to a registry. Then you can run the same compose file with docker-compose or docker stack deploy or even some k8s equivalents, without needing to redesign your workflow.
you can use as well concating of docker-compose files, with including both dockerfile pointing to your existing dockerfiles and run docker-compose -f docker-compose.yml -f docker-compose.prod.yml build
Newbie to Docker and what appears to be a simple issue isn't working. I would like to build a binary inside of a dockerfile and execute the binary in docker-compose.
Dockerfile:
FROM golang:1.10
ENV DIR=/go/src/api
RUN go get github.com/Masterminds/glide
WORKDIR $DIR
ADD glide.yaml glide.yaml
ADD glide.lock glide.lock
RUN glide install
COPY . $DIR
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
CMD main
And in my docker-compose.yml I have this:
version: '2'
services:
api:
build:
context: ./api
dockerfile: Dockerfile
ports:
- 8000:8000
However, there's no main executable when run from docker-compose. I've actually added a command: ls to the docker-compose file and it's not there. I've then added a ls to the Dockerfile image and main is there.
How do I prevent main from being lost in translation?