Currently, my docker-compose.yml is building an image. I have an image from a 3rd party that I need to add alongside my own, which my own image will be dependent on. When running the 3rd party image independently, I need to pass an argument to it like this:
docker run third_party/image --argument_flag
How do I translate this into the docker-compose.yml so that the argument_flag gets passed. Here is my yml (names have been generalized).
version: '3'
services:
my_app:
build: .
volumes:
- .:/my_app_folder
depends_on:
- "third_party"
third_party:
image: third_party/image
ports:
- "8050:8050"
You can pass your argument by overriding the default command
In Dockerfile you can get the argument ARGUMENT:
docker-compose build --build-arg PRODUCTION=VALUE
Dockerfile:
ARG ARGUMENT
FROM node:latest
or try to check it out:
How to pass arguments within docker-compose?
seems like the answer has been already there
In docker-compose file you can add like this. 'args' tag in docker-compose file represent the argument same as docker run.
third_party:
image: third_party/image
args:
some_variable_name: some_value
ports:
- "8050:8050"
Related
I have a docker-compose.yaml looking like this:
version: '3.9'
services:
sqlcl:
container_name: container_sqlcl
image: sqlcl
volumes:
- ./TNSNAMES.ORA:/opt/oracle/network/admin/TNSNAMES.ORA
environment:
- TNS_ADMIN=/opt/oracle/network/admin
entrypoint: ["sql", "mycredentials"]
build:
context: .
dockerfile: Dockerfile
args:
GIT_TOKEN: my_git_token
tty: true
I would like to pass a command when running the container (I don't want to put a command in my yaml file because I want the script to be passed as an argument), like this:
docker exec 1872dfa12f47 #"path_to_my_file.sql"
However, this executes #"path_to_my_file.sql" before the entrypoint reaches the sqlcl console, where it is supposed to run.
With a docker image, I would do the below:
docker run sqlcl #"path_to_my_file.sql"
And it would overwrite the CMD, but with an already created container it does not seem to work like that.
It works if I do this:
docker exec 1872dfa12f47 sql mycredentials #"path_to_my_file.sql"
But I would like to keep my ENTRYPOINT in my yaml file.
I am trying to build the two services with the same image, but two different Dockerfile. However Docker will always use only one Dockerfile for both, even though two have been defined:
version: '3.4'
services:
serviceA:
image: myimage
build:
dockerfile: ./Dockerfile
context: ${project.basedir}/${project.artifactId}-docker/target
depends_on:
- serviceB
serviceB:
image: myimage
build:
dockerfile: ./Dockerfile-cloud
context: ${project.basedir}/${project.artifactId}-docker/target
Even though I also say dependsOn, running
docker-compose up -f docker-compose.yml
it only used the Dockerfile-cloud for both.
I guess your problem is that you tag your image as myimage (using latest by default). So docker will build a first version of myimage with Dockerfile, then it'll build another version of myimage with Dockerfile-cloud, and in the end it will only use the latest version. This is why it will use Dockerfile-cloud for both. To fix it remove image: myimage or do something like:
serviceA:
image: myimage:serviceA
...
serviceB:
image: myimage:serviceB
Since you're building the two containers' images from different Dockerfiles, they can't really be the same image; they'll have different content and metadata.
Compose is capable of assigning unique names for the various things it generates. Unless you need to do something like docker-compose push built images to a registry, you can generally just omit the image: line. The two containers will use separate images built from their own Dockerfiles, and the Compose-assigned names will avoid the ambiguity you're running into here.
version: '3.8'
services:
serviceA:
# no image:
# short form of build: with default dockerfile: and no args:
build: ${project.basedir}/${project.artifactId}-docker/target
depends_on:
- serviceB
serviceB:
# no image:
build:
context: ${project.basedir}/${project.artifactId}-docker/target
dockerfile: ./Dockerfile-cloud
I have the following in my docker-compose.yml file
geth-testnet:
build:
context: .
dockerfile: Dockerfile
args:
GETH_REPO: 'https://github.com/ethereum/go-ethereum'
GETH_VERSION: 'v1.8.12'
RPC_LISTEN_PORT: 8546
command: "--rpcport ${RPC_LISTEN_PORT}"
entrypoint:
- "geth"
tty: true
image: geth-node-testnet:v1.8.12
container_name: geth-node-testnet
ports:
- '8546:8546'
volumes:
- /root/.ethereum
When I run, docker-compose up --build, expect it to run the following command:
geth -rpcport 8546
However, I get the following error
flag needs an argument: -rpcport
So, the value for RPC_LISTEN_PORT is not correctly substituted.
I have ARG RPC_LISTEN_PORT in my dockerfile
Double checked your question, seems command: "--rpcport ${RPC_LISTEN_PORT}" cannot utilize the value you put in docker-compose.yml.
So afford two solutions:
export RPC_LISTEN_PORT=8546 in bash before you do compose command.
New a .env file in the same folder, put RPC_LISTEN_PORT=8546 to it.
Newbie here. I created an empty solution, added WebApplication1 and WebApplication2. I then added docker support (Docker for Windows, Windows Containers). Compose file looks like this:
version: '3.4'
services:
webapplication1:
image: compositeapp
build:
context: .\WebApplication1
dockerfile: Dockerfile
webapplication2:
image: compositeapp
build:
context: .\WebApplication2
dockerfile: Dockerfile
So both containers are in a single image. Webapplication1 dockerfile has ENV LICENSE=abc123 and webapplication2 dockerfile has ENV LICENSE=abc456.
After building and starting the containers, I used exec -it powershell to remote into the 2 containers and did get-item env:license. Both containers returned 456.
As a newbie, I was expecting one machine to return abc123 and the other abc456. I just made up the environment name as being license, but what does one do if they need a per container environment variable?
I guess the issue you notice provides from the fact you specified the same image name for both services, which implies that they will have the same ENV variable as defined in the latest-compiled Dockerfile.
Could you try this instead?
version: '3.4'
services:
webapplication1:
image: compositeapp1
build:
context: .\WebApplication1
dockerfile: Dockerfile
webapplication2:
image: compositeapp2
build:
context: .\WebApplication2
dockerfile: Dockerfile
Anyway, even if this is working, I assume your two Dockerfile are almost the same (?), in which case I would rather suggest to use a single Dockerfile and a single image tag, but customize the environment of both services by using some environment section in your docker-compose.yml (or some env_file section, along with some external .env files...).
For example, you may want to write something like this:
version: '3.4'
services:
webapplication1:
image: compositeapp
build:
context: .\WebApplication
dockerfile: Dockerfile
environment:
- LICENSE=abc123
webapplication2:
image: compositeapp
environment:
- LICENSE=abc456
(not forgetting to remove the ENV LICENSE=... line from the Dockerfile)
Please help me understand the difference between 'image' and 'build' within docker compose
image means docker compose will run a container based on that image
build means docker compose will first build an image based on the Dockerfile found in the path associated with build (and then run a container based on that image).
PR 2458 was eventually merged to allow both (and use image as the image name when building, if it exists).
therobyouknow mentions in the comments:
dockerfile: as a sub-statement beneath build: can be used to specify the filename/path of the Dockerfile.
version: '3'
services:
webapp:
build:
context: ./dir
dockerfile: Dockerfile-alternate
args:
buildno: 1
build: expects dockerfile path as an argument, it will build an image first and then use the image to create a container.
image: expects existing image name as argument , it will launch container using this image.
Example:docker-compose.yaml
version: '3'
services:
service1:
build: .
ports:
- "5000:5000"
service2:
image: "redis:alpine"
service1 will build an image first based on Dockerfile of current path and run container based on this image.
service2 will download "redis:alpine" image from docker hub and run container on downloaded image.