Compose: docker-compose.yml에서 환경 변수 보간

에 만든 2015년 04월 30일  ·  109코멘트  ·  출처: docker/compose

( 오래된 것이 짐이 ​​많이 쌓여서 새로운 이슈를 만들고 있습니다.)

docker-compose.yml 의 any * 구성 항목 값에 환경 변수를 전달할 수 있어야합니다. 많은 사람들이하고 싶어하고 휴대성에도 좋고 혼돈을 일으키지 않을 것이라는 점에 만족합니다.

몇 가지 계산이 있습니다.

필수 변수 및 선택적 기본값

환경에 _ 반드시 _ 있어야하는 변수를 지정할 수 있으면 유용합니다. 즉, 그렇지 않으면 Compose가 실행을 거부 할 것입니다. 그러나 이것은 당신이 그것들을 많이 가지고있을 때 고통 스러울 것이므로 명시 적으로 활성화하거나 기본값을 지정할 수 있어야합니다.

MVP 구현에는 두 기능 중 하나가 필요하지 않지만 이전 버전과 호환되는 방식으로 둘 다 구현할 수있는 명확한 경로가 있어야합니다.

통사론

무겁지 않은 한 확립 된 표준을 구현하는 강력한 사례가 있습니다. 기능에 대한 요구 사항은 최소화됩니다.

  • POSIX 매개 변수 확장 은 정상입니다. 몇 가지 기능이 너무 많지만 일부를 구현할 수 있습니다.

    • ${VARIABLE} - VARIABLE 가 설정되지 않은 경우 빈 문자열을 출력합니다.

    • ${VARIABLE-default} - VARIABLE 가 설정되지 않은 경우 default 출력

    • ${VARIABLE?} - VARIABLE 가 설정되지 않은 경우 오류 발생

https://github.com/docker/compose/pull/845 는 POSIX 매개 변수 확장과 비슷하지만 약간 다른 Bash 스타일의 ${VARIABLE:default} 구문을 구현했습니다.

  • Python의 형식 구문 은 구현하기가 쉽지만 Python 언어와 연결되어 있으며 기능이 너무 많습니다.

이행

Python의 os.path.expandvars 함수는 POSIX 매개 변수 확장의 가장 기본적인 경우를 구현합니다.

>>> from os.path import expandvars
>>> expandvars('${HOME}')
'/Users/aanand'

그러나 적어도 두 가지 문제가 있습니다.

  1. 설정되지 않은 변수는 빈 문자열로 확장되지 않고 대신 확장되지 않습니다.

```

expandvars ( '$ {UNSET}')
'$ {UNSET}'
```

  1. 잘못된 구문은 오류가 발생하지 않고 대신 확장되지 않습니다.

```

expandvars ( '$ {HOME')
'$ {홈'
```

지금까지 https://github.com/docker/compose/pull/845 가 가장 가깝지만 정규식에 의존하는 구현에 대해 근본적으로주의하고 있습니다. 템플릿 작성은 사소한 일이 아니며 사람들은 모든 종류의 깨진 물건을 넣을 것이므로 도움이되는 메시지와 함께 강력하고 엄격하며 오류가있는 무언가가 필요합니다. 두 가지 중요한 요구 사항 :

  • 누군가 잘못된 것을 입력하면 Compose가 실행되지 않습니다.
  • 템플릿 구문에 사용 된 특수 문자를 이스케이프 할 수 있습니다.

이미 Bash와 같은 변수 보간에 대한 좋은 Python 구현이있을 수 있습니다. 그렇지 않은 경우 독립 실행 형을 만드는 것이 Compose 코드베이스를 확장하는 것보다 훨씬 낫습니다.

* 사실, 보간을 허용하지 _ 않아야하는 _ 구성 키가 있습니까?

kinenhancement kinfeature

가장 유용한 댓글

내 사용 사례 수 있도록하는 것입니다 $PWD 에서 volumes 팀의 모든 개발자가 경로가 여전히 제대로 마운트 될 어디서나에 REPO를 복제 할 수 있습니다.

elasticsearch:
  image: zinvoice/elasticsearch
  volumes:
    - $PWD:/app

모든 109 댓글

이러한 확립 된 UNIX 표준을 얼마나 멀리 가고 싶습니까? (FWIW, 이것은 사실상의 표준이 아니라 실제 표준입니다.)

가끔 실수로 Dockerfiles에서 POSIX 매개 변수 확장 을 사용하려고 시도하는 사람으로서 docker-compose.yml에서 모두 지원된다면 저를 행복한 캠핑카로 만들 것입니다.

@kojiromike 흠, 그래서 POSIX 매개 변수 확장은 실제로 내가하려는 것이지만 문서를 읽으면 구문 / 의미를 잘못 기억 한 것처럼 보입니다.

편집 : 설명의 구문에 대한 생각을 업데이트했습니다.

나는 이전 스레드를 따라 왔으며 긴급히이 기능을 원했습니다. 마지막으로 고통이 너무 커서 POSIX 스타일의 변수를 대체하기 위해 yaml 전 처리기 bahs 스크립트를 만들었습니다. 잘 작동했지만 결국 한 가지 문제가 있었기 때문에 사용을 중단했습니다. 최종 솔루션을 얻기 전에 먼저 전처리기를 실행하고 모든 매개 변수를 설정해야합니다. 이제 docker yaml extends 기능을 사용하고 있습니다. 실제 구성을 체크인하고 대상에서 실행할 수 있기 때문입니다. 우리는 무슨 일이 일어날 지 더 잘 알고 있습니다.

내가 docker-compose 전달 변수의 지지자 였지만 지금은 확실하지 않습니다.

이상적인 솔루션으로도 커가 제대로 확장되는 것을보고 싶습니다. 어떤 의미에서 두 가지 모두에 적합한 솔루션이 될 것입니다. 그렇다면 도커에서 깨진 것은 무엇입니까? 기본적으로 상속 된 파일에 모든 항목을 작성해야한다는 사실입니다. 재정의하려는 항목 만 입력하는 병합이 아닙니다.

