如何在Docker Compose中自动更新共享卷内的静态内容?
The core issue here is that Docker volumes are designed to persist data across container rebuilds. When you mount a volume to your UI container's /app/build directory, any existing content in the volume takes precedence over the container's filesystem—so even if you rebuild the UI image, the old static files in the volume remain unless explicitly overwritten.
Here's how to fix this so your static content updates automatically with every docker-compose up --build:
1. Adjust the UI Service Command
Modify your docker-compose.yml UI service to run a script that first rebuilds the static files (using your latest local code) and then starts your application (if you need a dev server). This ensures the volume gets fresh content every time the container starts:
ui: tty: true stdin_open: true environment: - CHOKIDAR_USEPOLLING=true build: context: ./ui/ dockerfile: Dockerfile volumes: - /app/node_modules - ./ui:/app - static:/app/build # Add this command to rebuild static files on container start command: sh -c "rm -rf /app/build && npm run build && npm start"
What this does:
rm -rf /app/build: Cleans out any old static files from the volume mount pointnpm run build: Rebuilds the static files using your latest local code (from the bind mount)npm start: Starts your dev server (adjust this to match your project's dev command if needed)
2. Simplify the UI Dockerfile (Optional but Recommended)
Since you're using a bind mount (./ui:/app) to sync local code with the container, the build steps in your Dockerfile are redundant. You can simplify it to just install dependencies:
FROM node:alpine WORKDIR /app COPY ./package.json ./ RUN npm i # Default command can be your dev server; we'll override it in docker-compose for builds CMD ["npm", "start"]
Alternative Production-Focused Approach
If you're using this setup for production (not development), a cleaner solution is to build the static files directly into your Nginx image instead of using a shared volume. This eliminates the volume persistence issue entirely:
Update your Nginx Dockerfile:
FROM nginx:alpine # Copy static files from the UI build stage COPY --from=ui-build /app/build /usr/share/nginx/html COPY ./prod.conf /etc/nginx/conf.d/default.conf
Update docker-compose.yml to use a build init container:
version: "3" services: nginx: depends_on: - backend - ui-build restart: always build: context: ./nginx/ dockerfile: Dockerfile ports: - "80:80" backend: # ... keep your existing backend config ui-build: build: context: ./ui/ dockerfile: Dockerfile # This container runs once to build static files, then exits command: npm run build postgres: # ... keep your existing postgres config # Remove the static volume since we're building directly into Nginx
This way, every time you run docker-compose up --build, the UI is rebuilt, and Nginx gets the latest static files directly from the UI build image.
内容的提问来源于stack exchange,提问作者Gracie williams

