Pass argument to container on runtime AFTER entrypoint - docker

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.

Related

Pass args to image in docker-compose.yml

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"

Unable to start Tomcat from docker-compose

I'm unable to start Tomcat server from docker compose.
When I log into container using docker exec -it <container id> bash and see ps -eaf | grep "tomcat" it is showing empty. Tomcat server is not running.
docker-compose.yml file:
version: "3"
services:
meghcore:
build: ./Core
container_name: 'meghcore'
expose:
- '8080'
ports:
- '8080:8080'
volumes:
- meghcore:/opt/Tomcat1/webapps/
command: /bin/bash
tty: true
stdin_open: true
networks:
- meghnet
volumes:
meghcore:
networks:
meghnet:
driver: bridge
Dockerfile file:
FROM tomcat:8.5.35
WORKDIR /app
COPY . /app
RUN mv /app/*.war /opt/Tomcat1/webapps/
ENV PATH $PATH:/opt/Tomcat1/bin
WORKDIR /opt/Tomcat1/bin
EXPOSE 8080
CMD ["catalina.sh", "run"]
Since you specify an alternate command: in your docker-compose.yml file, that overrides the CMD in the Dockerfile. You don't need most of the options you specify there at all, and several of them (the alternate command:, the volumes: overwriting the actual application) interfere with the normal container operation.
A complete, functional docker-compose.yml would be
version: "3"
services:
meghcore:
build: ./Core
ports:
- '8080:8080'
None of the other options you list out are necessary. If there were other containers listed in the file, they could still communicate using their Docker Compose service names, without any special setup (another container in this same file could successfully call http://meghcore:8080).
What is happening is command specify in docker-compose.yml is overwriting the CMD provided in dockerfile.
kindly update command with the command available in dockerfile or remove command from docker-compose.yml
Problem is resolved by adding below commands in dockerfile and removed command from docker compose file.
ENV PATH $PATH:$JAVA_HOME/bin
ENV PATH $PATH:/opt/Tomcat1/bin
WORKDIR /opt/Tomcat1/bin
EXPOSE 8080
CMD ["catalina.sh", "run"]

Using args in docker-compose file

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.

Docker: Why does my project have a .env file?

I'm working on a group project involving Docker that has a .env file, which looks like this:
DATABASE_URL=xxx
DJANGO_SETTINGS_MODULE=xxx
SECRET_KEY=xxx
Couldn't this just be declared inside the Dockerfile? If so, what is the advantage of making a .env file?
Not sure if I'm going in the right direction with this, but this Docker Docs page says (emphasis my own):
Your configuration options can contain environment variables. Compose
uses the variable values from the shell environment in which
docker-compose is run. For example, suppose the shell contains
POSTGRES_VERSION=9.3 and you supply this configuration:
db:
`image: "postgres:${POSTGRES_VERSION}"`
When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in. For this example, Compose resolves the image to postgres:9.3 before running the configuration.
If an environment variable is not set, Compose substitutes with an empty string. In the example above, if POSTGRES_VERSION is not set, the value for the image option is postgres:.
You can set default values for environment variables using a .env file, which Compose automatically looks for. Values set in the shell environment override those set in the .env file.
If we're using a .env file, then wouldn't I see some ${...} syntax in our docker-compose.yml file? I don't see anything like that, though.
Here's our docker-compose.yml file:
version: '3'
services:
server:
build:
context: ./server
dockerfile: Dockerfile
env_file: .env.dev
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- ./server:/app
ports:
- "8500:8000"
depends_on:
- db
stdin_open: true
tty: true
db:
image: postgres
client:
build:
context: ./client
dockerfile: Dockerfile
command: bash -c "npm install; npm run start"
volumes:
- ./client:/app
- /app/node_modules
ports:
- "3000:3000"
depends_on:
- server
Idea there is probably to have a place to keep secrets separated from docker-compose.yml, which you then can keep in VCS and/or share.

Are docker environment variables shared between containers?

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)

Resources