실제 예와 그것이 얼마나 장황한 지 살펴보십시오. 중요한 것은 두 줄뿐입니다.

#Common 
elasticsearch:
  image: zinvoice/elasticsearch
  hostname: elasticsearch
  restart: always
  dns: 172.17.42.1
  ports:
    - "9200:9200"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro
    - /data/elasticsearch:/opt/elasticsearch/data/elasticsearch

logstash:
  image: zinvoice/logstash
  hostname: logstash
  dns: 172.17.42.1
  restart: always
  ports:
    - "5000:5000"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro

kibana:
  image: zinvoice/kibana
  hostname: kibana
  dns: 172.17.42.1
  restart: always
  ports:
    - "5601:5601"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro

logspout:
  image: zinvoice/logspout
  hostname: logspout
  command: logstash://logstash.docker:5000
  restart: always
  dns: 172.17.42.1
  ports:
    - "8003:8000"
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock

doorman:
  image: zinvoice/doorman
  hostname: doorman
  restart:  always
  dns: 172.17.42.1
  ports:
    - "8085:8085"
# inherited
elasticsearch:
  extends:
    file: ../common.yml
    service: elasticsearch

logstash:
  extends:
    file: ../common.yml
    service: logstash

kibana:
  extends:
    file: ../common.yml
    service: kibana

logspout:
  extends:
    file: ../common.yml
    service: logspout

doorman:
  environment:
    - DOORMAN_GITHUB_APPID=xxxxxxxx
    - DOORMAN_GITHUB_APPSECRET=xxxxxx
  links:
    - nginxtrusted
  extends:
    file: ../common.yml
    service: doorman

그래서 내 권장 사항 수정 도커는 덜 장황하게 확장합니다. YAML이 필요한 모든 기능을 제공하므로 많은 코드를 작성할 필요조차 없습니다. 표준 YAML을 고수하면 다른 도구 및 UI에서 파일을 분석하거나 만들 수 있습니다.

YAML "노드 앵커"와 YAML "파일 병합"을 살펴보면 완벽한 솔루션이 될 수 있습니다.

참고 :이 토론은 현재 # 1380에서 계속됩니다.

@ Vad1mo 귀하의 경우 extends 이 부족하다는 데 동의합니다. 그 경험을 개선하기 위해 우리가 할 수있는 일이 많이 있습니다. 별도의 문제를 열어 주실 수 있습니까?

물론이야! 저는 이것이 쉽고 우아한 대안이 될 수 있음을 강조하고 싶었습니다.
compose extends가 너무 변수 전달의 절반을 얻는다면, 개선 된 compose-extends는 변수 전달을 쓸모 ​​없게 만들 것입니다. 이해해야 할 개념이 적 으면 사용자가 더 쉽게 이해할 수 있습니다.

내 사용 사례 수 있도록하는 것입니다 $PWD 에서 volumes 팀의 모든 개발자가 경로가 여전히 제대로 마운트 될 어디서나에 REPO를 복제 할 수 있습니다.

elasticsearch:
  image: zinvoice/elasticsearch
  volumes:
    - $PWD:/app

@mattes 이미 지원되고 있다고 생각합니다. .:/app 도 지원됩니다.

@aanand PoC로서 Python에서 POSIX PE 의 더러운 해킹을

@kojiromike 멋지네요 . 계속할 계획이 있으면 알려주세요.

@aanand 나는 의도했지만 지금 당장은 확실히 몇 가지 버그가 있습니다 (그리고 shlex 를 사용하는 것이 나쁜 생각이었을 수도 있습니다). 물론 버그 리포트와 PR도 환영합니다.

@dnephin $HOME / ~ 어때요?

@nafg 둘 다 볼륨의 호스트 경로에 대해 지원됩니다.

@dnephin 흥미로운, b / c 어떻게 든 '$ HOME'이라는 디렉토리로 끝났습니다 ...

@aanand "$ { VARIABLE : default }"제안과 마찬가지로 global_extends (또는 "import")를 사용하면이 기능이 다소 강력 해집니다.

Q : 호스트에 노출되는 포트 번호를 지정할 수 있습니까? 예 : "$ {WEB_ PORT : 80 } : 80"?
사용 사례는 일반적으로 다른 포트를 수신하거나 다른 로컬 도메인 이름에 할당 된 동일한 머신 / 클러스터에서 앱의 여러 인스턴스를 쉽게 스핀 업할 수있는 것입니다.

예, 그렇게 할 수 있습니다.

docker-compose scale my_app=3 와 함께 볼륨에서 vars를 사용하고 싶습니다. 이 docker-compose.yml

server:
  image: alexanderilyin/docker-teamcity-server
  ports:
   - "8111:8111"
  volumes:
    - .TeamCity:/root/.BuildServer
  links:
   - mysql
mysql:
  image: alexanderilyin/docker-mysql
  volumes:
    - .MySQL:/var/lib/mysql
  environment:
    MYSQL_DATABASE: teamcity
    MYSQL_USER: teamcity
    MYSQL_PASSWORD: teamcity
    MYSQL_ALLOW_EMPTY_PASSWORD: yes
agent:
  image: alexanderilyin/docker-teamcity-agent
  links:
   - server

에이전트에 scale 를 사용하고 실행 사이에 데이터를 유지하기 위해 동적 볼륨을 사용할 수 있기를 원합니다. 예를 들면 다음과 같습니다.

agent:
  image: alexanderilyin/docker-teamcity-agent
  volumes:
    - .agent_{$AGENT_INSTANCE_ID}:/opt/buildAgent
  links:
   - server

이미지 이름의 일부로 변수를 보간 할 수 있기를 바랍니다.
https://github.com/openshift/source-to-image 를 사용하여 모든 분기에 대한 CI에 로컬 컨테이너를 빌드 한 다음 docker-compose를 사용하여 테스트를 실행합니다.
동적 이미지로 테스트를 실행하는 것은 docker-compose로 매우 복잡하며 수동 템플릿 렌더링이 필요합니다 .. : -1 :

