我想要一个 Docker 容器,其中包含 Angular 应用程序的图像从内部提供服务。这样用户就可以方便地拉取镜像、运行应用程序并开始开发。
我当前的 Dockerfile 是:
FROM node:20.11.0-alpine
COPY . /ng17/
WORKDIR /ng17
RUN npm install -g @angular/cli
RUN npm install
CMD ["ng", "serve", "--host", "0.0.0.0"]
Docker 在 4201 端口上运行我的应用程序,一切正常。尽管如此,问题是代码并没有像我定期“ng services”而不使用 docker 那样实时编译。 我相信从容器内部“NG服务”可以解决这个问题。
我的 docker 流程是基本的:
docker build -t ng17:0.1 . ``docker run -d -p 4201:4200 ng17:0.1
我怀疑问题出在
CMD ["ng", "serve", "--host", "0.0.0.0"]
和 docker run -d -p 4201:4200 ng17:0.1
周围,但无法单独解决这个问题。我卑微的 Docker 经验告诉我与 exec
、bash
等相关的答案。
ps。我正在学习 Docker 的关键原理,特别是为了了解它在我的前端开发中有多方便。接下来我将使用 docker-compose,修复一些本地后端等。非常感谢本主题的任何策略、优缺点、设置和建议。
问题是代码没有被实时编译,就像我定期“ng服务”而不使用docker一样。这正是您当前工作流程中所期望的,因为您在
docker build
期间将文件复制到 Docker 映像一次,正好一行
COPY . /ng17/
我建议你使用构建简单的图像
FROM node:20.11.0-alpine
WORKDIR /work
RUN npm install -g @angular/cli
CMD npm install && ng serve --host 0.0.0.0
您只需要在构建期间安装 Angular CLI,其余的将在启动容器期间提供,因为您需要实时更新当然,要构建它,请使用您已有的相同命令:
docker build -t ng17:0.1 .
docker run --init --rm -t --net host -v $PWD:/work:rw -u $(id -u):$(id -g) ng17:0.1
-p 4201:4200
而不是使用端口映射 (
--net host
) 更简单,但这与偏好有关,两者都可以工作。
--rm
只是在容器退出时将其删除,因为不需要所有更改都使用
-v
进行安装,因此我们不关心容器内的其他更改,它会保持 docker 容器更干净(如果您输入
docker ps -a
) 如果不清理旧图像列表可能会很长并且会占用你的磁盘空间)
ng serve
正如我测试的,不能很好地使用 Ctrl+C 来停止它,快速修复它使用
--init
(它可以与任何未正确处理信号的应用程序一起使用)
-t
这将
tty
添加到正在运行的容器中,因此当
npm install
打包时你会看到进度,没有这个你可能会认为没有任何进展,因为进度条不会出现
-d
,就像在某个地方打开打开的控制台并查看日志一样,如果没有这个,当你的角度应用程序无法编译时,你必须使用
docker log $CONTAINER_NAME
来查看出了什么问题,这让生活变得更加困难。此外,当您完成工作后,只需在控制台中键入 Ctrl+C,容器就会退出,所有内容都会被清理
-v $PWD:/work:rw
它将把您当前的工作目录挂载到正在运行的容器中,这使得容器可以立即看到IDE中的更改,以便
ng serve
可以重新加载应用程序。我还添加了
:rw
,因为它对主机中的容器进行了更改,主要是因为当
npm install
安装软件包时,它们将持续容器重新启动
-u $(id -u):$(id -g)
,默认情况下大多数 Docker 镜像都以
root
的形式运行,但是当你的本地用户(在主机上)在 99% 的情况下是不同的,因此,最终会导致某些文件归你的本地用户所有,并且由
node_modules
休息(主要是
root
),这使得在必要时更难删除,因此在容器中强制使用与主机中使用的用户相同的用户
docker run
都可以更改为
docker-compose
,因此您将能够通过更短的命令来设置所有内容:
docker-compose up
version: '3.9'
services:
frontend:
build: .
init: true
tty: true
user: "${UID:-1000}:${GID:-1000}"
network_mode: host
volumes:
- $PWD:/work:rw
不幸的是,这个版本很难在容器内创建正确的用户ID,所以我将其默认为1000
,这在许多情况下都是正确的,您可以手动更改为正确的值或使用
docker-compose
启动
UID=$(id -u) GID=$(id -g) docker-compose up
注意:如果您有最新的 docker 版本,您可以使用 docker compose
而不是
docker-compose
命令(空格而不是破折号(
-
))