可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I want to do something like this where I can run multiple commands in order.
db:
image: postgres
web:
build: .
command: python manage.py migrate
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
回答1:
Figured it out, use bash -c
.
Example:
command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
Same example in multilines:
command: >
bash -c "python manage.py migrate
&& python manage.py runserver 0.0.0.0:8000"
回答2:
I run pre-startup stuff like migrations in a separate ephemeral container, like so (note, compose file has to be of version '2' type):
db:
image: postgres
web:
image: app
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
depends_on:
- migration
migration:
build: .
image: app
command: python manage.py migrate
volumes:
- .:/code
links:
- db
depends_on:
- db
This helps things keeping clean and separate. Two things to consider:
You have to ensure the correct startup sequence (using depends_on)
you want to avoid multiple builds which is achieved by tagging it the first time round using build and image; you can refer to image in other containers then
回答3:
I recommend using sh
as opposed to bash
because it is more readily available on most unix based images (alpine, etc).
Here is an example docker-compose.yml
:
version: '3'
services:
app:
build:
context: .
command: >
sh -c "python manage.py wait_for_db &&
python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
This will call the following commands in order:
python manage.py wait_for_db
- wait for the db to be ready
python manage.py migrate
- run any migrations
python manage.py runserver 0.0.0.0:8000
- start my development server
回答4:
Another idea:
If, as in this case, you build the container just place a startup script in it and run this with command. Or mount the startup script as volume.
回答5:
You can use entrypoint here. entrypoint in docker is executed before the command while command is the default command that should be run when container starts.
So most of the applications generally carry setup procedure in entrypoint file and in the last they allow command to run.
make a shell script file may be as docker-entrypoint.sh
(name does not matter) with following contents in it.
#!/bin/bash
python manage.py migrate
exec "$@"
in docker-compose.yml file use it with entrypoint: /docker-entrypoint.sh
and register command as command: python manage.py runserver 0.0.0.0:8000
P.S : do not forget to copy docker-entrypoint.sh
along with your code.
回答6:
If you need to run more than one daemon process, there's a suggestion in the Docker documentation to use Supervisord in an un-detached mode so all the sub-daemons will output to the stdout.
From another SO question, I discovered you can redirect the child processes output to the stdout. That way you can see all the output!
回答7:
Use a tool such as wait-for-it or dockerize. These are small wrapper scripts which you can include in your application’s image. Or write your own wrapper script to perform a more application-specific commands. according to: https://docs.docker.com/compose/startup-order/
回答8:
I ran into this while trying to get my jenkins container set up to build docker containers as the jenkins user.
I needed to touch the docker.sock file in the Dockerfile as i link it later on in the docker-compose file. Unless i touch'ed it first, it didn't yet exist. This worked for me.
Dockerfile:
USER root
RUN apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release;
echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce
RUN groupmod -g 492 docker && \
usermod -aG docker jenkins && \
touch /var/run/docker.sock && \
chmod 777 /var/run/docker.sock
USER Jenkins
docker-compose.yml:
version: '3.3'
services:
jenkins_pipeline:
build: .
ports:
- "8083:8083"
- "50083:50080"
volumes:
- /root/pipeline/jenkins/mount_point_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
回答9:
Though this is not entirely relevant to the question, posting it here incase it helps someone. If you want to run a command before starting of the container, you can run the container normally. Then login to the container and make the changes. You can then commit the container as a new image. This new image can be used to ensure that all necessary changes exist before starting the container.
回答10:
try using ";" to separate the commands if you are in verions two
e.g.
command: "sleep 20; echo 'a'"