如何在Amazon Linux AMI的EC2实例中运行指定Docker镜像?
从你提供的日志来看,核心问题是容器启动时找不到/usr/src/app/public/index.html文件,导致React的react-scripts start命令执行失败。下面一步步帮你排查和解决:
第一步:确认镜像内是否真的缺失index.html
先运行以下命令检查镜像里的public目录内容:
docker run --rm grant/docker-app:hookedup ls -la /usr/src/app/public
如果输出里没有index.html,说明镜像本身构建时就没包含这个文件,这是根源问题。
情况1:镜像构建存在缺陷(最可能的原因)
如果你是自己构建并推送到Docker Hub的镜像,回到本地项目检查Dockerfile,确保有复制public目录的指令。例如,你的Dockerfile应该包含类似这样的代码:
# 基于Node镜像(根据你实际使用的版本调整) FROM node:16-alpine WORKDIR /usr/src/app # 先复制依赖文件,利用Docker缓存优化构建 COPY package*.json ./ RUN npm install --production # 关键:复制项目所有文件,包括public和src目录 COPY . . EXPOSE 3000 CMD ["npm", "start"]
如果之前的Dockerfile漏掉了COPY . .或者只复制了src目录,就会导致public/index.html缺失。
修复Dockerfile后,重新构建并推送镜像:
# 本地构建 docker-compose build # 推送到Docker Hub(确保你已经登录) docker push grant/docker-app:hookedup
然后回到EC2实例,重新拉取最新镜像:
docker pull grant/docker-app:hookedup
情况2:镜像内存在index.html,但启动时出现问题
如果第一步的命令显示index.html存在,那可能是工作目录或权限问题:
- 检查镜像的工作目录是否正确:
确保输出是docker inspect grant/docker-app:hookedup | grep WORKDIR"/usr/src/app",否则启动时npm会在错误的目录寻找文件。 - 尝试手动进入容器检查文件权限:
如果文件权限是只读或无法访问,可能需要在Dockerfile中添加权限设置,例如:docker run -it --rm grant/docker-app:hookedup sh # 进入容器后执行 ls -la /usr/src/app/public/index.htmlRUN chown -R node:node /usr/src/app USER node
关于Docker Compose的正确使用
你之前执行docker-compose build grant/docker-app:hookedup失败,是因为docker-compose build是用来构建本地Dockerfile定义的服务,而不是拉取的远程镜像。如果想用Docker Compose启动已有的镜像,需要先在EC2实例上创建docker-compose.yml文件,内容示例:
version: '3.8' services: react-app: image: grant/docker-app:hookedup ports: - "3000:3000" restart: unless-stopped # 可选:容器退出时自动重启
然后在该文件所在目录执行:
docker-compose up -d
这样就能后台启动服务了。
最后验证服务状态
修复后,用以下命令检查容器状态:
docker ps # 查看日志确认服务正常启动 docker logs <容器ID>
如果看到类似Compiled successfully!的日志,说明服务已经正常运行。
内容的提问来源于stack exchange,提问作者grabury

