我有一個由以下 Dockerfile 創建的 docker 容器:
ARG TAG=latest
FROM continuumio/miniconda3:${TAG}
ARG GROUP_ID=1000
ARG USER_ID=1000
ARG ORG=my-org
ARG USERNAME=user
ARG REPO=none
ARG COMMIT=none
ARG BRANCH=none
ARG MAKEAPI=True
RUN addgroup --gid $GROUP_ID $USERNAME
RUN adduser --uid $USER_ID --disabled-password --gecos "" $USERNAME --ingroup $USERNAME
COPY . /api_maker
RUN /opt/conda/bin/pip install pyyaml psutil packaging
RUN apt install -y openssh-client git
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
ENV GIT_SSH_COMMAND="ssh -i /run/secrets/thekey"
RUN --mount=type=secret,id=thekey git clone [email protected]:$ORG/$REPO.git /repo
RUN /opt/conda/bin/python3 /api_maker/repo_setup.py $BRANCH $COMMIT
RUN /repo/root_script.sh
RUN chown -R $USERNAME:$USERNAME /api_maker
RUN chown -R $USERNAME:$USERNAME /repo
RUN mkdir -p /data
RUN chown -R $USERNAME:$USERNAME /data
RUN mkdir -p /working
RUN chown -R $USERNAME:$USERNAME /working
RUN mkdir -p /opt/conda/pkgs
RUN mkdir -p /opt/conda/envs
RUN chmod -R 777 /opt/conda
RUN touch /opt/conda/pkgs/urls.txt
USER $USERNAME
RUN /api_maker/user_env_setup.sh $MAKEAPI
CMD /repo/run_api.sh $@;
使用以下run_api.sh
腳本:
#!/bin/bash
cd /repo
PROCESSES=${1:-9}
LOCAL_DOCKER_PORT=${2:-7001}
exec /opt/conda/envs/environment/bin/gunicorn --bind 0.0.0.0:$LOCAL_DOCKER_PORT --workers=$PROCESSES restful_api:app
我的應用程式包含一些信號處理。如果我從容器內部手動發送SIGTERM
到(作業行程或父行程),我的信號處理作業正常。但是,當我在容器上gunicorn
運行時,它無法正常作業。docker stop
如何使我的 shell 腳本正確轉發它應該接收的 SIGTERM?
uj5u.com熱心網友回復:
您需要確保主容器行程是您的實際應用程式,而不是外殼包裝器。
正如您CMD
目前所擁有的那樣,shell 會呼叫它。引數串列$@
將始終為空。shell 決議/repo/run_api.sh
并看到它后面跟著一個分號,所以它可能需要做其他事情。因此,即使您的腳本正確地以exec gunicorn ...
直接將控制權移交給另一個行程結束,它仍然在外殼下運行,并且當您docker stop
使用容器時,它會轉到外殼包裝器。
避免這種 shell 的最簡單方法是使用exec 形式 CMD
:
CMD ["/repo/run_api.sh"]
這將導致您的腳本直接運行,而無需/bin/sh -c
包裝器呼叫它,并且當腳本最終exec
成為另一個行程時,該行程將成為主行程并接收docker stop
信號。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/478103.html