programing

도커 작성 - 여러 명령을 실행하는 방법?

megabox 2023. 8. 2. 08:57
반응형

도커 작성 - 여러 명령을 실행하는 방법?

다음 코드로 여러 명령을 실행할 수 있는 이런 작업을 수행하고 싶습니다.

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

여러 명령을 실행하려면 어떻게 해야 합니까?

알아냈어요, 사용하세요.

예:

command: bash -c "python manage.py migrate && python manage.py runserver 0.0.0.0:8000"

다중 행의 동일한 예:

command: >
    bash -c "python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000"

또는:

command: bash -c "
    python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000
  "

를 사용하는 것이 좋습니다.sh와는반과 bash대부분의 유닉스 기반 이미지(알파인 등)에서 더 쉽게 사용할 수 있기 때문입니다.

에 예가 있습니다.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"

이렇게 하면 다음 명령이 순서대로 호출됩니다.

  • python manage.py wait_for_dbDB가 준비될 때까지 기다립니다.
  • python manage.py migrate 실행
  • python manage.py runserver 0.0.0.0:8000하기 »

저는 별도의 사용 후 삭제 컨테이너에서 마이그레이션과 같은 사전 시작 작업을 실행합니다(참고로 작성 파일은 버전 '2' 유형이어야 함).

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

이것은 사물을 깨끗하고 분리된 상태로 유지하는 데 도움을 줍니다.고려해야 할 두 가지 사항:

  1. 시작 순서가 올바른지 확인해야 합니다(dependent_on 사용).

  2. 빌드 및 이미지를 사용하여 한 번에 태그를 지정하여 수행하는 다중 빌드를 피하려고 합니다. 그런 다음 다른 컨테이너의 이미지를 참조할 수 있습니다.

이것은 나에게 도움이 됩니다.

version: '3.1'
services:
  db:
    image: postgres
  web:
    build: .
    command:
      - /bin/bash
      - -c
      - |
        python manage.py migrate
        python manage.py runserver 0.0.0.0:8000

    volumes:
      - .:/code
    ports:
      - "8000:8000"
    links:
      - db

명령을 실행하기 전에 docker-backer는 변수의 참조를 취소하려고 하므로 변수를 처리하려면 변수를 두 배로 늘려서 달러-backer를 탈출해야 합니다.

    command:
      - /bin/bash
      - -c
      - |
        var=$$(echo 'foo')
        echo $$var # prints foo

...오류가 발생할 경우:

서비스 "web"의 "command" 옵션에 대한 보간 형식이 잘못되었습니다.

제일 깨끗해요?

---
version: "2"
services:
  test:
    image: alpine
    entrypoint: ["/bin/sh","-c"]
    command:
    - |
       echo a
       echo b
       echo c

여기서 진입점을 사용할 수 있습니다.도커의 진입점은 명령 전에 실행되며 명령은 컨테이너가 시작될 때 실행되어야 하는 기본 명령입니다.따라서 대부분의 애플리케이션은 일반적으로 진입점 파일에 설정 절차를 수행하고 마지막으로 명령 실행을 허용합니다.

은 " 셸스크립파다같만이듭다니음과일을트▁be▁as▁may"와 같을 수 .docker-entrypoint.sh(이름은 중요하지 않습니다) 다음 내용이 포함되어 있습니다.

#!/bin/bash
python manage.py migrate
exec "$@"

docker-docker.yml 파일과 합니다.entrypoint: /docker-entrypoint.sh을 " 및명을다로등니합다록으음"로 등록합니다.command: python manage.py runserver 0.0.0.0:8000추신: 복사하는 것을 잊지 마세요.docker-entrypoint.sh당신의 코드와 함께.

다른 아이디어:

이 경우처럼 컨테이너를 빌드할 경우 시작 스크립트를 컨테이너에 넣고 명령을 사용하여 이를 실행합니다.또는 시작 스크립트를 볼륨으로 마운트합니다.

이 스레드에는 이미 많은 훌륭한 답변이 있지만, 특히 Debian 기반 사용자에게 그 중 몇 가지 조합이 가장 잘 작동하는 것으로 보인다는 것을 알게 되었습니다.

services:
  db:
    . . . 
  web:
    . . .
    depends_on:
       - "db"
    command: >      
      bash -c "./wait-for-it.sh db:5432 -- python manage.py makemigrations
      && python manage.py migrate
      && python manage.py runserver 0.0.0.0:8000"

필수 구성 요소: wait-for-it.sh 을 프로젝트 디렉토리에 추가합니다.

문서에서 경고: ""Wait-for-it를 사용할 때.sh) 운영 환경에서 데이터베이스를 사용할 수 없게 되거나 언제든지 호스트를 이동할 수 있습니다. (이 솔루션은) 이러한 수준의 복원력이 필요하지 않습니다."

편집:

이 방법은 단기적으로는 효과적이지만 장기적인 해결책을 위해서는 각 이미지에 대해 도커 파일의 진입점을 사용해야 합니다.

업데이트 *