그러나 COMPOSE_PROJECT_NAME 를 설정하여 실행 당 접두사를 제어하여 이미 올바르게 수행 할 수 있습니까? 그렇다면 복잡한 논리와 이름 주위에 읽을 수없는 yml 파일이 필요하지 않습니다.

@andrerom 은 따르지 않습니다. 대신 이미지 속성을 설정하는 동안 다음 Sets the project name, which is prepended to the name of every container started by Compose 를 제어하는 ​​문서에 따르면 :

web:
  image: <I_AM_DYNAMIC>

아, 내 실수.

당신이 의미한다고 생각

<I_AM_DYNAMIC>:
  image: nginx

동적 이미지 (및 빌드) 참조는 실제로 많은 의미가 있습니다. 예를 들어 프로그래밍 언어에 대한 디버그 및 비 디버그 기본 컨테이너 간 전환은 이에 대한 좋은 사용 사례입니다.

추가 사용 사례 _ (@ Maxim-Filimonov가 염두에 둔 것일 수 있음) _ : 이미지를 사용할 태그를 재정의 할 수 있으므로 기본적으로 : latest를 사용할 수 있지만 yml을 변경하지 않고 다른 것을 쉽게 테스트하도록 변경할 수 있습니다. 파일 _ (기본적으로 CI 사용 사례에 필요) _.

@andrerom 은 정확히 우리의 사용 사례입니다 : +1 :

이것은 또한 같은 일에도 작동합니까 ??

web:
  environment:
    - FOO=${whoami}

@ k0377 셸에서 처리하는 작업이기 때문에 그럴 것이라고 생각하지 않지만 결과를 환경 변수에 추가하고 사용할 수 있습니다.

이 특별한 경우에 $USER 환경 변수는 아마도 당신에게 똑같은 것을 줄 것입니다.

@aanand 이미 존재하는 기존 템플릿 엔진을 사용하지 않는 이유는 무엇입니까? Jinja2가 있고 잘 작동합니다.

앞서 언급했듯이-우리 자신의 템플릿을 구현하는 것은 사소한 작업이 아니므로 (정규식은 그다지 멋지지 않습니다) 견고 함이 입증 된 기존 템플릿을 사용해야합니다.

또는 YAML ancors 및 참조 https://gist.github.com/bowsersenior/979804를 사용할 수 있습니다.

그러나 변수 사용에 제한이 있습니다 (콘텐츠 중간에 변수 이름 삽입).

+1 for Jinja2 : 확실히 틀에 맞을 것이고 ansible은
정확히 그 사용 사례 (yml 파일에서 템플릿 작성)

2015 년 5 월 26 일 화요일 오후 1:25에 tonnzor [email protected] 은 다음과 같이 썼습니다.

@aanand https://github.com/aanand 기존 템플릿을 사용하지 않는 이유
이미 존재하는 엔진? Jinja2가 있고 잘 작동합니다.

앞서 언급했듯이-자체 템플릿을 구현하는 것은 간단한 작업이 아닙니다.
(그리고 정규 표현식은 그다지 멋지지 않습니다) 이미 존재하는 것을 사용해야합니다.
견고 함이 입증되었습니다.


이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment -105493447.

Jinja2는 우리가 필요로하는 것보다 더 많이합니다.

  • 조건부
  • 루핑
  • 확장 / 상속
  • 코멘트
  • 필터

Compose에 해당 항목을 추가하지 않습니다. Jinja2가 변수를 보간하도록 구성 할 수 있다면 후보가 될 수 있습니다.

실제로 루핑이 흥미로울 수 있습니다.

컨테이너를 시작하려는 고객 목록이 있다고 가정합니다.
고객 특정 변수를 환경에 넣는 곳입니다.

확장 / 상속은 현재를 향상시키는 데 흥미로울 수 있습니다.
기초적인 확장 메커니즘.

필터는 기존 변수로 작업을 수행하는 데 유용 할 수 있습니다.

2015 년 5 월 26 일 화요일 오후 1:56, Aanand Prasad [email protected]
썼다 :

Jinja2는 우리가 필요로하는 것보다 더 많이합니다.

  • 조건부
  • 루핑
  • 확장 / 상속
  • 코멘트
  • 필터

Compose에 해당 항목을 추가하지 않습니다. Jinja2를 구성 할 수있는 경우
변수를 보간하기 위해 후보가 될 수 있습니다.


이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment -105498909.

흥미로운 기능 일 수도 있지만 Compose와 파일 형식 모두에 대해 편하게 소개하는 것보다 훨씬 더 복잡하며 단일 구현으로 특정 템플릿 언어에 둘 다 묶을 것입니다. 사양이 없습니다. 단순히 실행 가능하지 않습니다.

@aanand 여기에 몇 가지 참고 사항 :

  1. Jinja2는 견고하며 YAML을 사전 처리하는 데 몇 분이 걸립니다.

jinja2 가져 오기 템플릿에서
template = Template ( 'Hello {{name}}!')
template.render (name = "Aanand")
안녕 Aanand!

보안을 강화하려면 변경 불가능한 샌드 박스를 사용할 수 있습니다.

jinja2.sandbox에서 ImmutableSandboxedEnvironment 가져 오기
env = ImmutableSandboxedEnvironment ()
template = env.from_string ( 'Hello {{name}}!')
template.render (name = "Aanand")
안녕 Aanand!

우리의 경우에는 다음과 같습니다.

