불로장생약, 방출품, Docker
나는 처음부터 몇 가지 일을 분명히 하고 싶다.이 분야에는 많은 선택/해결 방안이 있다. 내가 가장 좋은 것을 말하는 것이 아니라, 더 나쁜 것을 말하는 것이 아니다. 나는 전문가도 아니지만, 내가 연구 과정에서 겪은 문제를 소개하고 싶다.이렇게 하면 아마도 다른 사람을 도울 수 있을 것이다.
my Github 에서 모든 코드를 찾을 수 있습니다.
왜 Docker는 불로장생약을 써야 합니까?
네, 우선 생산 버전을 만듭시다.우리는 어떤 환경에서 진행할 수 있습니까?
우리가 주의해야 할 것은 Elixir release의 결과는 응용 프로그램과 실행할 때의 단일 단원이지만, 자기 제어에 있어서는 제한을 받는다는 것이다. 그것은 구축 시스템과 충분히 비슷한 시스템에서만 실행될 수 있다는 것이다.
응, 그래서 만약 내가 맥OS에 Elixir 프로그램을 발표한다면, 리눅스에서 실행되지 않을 수도 있어.또는, 리눅스 버전에서 발표되었음에도 불구하고, Glibc 라이브러리는 대상 리눅스와 다르기 때문에, 이 프로그램은 붕괴되거나 실행할 수 없습니다.
어떻게 이 문제를 해결합니까?답은 부두화(컨테이너)에 있다.이것은 대상 용기와 같은 docker 이미지를 기반으로 프로그램이 생산에서 실행될 수 있도록 docker 용기에 Elixir 프로그램을 발표하는 첫 번째 목표를 설정합니다.
기본 이미지로 Alpine Elixir를 선택했습니다.Erlang/Elixir 환경의 전체 설치 및 Alpine Linux 구축
이제 첫 번째 행을 추가하여 Dockerfile을 작성합니다.
# Dockerfile
FROM bitwalker/alpine-elixir:latest AS release_stage
우리가 우리의 이미지를 정의하는 것은 알프스의 불로장생약에 근거할 것이다.multi-stage build를 사용하기 때문에 이 단계를release stage라고 명명합니다.이렇게 하면 응용 프로그램을 게시하고 실행하는 데 사용되는 Dockerfile이 유지됩니다.이거 놔.
Elixir 응용 프로그램을 게시하는 것은 mix-release 명령을 실행하는 것처럼 간단합니다. 모든 코드와 런타임(Erlang VM)을 미리 컴파일하여 패키지화한 다음 프로덕션 또는 유사한 환경에서 응용 프로그램을 실행할 수 있습니다.《장생불로약》의 이야기 뒤에는 많은 것들이 있는데, 나는 단지 두 가지를 강조하고 싶다.
모든 Elixir 모듈을 미리 불러오면 첫 번째 요청의 최고치가 제거됩니다.
런타임 프로비저닝은 응용 프로그램을 다시 시작할 때마다 다른 프로비저닝을 정의할 수 있으며, 응용 프로그램을 다시 컴파일(다시 게시)할 필요가 없습니다.우리는 나중에 다시 사용할 계획이다!
MIX_ENV=prod mix release
먼저 MIX ENV 변수를 prod로 설정하여 프로덕션 구성을 적용합니다(파일 config/prod.exs).구체적으로 말하면 우리는 기호화폐를 생산하는 기한이 개발 기호화폐보다 짧기를 희망하기 때문에 다음과 같은 조치를 취한다.import Config
config :jwt_example,
jwt_expiration_time_minutes: 15
좋아.게시 프로세스가 실행되고 폴더 build/prod/rel/jwt example에 모든 가공소재가 구축되어 저장되므로 다음 명령을 실행하여 응용 프로그램을 쉽게 실행할 수 있습니다._build/prod/rel/jwt_example/bin/jwt_example start
용기 내부에서 이 점을 실현하기 위해서, 우리는 적합한 도커 이미지를 준비해야 한다.우리 뭐가 필요해?출시 단계
Elixir 버전을 실행하려면 모든 소스 코드, 종속성 및 구성이 필요합니다.먼저 docker 이미지의 프로젝트 의존 항목을 가져오고, docker 파일에 다음 줄을 추가해서 구축합니다.
COPY mix.exs .
COPY mix.lock .
RUN mix deps.get
RUN mix deps.compile
Dockerfile의 각 명령은 이미지에 레이어를 추가하고 레이어를 캐시하므로 이미지를 재구성할 때 특정 레이어에 변화가 없으면 레이어가 호출되지 않습니다. 예를 들어,...
Step 5/10 : COPY mix.lock .
---> Using cache
---> 9d7f3925326c
Step 6/10 : RUN mix deps.get
---> Using cache
---> 79bae808d41c
Step 7/10 : RUN mix deps.compile
---> Using cache
---> 96c1e1d63927
Step 8/10 : COPY config ./config
---> efba111358c3
Step 9/10 : COPY lib ./lib
---> 04b6c23bdefb
Step 10/10 : COPY test ./test
---> b4f648c97967
그림을 만들 때 캐시된 층을 출력에서 볼 수 있습니다.이것은 우리에게 변경 확률이 낮은 일을 첫째로 하고 원본 코드 복제 등을 마지막으로 하는 이유를 주었다.
이제 구성 및 소스를 복제한 다음 버전 실행을 정의합니다.
COPY config ./config
COPY lib ./lib
COPY test ./test
ENV MIX_ENV=prod
RUN mix release
JWS 기밀, 버전 1
h256 서명의 비밀은 무엇입니까?이전 글에서 말한 바와 같이, 우리는 hs256 signature 키라는 파일에 기밀을 저장하는 해결 방안을 사용했다.컴파일할 때 기밀 파일을 읽고 응용 프로그램 환경에 기밀을 저장합니다.
#config/config.exs:
config :jwt_example,
jwt_secret_hs256_signature: Secret.get("hs256-signature-key", "default secret string")
만약 우리가 같은 방법을 유지하고 싶다면, 발행판을 실행하는 동시에, 컴파일할 때 도커 이미지 자체에 생산 기밀을 가져와야 한다.따라서 게시 관리자가 보안 위치(예:/etc/elixir/production/hs256 서명 키)에 저장된 프로덕션 기밀 파일에 대한 액세스 권한을 가지고 있고 docker 이미지를 준비하고 있다고 가정합니다.
docker build --build-arg SECRET="$(cat /etc/elixir/hs256-signature-key)" —build-arg SECRET_FILE="hs256-signature-key" -t t3 .
위의 docker build 명령에는ARG SECRET
ARG SECRET_FILE
RUN mkdir $HOME/secrets
RUN echo "$SECRET" > $HOME/secrets/$SECRET_FILE
RUN chown -R default $HOME/secrets
위의 몇 줄은 비밀 폴더를 만들고build 매개 변수의 비밀을 저장합니다. 그리고 믹스-release가 컴파일할 때 파일을 읽을 수 있는 권한을 설정합니다.면책 성명:
구축 시 매개 변수를 사용하여 기밀을 전달하는 것을 권장하지 않습니다.비록 우리가 마지막에 비밀 파일을 삭제했다 하더라도, docker history 명령을 실행할 때, 비밀을 볼 수 있다.이런 상황을 피할 수 있는 몇 가지 옵션이 있습니다. (검사 Access Private Repositories from Your Dockerfile Without Leaving Behind Your SSH Keys 하지만, 우리는 잠시 후에 다른 방법으로 전환할 것입니다.
거의 다 왔다
지금까지 우리는 다단계 이미지의 구축 단계를 준비했다.남은 것은 달리기 단계다.Erlang이 실행될 때만 '더 얇다' 는 이미지를 찍을 수 있지만, 같은 알프스의 불로장생약 이미지를 기반으로 할 것이다.Dockerfile에 행을 추가하려면 다음과 같이 하십시오.
FROM bitwalker/alpine-elixir:latest AS run_stage
COPY --from=release_stage $HOME/_build .
RUN chown -R default: ./prod
USER default
CMD ["./prod/rel/jwt_example/bin/jwt_example", "start"]
이전 단계에서 발표된 프로그램을 복사해서 기본 사용자에서 실행합니다.이렇게!이제 Dockerfile이 완료되었으므로 이미지를 구성할 수 있습니다.docker build --build-arg SECRET="$(cat /etc/elixir/hs256-signature-key)" --build-arg SECRET_FILE="hs256-signature-key" -t jwt_example .
그리고 용기를 실행하고 4001의 포트를 노출합니다. 저희 cowboy 서버가 이 포트를 감청하고 있습니다.docker run --name c_jwt_example -d --publish 4001:4001 jwt_example:latest
하면, 만약, 만약...docker ps -a
우리는 우리의 용기가 작동하고 운행하는 것을 볼 것이다.REST 호출을 실행하고 컨테이너 로그(응용 프로그램을 실행하는 stdout, stderr)를 확인합니다.
docker logs c_jwt_example —follow
다음과 같은 출력을 볼 수 있습니다.##### 16:13:20.485 application=jwt_example domain=elixir file=lib/jwt_example/application.ex function=start/2 line=6 mfa=JwtExample.Application.start/2 module=JwtExample.Application pid=<0.2056.0> [info] Starting application..
##### 12:34:18.531 application=plug domain=elixir file=lib/plug/logger.ex function=call/2 line=27 mfa=Plug.Logger.call/2 module=Plug.Logger pid=<0.2163.0> [debug] POST /login
##### 12:34:18.535 application=plug domain=elixir file=lib/plug/logger.ex function=call/2 line=34 mfa=Plug.Logger.call/2 module=Plug.Logger pid=<0.2163.0> [debug] Sent 200 in 4ms
보시다시피 프로그램이 시작되고 요청을 제공합니다.docker 매개 변수의 의미는 official docker documentation를 볼 수 있습니다.
네가 떠나기 전에
앞서 언급한 바와 같이, Elixir 발행판은 우리가 실행할 때 설정을 사용할 수 있도록 해 줍니다. 우리는 실행할 때 JWS 기밀을 설정할 수 있으며, 컴파일할 때가 아니라 실행할 때 JWS 기밀을 설정할 수 있습니다.
config/releases를 만듭니다.exs 파일 및 다음 행을 추가합니다.
import Config
config :jwt_example,
cowboy_port: String.to_integer(System.fetch_env!("COWBOY_PORT")),
jwt_secret_hs256_signature: System.fetch_env!("HS256_SIGNATURE_KEY")
보시다시피 저희도 실행할 때 데님 포트를 설치했습니다.작은 디테일, 시스템에 주의하세요.fetch env/1 함수는 항상 문자열을 되돌려주기 때문에 정수 값을 변환해야 합니다.
이것은 이 설정 파일의 변경 사항을 적용하기 위해 프로그램을 다시 컴파일할 필요가 없다는 것을 의미합니다. 용기를 다시 시작하기만 하면 새로운 설정이 고려됩니다.
상기 상황에 대해, 우리는 용기를 실행할 때port와secret을 환경 변수로 설정할 것입니다.또한 JWS 시크릿에 대한 구축 매개 변수를 제거할 수 있으므로 최종 Dockerfile은 다음과 같습니다.
FROM bitwalker/alpine-elixir:latest AS release_stage
COPY mix.exs .
COPY mix.lock .
RUN mix deps.get
RUN mix deps.compile
COPY config ./config
COPY lib ./lib
COPY test ./test
ENV MIX_ENV=prod
RUN mix release
FROM bitwalker/alpine-elixir:latest AS run_stage
COPY --from=release_stage $HOME/_build .
RUN chown -R default: ./prod
USER default
CMD ["./prod/rel/jwt_example/bin/jwt_example", "start"]
그리고 이미지 구축을 이렇게 호출합니다. (비밀 파라미터가 필요하지 않습니다.)docker build -t jwt_example .
원하는 환경 변수를 사용하여 컨테이너를 실행합니다.docker run --name c_jwt_example -d --publish is 8002:8002 -e COWBOY_PORT="8002" -e HS256_SIGNATURE_KEY="$(cat /etc/elixir/hs256-signature-key)" jwt_example:latest
아주 단도직입적이잖아!즐거운 코딩!
Reference
이 문제에 관하여(불로장생약, 방출품, Docker), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/mpevec9/elixir-releases-and-docker-2o47텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)