Can't overwrite file in docker compose - docker

I'm using docker compose to set up a payara server and need to overwrite the domain.xml file. I'm currently doing it through
volumes:
- './domain.xml:/opt/payara41/glassfish/domains/domain1/config/domain.xml'
but when i compose it with docker-compose up it keeps saying that it could not rename domain.xml to domain.xml.bak. Is there any way i can get permissions to overwrite it or make sure the rename works ?

Something like this should work:
command: sh -c 'cp /tmp/domain.xml /opt/payara41/glassfish/domains/domain1/config/domain.xml && YOUR_PREVIOUS_COMMAND'
volumes:
- ./domain.xml:/tmp/domain.xml
Or edit your current command (or CMD) if it's a script, prepending the copy.
Edit: This alternative is very handy and elegant.
command: sh /run-from-compose.sh
volumes:
- ./domain.xml:/tmp/domain.xml
- ./run-from-compose.sh:/run-from-compose.sh
run-from-compose.sh:
#!/bin/sh
cp /tmp/domain.xml /opt/payara41/glassfish/domains/domain1/config/domain.xml
YOUR_PREVIOUS_COMMAND
You don't need to modify the image, just mount a custom script that acts as command.

Related

Is it possible run multiple setup scripts of subdirectories on docker container startup

I would like to run an oracle docker container using docker-compose. In my docker-compose.yml file i mount the docker volume as
volumes: - /host/folder:/opt/oracle/scripts/setup
Actually the /host/folder has multiple subdirectories containing some setup scripts which i want them to be executed when i do docker-compose up. Would runScripts.sh in container consider the subdirectories too ?
No. docker-compose does not consider your subdirectories for that.
You can run a specific bash script according to your requirements in which you can execute the specific scripts.
Your docker-compose.yml will look like following:
version: "3"
services:
setup:
image: ubuntu:latest
volumes:
- ./startup-script.sh:/root/startup-script.sh
- /host/folder:/opt/oracle/scripts/setup
entrypoint: "/root/startup-script.sh"
stdin_open: true
tty: true
And startup-script.sh will look like following:
#!/bin/bash
bash /directory1/script.sh
bash /directory2/script.sh
bash /directory3/script.sh
bash /directory4/script.sh
/bin/bash
exec "$#"
So, when docker container gets up, startup-script.sh will be executed and it will then execute all of your other required scripts.
Note: If your container is not of ubuntu image and supports sh instead of bash, then you can replace /bin/bash with bin/sh within your docker-compose.yml and startup-script.sh

Use credentials inside docker container