수입 OS
jinja2.sandbox에서 ImmutableSandboxedEnvironment 가져 오기
env = ImmutableSandboxedEnvironment ()
template = env.from_string ( 'Hello {{name}}!')
template.render (** os.environ)

  1. 필터를 원하지 않습니까? 필터를 사용하면 기본값을 쉽게 정의 할 수 있습니다 ({{value | default ( "default")}})
  2. 확장 된 Jinja 기능을 사용하여 YAML 파일을 조이는 사용자를 정말로 신경 써야합니까? 같은 방식으로 사용자가 잘못된 YAML 파일을 수동으로 생성 할 수 있습니다. 단순하게 유지해야한다고 생각합니다. 주어진 Jinja 템플릿을 처리하고 오류가 있거나 생성 된 YAML이 유효하지 않은 경우 오류를 반환합니다 (지금과 동일).
  3. Jinja2가 해결책으로 보이지 않는다면 최소한 {{변수}}를 구문으로 사용하는 것이 좋습니다.
  4. Django는 regexp를 사용하여 템플릿을 구문 분석하고 생성합니다. 그것은 오랫동안 생산 등급이며 잘 살아 있습니다.

수입 OS
다시 가져 오기
template = "안녕하세요 {{name}}!"
re.sub ( "{{s _ ([a-zA-Z0-9 _] +?) s_}}", 람다 m : os.environ.get (m.group (1), ''), 템플릿)

어쨌든-어떤 솔루션을 사용하든이 기능을 롤링해야합니다.

템플릿을 고려하는 경우 일반적인 템플릿 솔루션을 사용하는 것에 +1합니다. 예 : 여러 언어로 제공되는 http://mustache.github.io . 이것은 단지 예일 뿐이며 다른 템플릿 엔진도 동일하게 고려할 수 있습니다.

@aanand 나는 당신의 요점을 완전히 이해합니다. 나는 또한 단순함과
compose dsl의 간결함.

메타 작곡가는 외부 프로젝트로 수행해야 할 수도 있습니다. 그것
compose.tpl.yml 및 variables.yml을 취하고 docker-compose.yml을 생성합니다.
그리고 우리는 간다.
@tonnzor가 보여준 것처럼 t는 작은 파이썬 코드로 할 수 있습니다.

이것은 그것을 필요로하는 사람들에게 강력한 템플릿을 제공 할 것입니다.
간단한 작업에 복잡성을 도입합니다.

2015 년 5 월 26 일 화요일 오후 4:52, Sebastiaan van Stijn <
[email protected]> 작성 :

템플릿이 있다면 _generic_ 템플릿 솔루션을 사용하는 것에 +1합니다.
깊이 생각한. 예 : http://mustache.github.io .
언어. 이것은 단지 예일 뿐이며 다른 템플릿 엔진은
동등하게 고려


이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment -105551631.

흠 ... 그래서는 제안 같은 것을 위해, (도커 용기를 구성을 설명하는 언어입니다)는 템플릿 언어 내부의 compose.yml를 사용하는 지금 commandentrypoint 이미 모두 동의하는 execsh -c 스타일 값? 템플릿 렌더링 후 결과 셸 명령이 여전히 해석 될 수 있기 때문에 혼란 스러울 수 있으므로 변수가 * 확장되면 추가로 glob 확장됩니다. 한 언어 또는 다른 언어로 시퀀스를 이스케이프하는 것은 이렇게 많은 폴 스루 해석 계층이있을 때 까다로워집니다.

@kojiromike 템플릿 엔진이 한다면 ! 잘 알려진 것을 사용하는 것이 좋습니다. 기본적인 질문은 다음과 같습니다. docker-compose가 처음부터 대체를 작성하거나 기존의 것을 사용해야합니다.

2015 년 5 월 26 일 화요일 오전 11:02 Christoph Witzany [email protected]
썼다 :

@aanand 나는 당신의 요점을 완전히 이해합니다. 나는 또한 단순함과
compose dsl의 간결함.

메타 작곡가는 외부 프로젝트로 수행해야 할 수도 있습니다. 그것
compose.tpl.yml 및 variables.yml을 취하고 docker-compose.yml을 생성합니다.
그리고 우리는 간다.

새로운 프로젝트없이 오늘 할 수 있습니다. 나는 진자가 될 수 있다고 확신합니다
어떻게 든 명령 줄에서 호출됩니다. 개인적으로 저는 envsubst를 사용합니다.
명령.

정말로 도움이되는 것은 compose가 stdin에서 파일을 읽을 수 있다면.
그러면 중간 파일이 필요하지 않습니다.

@tonnzor가 보여준 것처럼 t는 작은 파이썬 코드로 할 수 있습니다.

이것은 그것을 필요로하는 사람들에게 강력한 템플릿을 제공 할 것입니다.
간단한 작업에 복잡성을 도입합니다.

2015 년 5 월 26 일 화요일 오후 4:52, Sebastiaan van Stijn <
[email protected]> 작성 :

템플릿이 있다면 _generic_ 템플릿 솔루션을 사용하는 것에 +1합니다.
깊이 생각한. 예 : http://mustache.github.io.
언어. 이것은 단지 예일 뿐이며 다른 템플릿 엔진은
동등하게 고려

이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment-105551631.

이 이메일에 직접 답장하거나 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment-105554730. src = "
https://ci6.googleusercontent.com/proxy/iSBXyl7D8PwFM4p1mGPHCR7bQctunieGbhyGkvo0QIMIjmAYE3I0Mt96yl1fGrqcuOzxV4APP8ZRIw-5_qd6nzps9Mpr6jTAydCC4xs8JDgqm93aIbWvN1eMlxykrz7iwYooyAQdqL4RFJokeEbnBkZm5mhgKg=s0-d-e1-ft#https://github.com/notifications/beacon/AAGAUO8xqz29B2SUoG7QFPUy848_JJW9ks5oNIJlgaJpZM4EMysO.gif
">

+1은 stdin에서 파일을 읽습니다. 외부 템플릿 솔루션을 사용하는 데 문제가 없지만 중간 파일이없는 것이 좋습니다.

그것은 훌륭한 첫 번째 단계이며 많은 CLI 도구의 공통 기능처럼 들립니다. 그걸하자

: +1 :

예를 들어

envsubst compose.tmpl.yml | docker-compose -f - up -d

wfm. : +1 :

docker / distribution은 환경 변수를 통해 yml 파일의 재정의 값을 처리하지만 다른 접근 방식을 사용합니다 https://github.com/docker/distribution/blob/master/docs/configuration.md#override -configuration-options