일부 명령을 실행하는 가장 좋은 방법은 이미지에서 공식 CMD를 실행하기 전에 원하는 모든 작업을 수행하는 사용자 지정 Docker 파일을 작성하는 것이라고 생각했습니다.

도커식의음:

version: '3'

# Can be used as an alternative to VBox/Vagrant
services:

  mongo:
    container_name: mongo
    image: mongo
    build:
      context: .
      dockerfile: deploy/local/Dockerfile.mongo
    ports:
      - "27017:27017"
    volumes:
      - ../.data/mongodb:/data/db

Dockerfile.mongo:

FROM mongo:3.2.12

RUN mkdir -p /fixtures

COPY ./fixtures /fixtures

RUN (mongod --fork --syslog && \
     mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
     mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
     mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
     mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
     mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
     mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
     mongoimport --db wcm-local --collection videos --file /fixtures/videos.json)

이것이 아마도 가장 깨끗한 방법일 것입니다.

오래된 방법 *

명령어로 셸 스크립트를 만들었습니다.는 이경에저시싶다니었습고하작는우다니▁start▁to싶▁in▁wanted었을 시작하고 싶었습니다.mongod그리고 실행mongoimport하지만 부르는 것mongod나머지를 실행할 수 없도록 차단합니다.

도커식의:

version: '3'

services:
  mongo:
    container_name: mongo
    image: mongo:3.2.12
    ports:
      - "27017:27017"
    volumes:
      - ./fixtures:/fixtures
      - ./deploy:/deploy
      - ../.data/mongodb:/data/db
    command: sh /deploy/local/start_mongod.sh

start_mongod.sh:

mongod --fork --syslog && \
mongoimport --db wcm-local --collection clients --file /fixtures/clients.json && \
mongoimport --db wcm-local --collection configs --file /fixtures/configs.json && \
mongoimport --db wcm-local --collection content --file /fixtures/content.json && \
mongoimport --db wcm-local --collection licenses --file /fixtures/licenses.json && \
mongoimport --db wcm-local --collection lists --file /fixtures/lists.json && \
mongoimport --db wcm-local --collection properties --file /fixtures/properties.json && \
mongoimport --db wcm-local --collection videos --file /fixtures/videos.json && \
pkill -f mongod && \
sleep 2 && \
mongod

그래서 이 포크 몽고는 모노 임포트를 하고, 분리된 포크 몽고를 죽이고, 분리되지 않고 다시 시작합니다.분기된 프로세스에 연결할 수 있는 방법이 있는지 확실하지 않지만 이것은 효과가 있습니다.

참고: 일부 초기 DB 데이터를 로드하려면 다음과 같이 하십시오.

mongo_import.sh

#!/bin/bash
# Import from fixtures

# Used in build and docker-compose mongo (different dirs)
DIRECTORY=../deploy/local/mongo_fixtures
if [[ -d "/fixtures" ]]; then
    DIRECTORY=/fixtures
fi
echo ${DIRECTORY}

mongoimport --db wcm-local --collection clients --file ${DIRECTORY}/clients.json && \
mongoimport --db wcm-local --collection configs --file ${DIRECTORY}/configs.json && \
mongoimport --db wcm-local --collection content --file ${DIRECTORY}/content.json && \
mongoimport --db wcm-local --collection licenses --file ${DIRECTORY}/licenses.json && \
mongoimport --db wcm-local --collection lists --file ${DIRECTORY}/lists.json && \
mongoimport --db wcm-local --collection properties --file ${DIRECTORY}/properties.json && \
mongoimport --db wcm-local --collection videos --file ${DIRECTORY}/videos.json

