首页 > 解决方案 > 带有打字稿的 Docker 卷

问题描述

我的 TS 应用程序有一个 dockerfile

FROM node:alpine
WORKDIR /usr
COPY package.json ./
COPY tsconfig.json ./
COPY src ./src
RUN ls -a
RUN npm install
EXPOSE 4005
CMD ["npm","run","dev"]

我可以用这个命令构建它

docker build -t ts-prisma . 像这样运行它 docker run -it -p 3000:4005 -v src-prisma:/usr/src ts-prisma

我想要实现的是为其附加一个卷,并且每次我在代码中更改某些内容时都会在 docker 中更改它。

我的意思是,我第一次构建我的应用程序时,我拥有这样的端点

app.get(
    "/",
    async (req: Request, res: Response): Promise<Response> => {
        return res.status(200).send({
            message: "Hello world!!!",
        });
    }
);

如果我卷曲到“http://localhost:3000”,它会向我发送正确的响应

{
   message: "Hello world!!!",
}

但是如果我为此改变它

app.get(
    "/",
    async (req: Request, res: Response): Promise<Response> => {
        return res.status(200).send({
            message: "This is a new message",
        });
    }
);

我仍然收到较旧的消息。

我使用 docker exec -it <id> /bin/sh index.ts 文件访问 docker 并执行 cat

并且仍然是它的第一个版本,没有任何改变。

我错过了什么?

我知道有一种方法可以用卷来做到这一点,但我想不通。

标签: docker

解决方案


假设您想在容器中严格运行节点以进行开发,那么您希望将源代码保留在主机驱动器上,并且根本不将其放在容器中。因此,不需要 Dockerfile 中的 COPY 语句。您实际上可能能够摆脱运行完全标准的节点映像。

请注意,我假设您的主机是 Linux 或 MacOS 机器。如果您在 Windows 上使用 WSL2,那么这样做会很困难(呃),因为 Windows 文件系统上的文件更改不会发送到 Linux 容器,因此当您对文件进行更改时,容器不会收到通知。

为了确保您安装了必要的软件包,我们可以运行

docker run --rm -v $(pwd):/src -w /src node:alpine npm install

这将在您的主机文件系统上安装您需要的软件包。

现在你可以开始你的开发环境了

docker run --rm -v $(pwd):/src -p 3000:4005 -w /src node:alpine npm run dev

现在您应该能够更改主机文件系统上的文件,并且您的容器应该会接收更改。

当您的应用程序完成并且您想要创建最终图像时,您可以使用像这样的 Dockerfile

FROM node:alpine
WORKDIR /src
COPY . ./
RUN npm install
EXPOSE 4005
CMD ["npm", "run", "production"]

该图像将包含您所有的源代码,因此一旦构建它,除非您再次构建它,否则对代码的任何更改都不会对其产生影响。

要构建它并运行它,你会做

docker build -t myimage .
docker run -p 3000:4005 myimage

推荐阅读