^^ @aanand

@thaJeztah 도 우리를 위해 일할 것입니다. 환경 변수를 사용하여 명령을 재정의 할 수 있습니다.

DOCKER_COMPOSE_IMAGE_NAME='my_image:is_dynamic'

흥미로운 접근 방식이지만 저는 팬이 아닙니다. 자세한 환경 변수 이름, 여러 위치에서 하나의 값을 사용하려는 경우 많은 중복, 모든 것이 암시 적이며 문자열 내 보간이 없습니다.

@aanand 는 실제로 그 접근 방식을 판매하지는 않았지만 "Docker"조직 내의 또 다른 프로젝트이기 때문에 지적하고 싶었습니다.

관심이있을 수있는 https://github.com/kelseyhightower/confd에서 우연히 발견되었습니다. http://golang.org/pkg/text/template/#pkg -overview를 사용합니다.

@olalonde 불행히도 docker-compose는 Python으로 작성되었으므로 Go 템플릿이 작동하지 않습니다.

@aanand 저는 원래 제안에 +20이며 이미지와 특히 태그도 삽입 할 수 있어야합니다. 그냥 가십시오. 많은 래퍼와 불필요한 구성 처리를 절약 할 수 있습니다.)

저에게 도움이되는 작은 파이썬 패키지를 작성했습니다. 계획은 모든 명령을 docker compose로 터널링하여 동등하게 사용할 수 있도록하는 것입니다.
https://github.com/webcrofting/meta-compose/ 에서 확인

meta-compose는 정말 멋져 보입니다. docker-compose에 통합되어야합니다!

여기서 큰 +1-템플릿 전처리에 대해 흥분하지 않지만 환경 변수를 어떤 식 으로든 가져 오는 것이 좋습니다. POSIX 확장은 아마도 Jinja2보다 깨끗하지만 어느 쪽이든 괜찮습니다.

여기에서도 큰 +1. 내 사용 사례는 데이터 생산자 (다른 컨테이너 일 수 있음)에게 필수적인 kafka 컨테이너에 대한 동적 광고 ID 지원을 추가하는 것입니다.

이 기능에 대해서도 기대가됩니다.

POSIX 확장은 아마도 Jinja2보다 깨끗하지만 어느 쪽이든 괜찮습니다.

POSIX 확장에 찬성하는 또 다른 주장은 논리가 없다는 것입니다. Jinja2는 어느 정도의 조건부 / 루프 논리를 지원합니다 (대부분의 템플릿 엔진이 지원하는 것처럼 "논리적"이라고 주장하는 엔진도 마찬가지 임). 템플릿 논리와 YAML을 혼합하는 것은 내 경험에서 꽤 이상합니다. 누군가 그러한 논리에 대한 사용 사례를 생각할 수 있습니까? 그렇지 않은 경우 현재 지원을 특별히 피하는 것이 가장 좋습니다.

이 기능에 대해 개발자로부터 명확한 답변을받는 것이 좋을 것입니다. 다양한 이슈와 PR을 읽어 보면 실제로 구현하고 싶은지 아닌지는 확실하지 않습니다.

그렇다면 어떤 메커니즘으로? 그렇지 않으면 사람들이 기능을 관리하기 위해 타사 도구를 구축하기 시작할 수 있습니다.

감사합니다 !

연결된 문제 / PR에 대해 몇주기를 걸었습니다.

AFAIK, nginx 커뮤니티는 단순한 변수 대체를 위해 구성 파일에 대한 템플릿 엔진을 채택하는 것을 거부했습니다. 왜? 아마도 그들은 여전히 ​​이상적인 템플릿 엔진을 선택하고있을 것입니다 : smile :. 결과? (상대적으로) 고통!

@hadim

다양한 이슈와 PR을 읽어 보면 실제로 구현하고 싶은지 아닌지는 확실하지 않습니다.

이 문제는 그 질문에 대한 확실한 답을 제공하기로되어 있었기 때문에 명확하지 못해서 죄송합니다. 예, POSIX 스타일 구문으로 구현하고 싶습니다.

@aanand 감사합니다!

감사합니다, @aanand.

나를 위해 +1. --dns = (address of the docker0 bridge)를 전달해야하며, 이후 버전의 docker에서 변경 될 경우 작동해야하므로 환경 변수 및 / 또는 셸이 완벽합니다. meta-compose는 원격 DOCKER_HOST 및 예를 들어 로컬뿐만 아니라 docker-swarm을 통해 지원해야하기 때문에 나를 위해 작동하지 않습니다.

: +1 : 아주 좋을 것 같아요. 현재 나는 다른 스크립트를 통해 .yml 파일을 생성하거나 docker-compose를 모두 사용하지 않고 수동으로 Docker를 연결합니다.

: 좋아요 :

기본적인 환경 변수 보간은 간단한 일에 매우 유용 할 것이라고 생각합니다.

몇 가지 간단한 사용 사례 :

  • 원격 저장소에서 가져올 이미지의 태그를 동적으로 지정할 수 있습니다.
  • 컨테이너에 대한 포트 매핑을 설정할 수 있습니다.

Ansible과 같은 도구는 이미 템플릿을 매우 잘 수행하므로 전체 템플릿 엔진이 필요한지 잘 모르겠습니다. 그러나 comose.yml 파일에 동적 콘텐츠를 포함 할 수 없다는 것은 매우 제한적입니다.

병합 된 PR # 1488과 관련하여 특히 구성 파일을 docker-compose 에 파이프하는 데 관심이 있습니다. docker-compose 이 노드 프로세스에서 선택할 수없는 이유를 이해할 수 없습니다.

var spawn = require('child_process').spawn;

var compose = spawn('docker-compose', ['--file' + '-' + 'up']);

compose.stdin.setEncoding = 'utf-8';

compose.stdout.on('data', function (data) {
    console.log('"docker-compose --file - up" stdout: "%s".', data);
});

