【问题标题】:How to run command when container is started - Docker容器启动时如何运行命令 - Docker
【发布时间】:2019-05-21 07:22:23
【问题描述】:

这是 Dockerfile:

FROM nginx:stable-alpine

COPY ./mailservice /var/www/backend
COPY ./dist /usr/share/nginx/html
COPY ./docker/nginx_config/default.conf /etc/nginx/conf.d/default.conf
COPY ./docker/nginx_config/.htpasswd /etc/nginx

RUN chown -R nginx:nginx /usr/share/nginx/html/ \
    && chown -R nginx:nginx /etc/nginx/.htpasswd \
    && apk add --update nodejs nodejs-npm

WORKDIR /var/www/backend
RUN npm run start

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

但是我的RUN npm run start 不起作用,我必须手动将外壳附加到容器,然后自己运行它。容器启动后启动npm run start的正确方法是什么?

更新

CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["node", "server.js"]

这行得通吗?

【问题讨论】:

  • 正确的方法是使用ENTRYPOINTCMD,因为它们是在启动容器时使用的。 RUN用于在构建镜像阶段执行命令。
  • 您是指ENTRYPOINTCMD?举个例子好吗?
  • @tgogos,更新了我的问题,请纠正我。现在一切都坏了......仍然无法弄清楚。

标签: node.js docker npm


【解决方案1】:
  • 您当前的方法在设计上根本是错误的。
  • 您当前的做法是使用容器的明确反模式
  • 请为您的应用创建一个 Dockerfile
  • 请单独为nginx创建一个Dockerfile
  • 使用 docker-compose 构建堆栈,或者您可以按照自己的方式编写它
  • 始终在单独的容器上运行应用程序和代理

【讨论】:

    【解决方案2】:

    您将构建时间(基本上是 RUN 指令)与运行时间(ENTRYPOINT 或 CMD)混淆了,并且, 在那之后,你就打破了规则:一个容器,一个过程,即使这不是一个神圣的。

    我的建议是在此配置中使用 Supervisord

    [unix_http_server]
    file=/tmp/supervisor.sock                       ; path to your socket file
    
    [supervisord]
    logfile=/var/log/supervisord/supervisord.log    ; supervisord log file
    loglevel=error                                  ; info, debug, warn, trace
    pidfile=/var/run/supervisord.pid                ; pidfile location
    nodaemon=false                                  ; run supervisord as a daemon
    minfds=1024                                     ; number of startup file descriptors
    minprocs=200                                    ; number of process descriptors
    user=root                                       ; default user
    childlogdir=/var/log/supervisord/               ; where child log files will live
    
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
    [supervisorctl]
    serverurl=unix:///tmp/supervisor.sock         ; use a unix:// URL  for a unix socket
    
    [program:npm]
    command=npm run --prefix /path/to/app start
    stderr_logfile = /dev/stdout
    stdout_logfile = /dev/stderr
    
    [program:nginx]
    command=nginx -g "daemon off;"
    stderr_logfile = /dev/stdout
    stdout_logfile = /dev/stderr
    

    使用此配置,您会将日志重定向到标准输出,这是一个很好的选择 练习而不是容器内可能是短暂的文件,你也会有一个 PID 负责处理子进程并使用特定规则重新启动它们。

    您也可以尝试使用 bash 脚本来实现这一点,但可能会很棘手。

    另一个最佳解决方案应该是使用带有网络命名空间的分离容器,以便 将 NGINX 请求转发到上游的 NPM ......但如果没有 Kubernetes,它几乎不可能 维护,即使仅使用 Docker 也不是不可能的 :)

    【讨论】:

      【解决方案3】:

      最佳实践说您不应该在每个容器中运行多个进程。除非您的应用程序是从一个唯一的入口点启动多个进程的方式。

      但是您可以使用一些解决方法。试试看这个问题:Docker multiple entrypoints

      【讨论】:

        【解决方案4】:

        这样解决:

        Dockerfile

        FROM nginx:stable-alpine
        
        COPY ./mailservice /var/www/backend
        COPY ./dist /usr/share/nginx/html
        COPY ./docker/nginx_config/default.conf /etc/nginx/conf.d/default.conf
        COPY ./docker/nginx_config/.htpasswd /etc/nginx
        
        RUN chown -R nginx:nginx /usr/share/nginx/html/ \
            && chown -R nginx:nginx /etc/nginx/.htpasswd \
            && apk add --update nodejs nodejs-npm
        
        ADD ./docker/docker-entrypoint.sh /docker-entrypoint.sh
        RUN chmod 755 /docker-entrypoint.sh
        
        EXPOSE 80
        
        WORKDIR /
        
        CMD ["/docker-entrypoint.sh"]
        

        docker-entrypoint.sh

        #!/usr/bin/env sh
        
        exec node /var/www/backend/server.js > /var/log/node-server.log &
        exec /usr/sbin/nginx -g "daemon off;"
        

        【讨论】:

        • 如果您的 Node 后端因任何原因崩溃,Docker 不会注意到它; nginx 进程将继续运行并吐出 503 错误,直到操作员注意到并重新启动容器。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 1970-01-01
        • 1970-01-01
        • 2019-03-11
        • 1970-01-01
        • 2021-11-05
        • 1970-01-01
        相关资源
        最近更新 更多