这是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
无法正常工作,我必须手动将shell附加到容器上,然后自行运行。容器启动后启动npm run start
的正确方法是什么?
更新
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT ["node", "server.js"]
这项工作可以吗?
答案 0 :(得分:2)
最佳实践说,每个容器不应运行多个进程。除非您的应用程序是通过从唯一的 entrypoint 开始进行多次处理的方式制作的。
但是您可以使用一些解决方法。尝试检查以下问题:Docker multiple entrypoints
答案 1 :(得分:0)
已解决:
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;"
答案 2 :(得分:0)
您将构建时间(基本上是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 :(得分:0)