compose.stderr.on('data', function (data) {
    console.log('"docker-compose --file - up" returned an error: "%s".', data);
});

compose.on('close', function (code) {
    if (code !== 0) {
        console.log('"docker-compose --file - up" existed with an erroneous code: "%s".', code);
    } else {
        console.log('"docker-compose --file - up" existed with code: "%s". SUCCESS!', code);
    }
});

compose.stdin.write("redis: {\"image\": \"redis\"}\n");
compose.stdin.end();

Node.js에서 데이터를 파이프하는 방법에 대한 예가 있습니까?

내가 찾은 또 다른 한가지는 점이다 docker-compose 1.4.0-RC1이 같은 일부 겉으로는 정상적인 메시지를 보내는 Starting... 또는 Attaching...stderr 대신 stdout .

@kadishmal 이것들에 대해 별도의 문제를 열 ​​수 있습니까?

또 다른 후보 구문 / 구현 : PEP 0292에 지정되고 string.Template에 구현 된 Python의 문자열 템플릿.

POSIX 매개 변수 확장과 매우 ​​유사합니다.

  • $foofoo 의 값으로 확장됩니다.
  • ${foo}foo 의 값으로 확장됩니다.
  • $ , ${ , $} , ${} , ${foo , $ {foo} , ${ foo} , ${foo } 은 오류입니다.

단점 :

  • 기본값 또는 "필수 값"구문이 없습니다. 그래도 나중에 템플릿 코드를 작성하는 데 충분한 가치가 있는지 나중에 결정할 수 있습니다.
  • 오류 메시지는 구문 오류가있는 위치에 대한 기계 판독 가능 정보를 노출하지 않습니다 (오류 문자열에 대해 정규식 일치를 수행하지 않음).
  • 이스케이프 구문은 POSIX와 다릅니다 : $$ 대신 \$ .

이것은 실제로 위장의 축복 일 수 있습니다. YAML은 \$ 좋아하지 않으며 이중 탈출을 요구합니다. 나는 사람들에게 달러 기호를 얻기 위해 \\$ 를 입력하라고 말하는 것이 날아갈 것이라고 생각하지 않습니다.

# 1765에서 구현을 급증했습니다.

+1

이것이 적절한 장소인지, 아니면 새로운 문제를 만들어야하는지 잘 모르겠습니다.

env 우선 순위는 반대로해야한다고 생각합니다. 즉, docker-compose를 호출하는 셸의 변수가 docker-compose.yml 내의 모든 변수를 재정의해야하며, 차례로 컨테이너에 의해 정의 된 모든 변수를 재정의해야합니다.

현재 시도하면 다음과 같은 일이 발생합니다.

docker-compose.yml :

test:
    image: ubuntu
    environment:
        - FOO="from compose"

그런 다음 env 명령으로 실행합니다.

docker-compose run test env | grep FOO

예상대로 FOO="from compose" 제공합니다. 하지만:

FOO="from shell" docker-compose run test env | grep FOO

또한 FOO="from compose" 를 제공하지만 여기서는 FOO="from shell" 예상했습니다.

어떤 사람들은 여전히 ​​다른 사용 사례에 대해 변수 보간이 필요할 수 있지만이를 변경하면 "기본"사례가 충족됩니다. 실제로 docker-compose.yml의 environment: 정의 / 값이 기본값이며 재정의 할 수 있습니다. 추가 YAML 구문없이 필요한 경우 런타임에.

@fazy 당신은 env 명령이 FOO 의 값이 from compose 격리 된 test 컨테이너에서 실행되었다는 것을 고려하지 않았습니다 docker-compose 파일에 구성된대로). 그러나 해당 컨테이너 외부에서 docker-compose 프로세스가 명령 전에 설정 한 환경 변수에 대해 일종의 인쇄 기능을 가지고 있다면 '셸에서'를 인쇄했을 것이므로 호스트의 값이됩니다. 실행중인 docker-compose 프로세스). 이 경우 FOO 값이 from shell 가 될 것이라고 예상 하셨을 수도 있지만, 개인적으로 그럴 경우 상당히 놀랄 것입니다. (내 영어에도 불구하고 내 요점을 이해하기를 바랍니다.)

@smileart 감사합니다, 나는 당신이 말하는 것을

그러나 test 컨테이너는 완전히 격리되지 않았으며 docker-compose 에서 환경을 가져오고 (또는 최소한 docker-compose가 시작된 컨테이너에 환경 변수를 설정할 수 있음) docker-compose 자체적으로 "외부"환경 변수를 볼 수 있습니다.

이 docker-compose.yml로 볼 수 있습니다.

test:
    image: ubuntu
    environment:
        - FOO

그런 다음 명령 :

FOO="from shell" docker-compose run test env | grep FOO

실제로 "쉘에서"결과를 제공합니다.

그래서 제 질문은 우선 순위에 관한 것입니다. 여기에 변수 이름 - FOO 만 지정하면 외부에서 변수를 주입 할 수 있습니다. 하지만 - FOO=something _and_를 지정하면 외부에서 변수를 주입하는 것이 우선해야합니까? IMHO 명령 줄에 지정된 변수는 구성 파일보다 우선해야합니다.

@fazy 아, 죄송합니다. docker-compose.yml 값을 지정하지 않고 FOO="from shell" docker-compose run test env | grep FOO 을 (를) 시도한 적이 없으며 호스트의 FOO 값을 제공하는지 몰랐습니다. 그래서 그것은 저에게 이미 퀴어 일 뿐이 아닙니다. : smiley : docker-compose 전에 환경 변수를 설정하면 docker-composedocker-compose 에만 영향을 미칠 것이라고 생각했습니다. 컨테이너. 이제 무슨 뜻인지 알겠습니다.

방금 https://github.com/docker/compose/issues/1377#issuecomment -124571722에 언급 된 $ 이스케이프의 단점을 발견했습니다. 먼저 FOO=ba$e 다음 FOO='ba$e' ( "베어"라는 것을 잊어 버림), FOO=ba\$e , FOO=ba\\$e , 포기하고 갔다. " $$ "의 이스케이프 문자라는 사실에 놀랐습니다. 나에게 이것은 특별히 "최소한 놀라움"이 아니었다.