mongo_mongo/*.json 파일은 mongoexport 명령을 통해 생성되었습니다.

도커식의

version: '3'

services:
  mongo:
    container_name: mongo
    image: mongo:3.2.12
    ports:
      - "27017:27017"
    volumes:
      - mongo-data:/data/db:cached
      - ./deploy/local/mongo_fixtures:/fixtures
      - ./deploy/local/mongo_import.sh:/docker-entrypoint-initdb.d/mongo_import.sh


volumes:
  mongo-data:
    driver: local

를 사용하여 도커 합성 파일에서 여러 명령을 실행합니다.

command: >
    bash -c "python manage.py makemigrations
    && python manage.py migrate
    && python manage.py runserver 0.0.0.0:8000"

출처: https://intellipaat.com/community/19590/docker-run-multiple-commands-using-docker-compose-at-once?show=19597#a19597

이것이 이 문제에 대한 제 해결책입니다.

services:
  mongo1:
    container_name: mongo1
    image: mongo:4.4.4
    restart: always
#    OPTION 01:
#    command: >
#      bash -c "chmod +x /scripts/rs-init.sh
#      && sh /scripts/rs-init.sh"
#    OPTION 02:
    entrypoint: [ "bash", "-c", "chmod +x /scripts/rs-init.sh && sh /scripts/rs-init.sh"]
    ports:
      - "9042:9042"
    networks:
      - mongo-cluster
    volumes:
      - ~/mongors/data1:/data/db
      - ./rs-init.sh:/scripts/rs-init.sh
      - api_vol:/data/db
    environment:
      *env-vars
    depends_on:
      - mongo2
      - mongo3

Alpine 기반 이미지에는 실제로 bash가 설치되어 있지 않은 것처럼 보이지만 사용할 수 있습니다.sh또는ash에 링크/bin/busybox.

»docker-compose.yml:

version: "3"
services:

  api:
    restart: unless-stopped
    command: ash -c "flask models init && flask run"

두 개 이상의 데몬 프로세스를 실행해야 하는 경우 Docker 설명서에 Supervisord를 분리되지 않은 모드로 사용하여 모든 하위 데몬이 stdout으로 출력되도록 하는 제안이 있습니다.

다른 SO 질문에서 하위 프로세스 출력을 stdout으로 리디렉션할 수 있다는 것을 발견했습니다.그래야 모든 출력을 볼 수 있습니다!

대기 또는 도커라이즈와 같은 도구를 사용합니다.응용 프로그램 이미지에 포함할 수 있는 작은 래퍼 스크립트입니다.또는 애플리케이션별 명령을 수행하기 위해 고유한 래퍼 스크립트를 작성합니다.다음에 따르면: https://docs.docker.com/compose/startup-order/

@Bjorn 응답을 기반으로, 도커는 최근 "init 컨테이너"가 성공적으로 종료될 때까지 기다릴 수 있는 특별한 종속성 규칙을 도입했습니다.

db:
  image: postgres
web:
  image: app
  command: python manage.py runserver 0.0.0.0:8000
  depends_on:
    db:
    migration:
      condition: service_completed_successfully
migration:
  build: .
  image: app
  command: python manage.py migrate
  depends_on:
    - db

빌드킷이 아직 필요한지는 모르겠지만, 제 입장에서는 그것이 작동합니다.

DOCKER_BUILDKIT=1 COMPOSE_DOCKER_CLI_BUILD=1 docker-compose up

Windows 컨테이너에서 실행하는 방법:

  • 만들다.bat파일(cmd로 실행하거나 다음을 만들 수 있습니다..ps1용기에 파워셸이 있으면 실행합니다.)
  • 에서command또는entrypoint사용하다myFile.bat(또는)myFile.ps1)

벨로우마이docker-compose.yml:

version: "3.4"

services:
  myservicename:
    image: mcr.microsoft.com/dotnet/sdk:6.0 
    container_name: mycontainername
    environment:
      - PORT=44390
    command: buildAndRun.bat
[...]

나의buildAndRun.bat:

dotnet --list-sdks
dotnet build
dotnet run

젠킨스 사용자로서 도커 컨테이너를 구축하기 위해 젠킨스 컨테이너를 설정하는 중에 이 문제가 발생했습니다.

도커에 손을 대야 했습니다.나중에 도커 합성 파일에서 링크할 때 도커 파일의 sock 파일.제가 먼저 손을 대지 않는 한, 그것은 아직 존재하지 않았습니다.이것은 저에게 효과가 있었습니다.

도커 파일:

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.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

동일한 컨테이너에서 포트 3000에서 리액트 앱을 실행하고 포트 6006에서 스토리북을 실행하려는 경우에도 동일한 문제가 발생했습니다.

도커 파일의 진입점 명령어와 도커 컴포지를 사용하여 둘 다 시작하려고 했습니다.command선택.

이것에 시간을 보낸 후, 이 서비스들을 별도의 컨테이너로 분리하기로 결정했고 그것은 매력적으로 작동했습니다.

다른 사용자가 Windows 기반 컨테이너를 사용하여 여러 명령을 파악하려는 경우 다음 형식이 작동합니다.
command: "cmd.exe /c call C:/Temp/script1.bat && dir && C:/Temp/script2.bat && ..."

'통화' 지침을 포함하는 것이 저에게 그것을 고친 것입니다.

또는 이전 명령을 실행하지 않고 각 명령을 실행할 수 있는 경우 세미콜론으로 구분합니다.
command: "cmd.exe /c call C:/Temp/script1.bat; dir; C:/Temp/script2.bat; ... "

첫 번째 서비스가 필요하고, 시작만 하는 것이 아니라 두 번째 서비스를 기다리는 것이 필요하다면, 건강 점검을 할 수 있습니다.다음과 같은 것:

db:
  image: postgres
  container_name: postgres_test
  ports: "8000:8000"
  healthcheck:
    test: ["CMD-SHELL", "pg_isready", "-h", "localhost", "-p", "5432"]
    interval: 5s
    timeout: 3s
    retries: 10 
web:
  build: .
  command: command1 && comand2
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  depends_on:
    postgres_test:
      condition: service_healthy

이렇게 하면 첫 번째 서비스가 자체 정의 상태 점검의 정의에 따라 상태/연결 가능한 경우에만 두 번째 서비스가 실행됩니다(이 경우 5432에 연결하는 즉시 이 서비스에 연결 가능).

예를 들어 버전 2인 경우 ";"를 사용하여 명령을 분리해 보십시오.

command: "sleep 20; echo 'a'"

언급URL : https://stackoverflow.com/questions/30063907/docker-compose-how-to-execute-multiple-commands

반응형