我正在尝试将网站的前端容器化并自动进行部署。我的目标是能够在推送更改时生成并托管一个新映像,并让服务器自动获取它并重新启动容器。这是我要采取的步骤:
我首先通过构建Node应用程序,然后将发行版和nginx配置文件捆绑到最新的linuxserver/letsencrypt映像中来创建映像。这是Dockerfile:
# Use the NodeJS image as builder
FROM node:alpine AS builder
# Create the workspace
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Copy the package file and source code
COPY package.json /usr/src/app
COPY . ./
# Install dependencies
RUN npm install
# Build the application
RUN npm run build
# The nginx server, this builds the final image
FROM linuxserver/letsencrypt
# Copy the nginx configuration
COPY ./config/nginx.conf /config
# Copy the output of the builder
COPY --from=builder /usr/src/app/dist /config/www
# Inform Docker to listen on port 443 and 80
EXPOSE 443 80
此图像已上传到GitHub's package registry,我使用Watchtower轮询更新。
使用此docker-compose文件启动图像:
version: "3"
services:
...
frontend:
image: [IMAGE]
container_name: frontend
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=[TIMEZONE]
- URL=[URL]
- SUBDOMAINS=www,
- VALIDATION=http
ports:
- 443:443
- 80:80
volumes:
- ./frontend:/config
restart: unless-stopped
...
问题是,当我在docker-compose中使用以下行时,使用COPY
指令打包到映像中的文件将被覆盖:
volumes:
- ./frontend:/config
如果我从docker-compose文件中删除该部分,则一切正常,但是这不是解决方案,因为该文件夹存储了重要数据。
我已经读到,装入卷会完全覆盖以前的所有数据,但是我喜欢这样的事实,即我可以轻松地将映像加载到服务器上并已嵌入所有必需的文件。有什么我可以解决的问题,还是我滥用/误解了Docker映像?
我尝试按照建议的here将卷设置为只读,但是这没有用,而是导致映像不断停止并重新启动。
我还简要了解了bind mounts,并想知道它们是否会有用。
答案 0 :(得分:1)
此行为是预期的。 Docker挂载的工作方式与Linux挂载相同,即用源目录的内容覆盖目标目录的内容。
我的建议是为卷使用另一个目标目录,例如
volumes:
- ./frontend:/someotherdir
然后调整您的nginx配置以在其中查找JS文件。
答案 1 :(得分:0)
我发现我可以通过首先创建一个named volume来保留图像中的数据:
volumes:
frontend_data:
然后将容器安装到该体积:
services:
frontend:
...
volumes:
- frontend_data:/config
...