그러나 좋은 솔루션이 무엇인지 모르겠습니다.

@ ct-clearhaus Compose는 $ 이스케이프를 위해 $ 를 사용하는 유일한 프로그램이 아닙니다. makefile에서도 찾을 수 있습니다. 그래서 어떤 사람들에게는이 관용구가 아주 익숙합니다.

기존 변수 대체 구현이 마음에 듭니다. 그러나 @aanand 의 원래 제안에 따라 기본값을 설정하는 기능을 사용할 수 있습니다. POSIX 구문이 완벽하다고 생각합니다.

${ENV-default}

내 특정 용도는 서비스가 실행되는 호스트 포트를 지정할 수 있기를 원한다는 것입니다.

PORT=8123 docker-compose up

이것을 내 docker-compose.yml 추가하면 :

web:
  ports:
    - "${PORT-8000}:5000"

이 기능은 아직 계획이며 현재 진행 중입니까?

나는 extends로 내 문제를 해결하려고 시도했지만 꽤 지저분 해졌습니다. 하나의 설정을 변경하기 위해 거의 모든 docker-compose.yml 를 복제해야했을뿐만 아니라 노출 된 포트 설정을 _change_ 할 수있는 방법도 없습니다. 노출 된 포트 목록 만 add to 만 변경할 수 있습니다. 나에게 이상적이지 않습니다.

환경 변수가 설정되지 않은 경우 docker-compose가 실패하지 않는 이유는 무엇입니까? 경고 만 기록하고 계속됩니다. 반환과 오류가 더 나은 접근 방식이 아닙니다 ...
WARNING: The FOO variable is not set. Defaulting to a blank string.

기본값 선언을위한 POSIX 구문의 경우 +1

분명한 것이 누락되었을 수도 있지만 env_file의 환경 변수를 사용하여 환경 변수의 값을 설정할 수 있기를 원합니다. 예 :

docker-compose.env :

DB_PASSWORD=test

docker-compose.yaml :

...
service:
    database:
        env_file:
            - ./docker-compose.env
        environment:
            - MYSQL_PASSWORD=${DB_PASSWORD}
    webserver:
        env_file:
            - ./docker-compose.env
        environment:
            - WORDPRESS_DB_PASSWORD=${DB_PASSWORD}

다른 방법으로 수행 할 수 있습니까? envsubst를 통해 파이프되어야하는 yaml 템플릿 파일을 갖고 싶지 않습니다.

이 값을 원하는 방식으로 env_file 직접 입력하지 않으시겠습니까?

2636은 기본값에 대한 env 파일을 지원합니다.

즉, 두 위치에서 동일한 값이어야하는 변수가 있으면 하나만 변경하면 더 쉬워집니다. # 2636은 유망 해 보입니다.

기존의 제한으로 인해 도커 작성을 돕기 위해 래퍼 스크립트를 사용해야하므로 기본 변수를 지원하는 메커니즘이 절실히 필요합니다. 일하려면 NODE_ENV=${NODE_ENV:-dev} 같은 물건이 필요하고 편의상 SOME_NUMBER=$((96*60)) 가) 일하는 것이 좋습니다. 향후 버전이 예정되어 있습니까?

기본값은 +1

기본값은 +1입니다. 이것은 우리에게 중요 해지고 있습니다.

@ darkn3rd에 동의합니다-컨테이너에 설정하려면 사용자 ID와 사용자 그룹 ID를 얻어야합니다. 내가 찾은 유일한 방법은 팀이 2 개의 vars를 내보내도록 강요하거나 내가 만든 makefile을 사용하여 내보내는 것입니다.

내가 할 수만 있다면 :

    user: $((id -u)):$((id -g))

내 모든 문제를 해결할 것입니다.

@mgor 그냥 envsubst 통과 할 수있는 것 같나요?

env $(cat docker-compose.env | xargs) envsubst < docker-compose.tmpl > docker-compose.yml

(지속적인 환경을 오염시키지 않고)해야한다고 생각합니다.

@OJFord @mgor 스레드를 하이 envsetslv .

envset development -- slv docker-compose.tpl > docker-compose.yml

envset은 env 파일에서 현재 쉘 세션으로 변수를로드하고 slv는 환경 변수를 사용하여 템플릿을 대체합니다.

@OJFord에 동의하지만 그게 내가 필요한 것이 아닙니다 ...
정확히 말씀 드리겠습니다. 우리는 서로 다른 docker-compose 스택을 사용하는 40 명의 개발자로 구성된 팀입니다. 우리는 코드를 얻기 위해 git을 사용하고 있습니다.

내가 그들에게 우리 자식이 제공하는 docker-compose.yml을 수정하도록 요청하면 누군가 수정 된 docker-compose.yml 파일을 푸시 할 것이라고 확신합니다. 저를 믿으십시오.

git에 의해 무시되고 docker-compose.yml에 의해 확장되는 "기본 작성기 파일을 생성"할 수 있지만, 생성하려면 Makefile이나 bashscript를 제공해야합니다. "base docker file "변경이 필요하며 팀은 세대를 다시 실행해야한다는 사실을 인식하지 못합니다.

"env"파일과 동일합니다. 매우 훌륭하지만 "build"에서는 작동하지 않으므로 팀에이 파일을 생성하도록 요청해야합니다.

실제로 docker-compose가 yaml 파일의 bash (또는 ENV var이 아닌 다른 것을 반환하는 다른 솔루션)에서 값을 가져올 수 있다면 많은 요구를 해결할 것입니다.

이전 명령의 내 예제는 완벽한 것입니다. 사용자 ID와 gid를 가져와야하며 해당 값은 ENV 변수에 의해 설정되지 않습니다. 그래서 팀에게 .env 파일에 ID를 작성해달라고 요청해야합니다. 모두가 아닌 나와 여러분에게 간단합니다.