I'm building a docker image from a project where I have a file with default credentials for the database. At the docker container run time, I want to pass the real credentials and replace the variables defined on that file. What is the best way to do it? I tried to use environment variables, but it's not working.
db_config.yml:
host: ${HOST}
user: ${USER}
pass: ${PASS}
port: ${PORT}
db: ${DB_NAME}
docker-compose.yml:
version: '2.3'
services:
test_ctr:
container_name: test
image: container:latest
network_mode: "host"
environment:
- HOST=${HOST}
- USER=${USER}
- PASS=${PASS}
- PORT=${PORT}
- DB_NAME=${DB_NAME}
db_config.yml is in builded image and language is Python. Basically when I run container, db_config.yml is red by a script and use file's credentials. When I create the image, this db_config.yml have default credentials. but when I run the container, I want to replace this file
To debug this try running:
docker exec -it <name-of-the-container> <command>
In your case this translates to:
docker exec -it test sh
This should open a shell inside the container.
Then type:
printenv
This will print all Environment variables and their values (that way You will see if the values You have passed are present)
There will be a problem if the container is crashing at startup (in this case it's not possible to use docker exec).
TIP:
Use .env file located in the same directory as docker-compose.yml (or whatever your docker-compose file is) to pass variables.
.env:
KEY1=value1
KEY2=value2
In your case this might look something like:
HOST=1.2.3.4
USER=sa
PASSWORD=42
PORT=4242
DB_NAME=mydb
When your running:
docker-compose up
docker-compose will look for this .env file and will inject the values from this file
Good luck

Create a directory in docker-compose.yml file

I have a docker-compose yml that creates a sftp image on my docker. I'd like to write a script in the yml file as I want directories to be created automatically as soon as I run the docker-compose.yml.
Here's my yml file;
sftp:
image: atmoz/sftp
volumes:
- C:\tmp\sftp:/home/foo/upload
ports:
- "2222:22"
command: username:password:1001
Is there a way to write mkdir and chmod in this file?
You do not need to create and set mod manually, just pass the directory name to CMD and the entrypoint will create one for you. Here is the simplest example.
Define users in (1) command arguments, (2) SFTP_USERS environment
variable or (3) in file mounted as /etc/sftp/users.conf (syntax:
user:pass[:e][:uid[:gid[:dir1[,dir2]...]]] ..., see below for
examples)
using docker-compose
sftp:
image: atmoz/sftp
command: username:password:100:100:upload
it will create user name username and directory upload under /home/username
You can verify this using
docker exec -it --user username <container_id> bash -c "ls /home/username"
if you want to access upload files from host just add mounting in your docker-compose
sftp:
image: atmoz/sftp
command: username:password:100:100:upload
volumes:
- /host/upload:/home/username/upload
Examples
Simplest docker run example
docker run -p 22:22 -d atmoz/sftp foo:pass:::upload
User "foo" with password "pass" can login with sftp and upload files
to a folder called "upload". No mounted directories or custom UID/GID.
Later you can inspect the files and use --volumes-from to mount them
somewhere else (or see next example).
see the offical documentation

How to append command to docker-compose.yml without override existing?

In docker-compose.yml I have a service
app:
image: yiisoftware/yii2-php:7.1-apache
volumes:
- ~/.composer-docker/cache:/root/.composer/cache:delegated
- ./:/app:delegated
ports:
- '80:80'
depends_on:
- db
So I want to execute command yii migrate --interactive=0 when container is started. But if I just add string
command: "yii migrate --interactive=0"
It override command that already specified in yiisoftware/yii2-php:7.1-apache dockerfile. How can I append command, not replace? Is it possible?
I already googled for this problem, but most popular solution is "create your own dockerfile". Can I solve this without create/modify dockerfile or shell script, only with docker-compose?
To do this, you would have to define your own ENTRYPOINT in your docker-compose.yml. Besides building your own Dockerfile, there is no way around this.
As much as I am searching, I cannot find a CMD instruction in this image's Dockerfile, though. So this is probably what's being used.
I'm not familiar with PHP, so I cannot estimate what you would have to change to run a container with your specific needs, but these are the points that you should have a look at.
You can include the pre-existing command in your new command. Now understand that everything in those commands can be called from sh or bash. So look up the existing command by doing an:
docker image inspect yiisoftware/yii2-php:7.1-apache
Then check the command in Config { Command }. (Not ConatinerConfig.) So if the existing command had been:
"start-daemon -z foo-bar"
then your new command would be:
sh -c "start-daemon -z foo-bar; yii migrate --interactive=0"
Now you'll have the existing command plus your new command and the desired effect.

Mount a volume in docker-compose. How is it done?

If I execute this cmd in a console:
docker run -it --rm --link rabbit --link elasticsearch -v "$PWD"/logstash:/config-dir logstash logstash -f /config-dir/logstash.conf
It runs fine. Inside ./logstash folder there is a logstash.conf.
But now I'm trying to put in a docker-compose and the same doesn't works:
logstash:
image: logstash:latest
links:
- "elasticsearch:elasticsearch"
- "rabbit:rabbit"
volumes:
- $PWD/logstash:/config_dir
command:
- "-f /config_dir/logstash.conf"
But I cannot see the difference between both commands. Some help? How is it volume mounting done? Or is the command that doesn't works? Response from logstash init is:
logstash_1 | {:timestamp=>"2016-07-06T15:43:06.663000+0000", :message=>"No config files found: / /config_dir/logstash.conf\nCan you make sure this path is a logstash config file?", :level=>:error}
rabbitmq_logstash_1 exited with code 1
Edit: I finally solved the problem by removing the command and using the default command of the original image, but I still don't understand the problem and how the same command is passed to docker and works but if it is passed throught docker-compose don't.
Thanks in advance
Your config is probably not working because your version of docker-compose does not execute shell expansions while creating your container. That means that docker compose is trying to find a literal path $PWD/logstash instead of expanding $PWD to your present directory. Later versions of docker compose do allow for environment variable expansion.
Docker-compose does allow relative paths though, through the use of ./, which references the folder the compose file is in, not necessarily your pwd, so you just need to change your compose file to be:
volumes:
- ./logstash:/config_dir

Resources