我试图做一个Dockerfile
和docker-compose.yml
的webapp
使用elasticsearch
。我已连接elasticsearch
到webapp
并将其公开给主机。但是,在webapp运行之前,我需要创建elasticsearch
索引并填充它们。我有2个脚本可以做到这一点,data_scripts/createElasticIndex.js
并且data_scripts/parseGenesToElastic.js
。我试图用添加这些到Dockerfile
CMD [ "node", "data_scripts/createElasticIndex.js"]
CMD [ "node", "data_scripts/parseGenesToElastic.js"]
CMD ["npm", "start"]
但运行后docker-compose up
,没有索引。elasticsearch
在运行Webapp之前如何填写?
Dockerfile的:
FROM node:11.9.0
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY package*.json ./
# Install any needed packages specified in requirements.txt
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
#
RUN npm build
RUN npm i natives
# Bundle app source
COPY . .
# Make port 80 available to the world outside this container
EXPOSE 80
# Run app.py when the container launches
CMD [ "node", "data_scripts/createElasticIndex.js"]
CMD [ "node", "data_scripts/parseGenesToElastic.js"]
CMD [ "node", "servers/PredictionServer.js"]
CMD [ "node", "--max-old-space-size=8192", "servers/PWAServerInMem.js"]
CMD ["npm", "start"]
docker-compose.yml:
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: webapp
ports:
- "1337:1337"
- "4000:85"
depends_on:
- redis
- elasticsearch
networks:
- redis
- elasticsearch
volumes:
- "/data:/data"
environment:
- "discovery.zen.ping.unicast.hosts=elasticsearch"
- ELASTICSEARCH_URL=http://elasticsearch:9200"
- ELASTICSEARCH_HOST=elasticsearch
redis:
image: redis
networks:
- redis
ports:
- "6379:6379"
expose:
- "6379"
elasticsearch:
image: elasticsearch:2.4
ports:
- 9200:9200
- 9300:9300
expose:
- "9200"
- "9300"
networks:
- elasticsearch
networks:
redis:
driver: bridge
elasticsearch:
driver: bridge
Docker容器只能运行一个命令。当您的Dockerfile有多行时CMD
,只有最后一行有效,其余的将被忽略。(ENTRYPOINT
这里只是用不同的方式来提供的单个命令;如果同时指定ENTRYPOINT
和CMD
,然后入口点成为主要过程和命令作为参数传递给它)
给定您显示的示例,我将分三个步骤运行它:
仅启动数据库
docker-compose up -d elasticsearch
运行“种子”作业。为了简单起见,我可能会在本地运行它们
ELASTICSEARCH_URL=http://localhost:9200 node data_scripts/createElasticIndex.js
(从直接在物理主机上运行的脚本的角度使用物理主机的名称,以及从容器中发布的端口),但如果您愿意,还可以通过Docker设置运行它们
docker-compose run web data_scripts/createElasticIndex.js
建立数据库后,启动整个应用程序
docker-compose up -d
这将使运行中的Elasticsearch不受影响,并启动其他容器。
如果您确定要在每个容器启动时都运行这些“种子”或迁移作业,那么另一种模式是编写一个入口点脚本。此处的基本模式是通过CMD
现有服务器启动服务器,但是编写一个脚本进行首次安装,最后exec "$@"
运行该命令,并使其成为容器ENTRYPOINT
。这看起来像
#!/bin/sh
# I am entrypoint.sh
# Stop immediately if any of these scripts fail
set -e
# Run the migration/seed jobs
node data_scripts/createElasticIndex.js
node data_scripts/parseGenesToElastic.js
# Run the CMD / `docker run ...` command
exec "$@"
# I am Dockerfile
FROM node:11.9.0
...
COPY entrypoint.sh ./ # if not already copied
RUN chmod +x entrypoint.sh # if not already executable
ENTRYPOINT ["/app/entrypoint.sh"]
CMD ["npm", "start"]
由于入口点脚本实际上只是一个shell脚本,因此您可以使用任意逻辑,例如仅基于命令运行种子作业,if [ "$1" == npm ]; then ... fi
而不能用于调试shell(docker run --rm -it myimage bash
)。
你Dockerfile也像你可能会试图启动三个不同的服务器(PredictionServer.js
,PWAServerInMem.js
,和任何npm start
启动); 您可以在同一图像的三个单独的容器中运行它们,并command:
在每个docker-compose.yml
块中指定。
docker-compose.yml
如果删除networks:
(除非对您来说至关重要的是,Elasticsearch和Redis不能互相交谈;通常不是这样)和expose:
声明(不起作用,尤其是在存在ports:
)对您来说会更简单。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句