정확히 말하면 git 저장소에 있기 때문에 팀이 변경해서는 안되는 도커 작성 파일을 제공해야합니다.

이 풀 리퀘스트는 저에게 적합한 간단한 예입니다. 내가 더 잘할 수 있도록 도와 줄 수있을 것입니다.

docker-compose.yml 파일의 환경 및 사용자 지시문으로 시도했습니다. 지금은 잘 작동합니다.

기본값이 있어야합니다 ... 매우 유용합니다 ... 개발자와 OPS는 도커 로그 또는 syslog를 사용하고 있습니다 ... 따라서 일반적으로 아래에 표시된 기본 LOG_FORMAT 을 만들어야합니다 ... 우리는 기본값 만 가질 수 있습니다. syslog로 전환 할 때만 사용하십시오.

default:
  extends:
    file: base.yml
    service: base-${LOG_FORMAT:docker}
  labels:
    - "net.company.npmjs.datacenter=${DATA_CENTER}"
    - "net.company.npmjs.env=${ENV}"
    - "net.company.npmjs.hostname=${HOSTNAME}"
    - "net.company.npmjs.role=${NPMO_ROLE}"
    - "net.company.npmjs.log=${LOG_FORMAT}"

base-syslog:
  log_driver: syslog
  log_opt:
    tag: "{{.ImageName}}/{{.Name}}/{{.ID}}"

base-docker:
  log_driver: json-file
  log_opt:
    max-size: "128m"
    max-file: "4"

언제 사용할 수 있습니까? 나는 Compose 1.7.0에 있고 이것은 여전히 ​​거기에 없습니다 :(

기본값을 알려주십시오!

@marcellodesales : 아마도 docker-compose.override.yml 파일을 어떤 식 으로든 사용할 수 있습니다. 그 기능을 확인하십시오.

또한 환경 변수에 +1합니다. 오늘날 docker-compose의 주요 문제점입니다.

호스트로부터 특정 값을 얻을 수 있도록 PR # 3367을 고집합니다. :)

@pataquets 나는 아직 다른 오버라이드 파일을 만들고 싶지 않다고 생각합니다 ... 위와 같이 base.yml 파일은 로거 드라이버 등의 측면에서 지원되는 모든 항목을 보여줍니다. 기본값이 있습니다. 더 많은 yml 파일을 유지 관리해야한다고 생각합니다. 하지만 혹시라도 염두에 두겠습니다.

+1

+1

+1

+1

docker-compose에서 환경 변수 사용에 대한 알림이 있습니까?

+1

+1

참고 : docker-compose 용 환경 변수는 1.7.0부터 작동합니다. 루트 docker-compose.yml 파일과 동일한 디렉토리의 .env 에서 docker-compose 기본 변수를 설정할 수도 있습니다. Docker 엔진 환경 파일과 혼동해서는 안됩니다.

서비스 이름을 변수로 설정하는 방법이 있습니까?

이것을 쓰는 대신

services:
   site_db:
     image: mysql:5.7

우리는 쓸 수 있습니다

services:
   ${CONTAINER_NAME}:
     image: mysql:5.7

내 목표는 여러 사이트에서 동일한 docker-compose.yml 을 유지하고 .env 파일 만 변경하는 것입니다. 지금은 동일한 호스트에서 여러 앱을 실행하고 있으므로 컨테이너 이름을 수정해야합니다. 그리고 명확성을 위해 각 서비스에 고유 한 이름을 지정하고 싶습니다.

@LouWii 사용할 수 있습니다

services:
    site_db:
      container_name: "${CONTAINER_NAME}"
      image: mysql:5.7

또는 (작성 파일 형식 2.1 이상)

services:
    site_db:
      container_name: "${CONTAINER_NAME:-defaultname}"
      image: mysql:5.7

하지만 왜 프로젝트 이름을 설정하지 않습니까? 프로젝트 이름은 동일한 호스트의 다른 프로젝트와 충돌하지 않도록 생성 된 컨테이너 이름을 접두사 / 네임 스페이스로 지정하므로 _intended_입니다. https://docs.docker.com/compose/reference/envvars/#/composeprojectname 참조

@thaJeztah 감사합니다! 나는 여전히 Docker와 docker가 어떻게 작동하는지 배우고 있습니다. 프로젝트 이름을 설정하는 것이 더 나은 옵션 인 것 같습니다.

보간 된 중괄호 안에 스크립팅하는 방법이 있습니까? 예 : ${HOST_PORT + 1} .

Jinja 등을 통해 파일을 파이프 할 수 있습니다.

2017 년 1 월 24 일 화요일 오전 5:36 Sam A. Horvath-Hunt [email protected]
썼다 :

보간 된 중괄호 안에 스크립팅하는 방법이 있습니까? 예 : $ {HOST_PORT

  • 1}.


당신이 언급 되었기 때문에 이것을 받고 있습니다.
이 이메일에 직접 답장하고 GitHub에서 확인하세요.
https://github.com/docker/compose/issues/1377#issuecomment-274767368 ,
또는 스레드 음소거
https://github.com/notifications/unsubscribe-auth/AAGAUN5ZrU39dnVVVASwIHr5mGqJFxh3ks5rVdRIgaJpZM4EMysO
.

$ 에서 벗어날 수 있습니까?

environment:
   PATH: "$PATH:/home/appuser/.bundler/bin"

현재 이로 인해 컨테이너가 아닌 호스트의 PATH 변수가 보간됩니다.

docker-compose.yml 파일이 하나만 있습니까?
어떻게 추가하거나 수정할 수 있습니까?
미리 감사드립니다

@logicminds 어디에서도 문서화 된 것을 찾을 수는 없지만 $$ 이스케이프 된 $ 보간하는 것을 발견했습니다.

environment:
   PATH: "$$PATH:/home/appuser/.bundler/bin"

@elquimista 에는 유용한 솔루션이 있습니다 https://github.com/mhart/alpine-node/issues/48#issuecomment -430902787

이 페이지가 도움이 되었나요?
0 / 5 - 0 등급