watchexec / cargo-watch

Watches over your Cargo project's source.
Creative Commons Zero v1.0 Universal
2.78k stars 81 forks source link

Recompiling takes too long inside docker container #270

Open zavvdev opened 1 year ago

zavvdev commented 1 year ago

Hi! I'm playing with Rocket framework and created a monorepository with dockerized server service. I'm using cargo-watch for development mode and it works fine if I launching it locally. After saving source files it recompiles after ~0.68 seconds. But when I start server service inside docker container it takes too long. Near 2 minutes to restart. Screenshot 2023-05-21 at 7 35 31 PM

This is my docker-compose.yml file:

services:
  client:
    image: ${APP_NAME}_client
    build:
      context: ./client
    container_name: ${APP_NAME}_client
    command: pnpm prod
    restart: unless-stopped
    networks:
      - common

  server:
    image: ${APP_NAME}_server
    build:
      context: ./server
      dockerfile: ./Dockerfile
    container_name: ${APP_NAME}_server
    command: cargo build -r && ROCKET_ENV=production cargo run -r
    restart: unless-stopped
    networks:
      - common

  nginx:
    image: ${APP_NAME}_nginx
    build:
      context: ./nginx
    container_name: ${APP_NAME}_nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/nginx.conf
    depends_on:
      - server
      - client
    networks:
      - common

networks:
  common:
    name: ${APP_NAME}-network
    driver: bridge

docker-compose.dev.yml

version: "3.9"
services:
  client:
    command: pnpm dev
    stdin_open: true
    tty: true
    ports:
      - 3001:3000
    volumes:
      - ./client/src:/usr/src/app/src

  server:
    build:
      context: ./server
      dockerfile: ./Dockerfile.dev
    command: cargo watch -x run
    volumes:
      - ./server/src:/usr/src/app/src
      - ./server/target:/usr/src/app/target

  nginx:
    volumes:
      - ./nginx/nginx.dev.conf:/etc/nginx/conf.d/nginx.conf

And Dockerfile.dev:

FROM rust:1.67
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN cargo install cargo-watch
COPY . .

As you can see, I've added src and target folder into the container volumes. I'm not sure if it's an issue with cargo-watch but it's really not obvious why it behaves like this. It looks like on each save it ignores cache and compiling from scratch. But container contains target folder. Does anyone know what's wrong there? Is this a cargo-watch issue?

You can find full repo here: https://github.com/zavvdev/rocket-svelte-rest/tree/main

Thanks!

passcod commented 1 year ago

Fairly easy to determine if it's a cargo-watch issue or not:

# build image
local> $ cd server; docker build -f Dockerfile.dev server

# start docker manually into a shell
local> $ docker run -it --rm -v $(pwd)/server/src:/usr/src/app/src -v $(pwd)/server/target:/usr/src/app/target server bash

# do cargo run twice in the container
container> $ cargo run
[Finished in X]

container> $ cargo run
[Finished in Y]
passcod commented 1 year ago

At a guess, though, I would say it's probably to do with the cargo cache in ~/.cargo