Search code examples
dockerdocker-compose

Source code is not getting updated with docker compose for development


I've 3 app in a single repo. For a project it's Api, Admin UI & Front-end. In all of those I'm facing the issue that the source code is not getting updated correctly. Following is the Dockerfile for Api

FROM golang:1.22.5-alpine3.20

WORKDIR /usr/src/app

COPY go.mod go.sum ./
RUN go mod download && go mod verify

COPY . .
RUN go build -v -o /usr/local/bin/app ./

EXPOSE 3000

CMD ["app"]

Following is docker-compose.yaml

services:
  db:
    image: mariadb:10.5.25
    restart: always
    # ...
  adminer:
    image: adminer
    restart: always
    # ...
  API: # Our focus is in here
    container_name: bjm_api
    build: ./api
    ports:
      - "3000:3000"
    develop:
      watch:
        - action: sync
          path: ./api
          target: /usr/src/app
    networks:
      - bjm_net
    volumes:
      - api_data_bjm:/app/logs
    env_file: ./api/.env
    depends_on:
      db:
        condition: service_healthy
  admin:
    container_name: bjm_admin
    build: ./admin
    ports:
      - "3001:3001"
    # ...
    depends_on:
      api:
        condition: service_started
  web:
    container_name: bjm_web
    build: ./web
    ports:
      - "3002:3002"
    # ...
    depends_on:
      api:
        condition: service_started

networks:
  bjm_net:
    name: bjm-net
volumes:
  db_data_bjm:
    driver: local
  api_data_bjm:
    driver: local

Then ran with docker compose up --watch

Steps to reproduce the issue

  1. After the above do change something in the (go file) code
  2. Notice that the thing is not updated in the output. But in terminal it shows that updated code is taken into container. Following is shown in terminal
bjm_api    | ➡ POST /v1/auth/sign-in - 400
           ⦿ Syncing "api" after changes were detected
           ⦿ Syncing "api" after changes were detected

I think the code was syncked but the executable is not being built. How to solve this?

My setup Docker version 27.1.1 Ubuntu 24.04


Solution

  • Go is a compiled language. Just mapping the original Go source code into the container doesn't do anything, because it doesn't get run. Instead, your Dockerfile produces the compiled app binary, and that's what gets run. When your source code changes, you need to rebuild the image (and with it the Go binary).

    The Compose watch block has a couple of different action values. You've set it to sync, which tries to copy files into the container. You actually need to set it to rebuild to get your Go application rebuilt.

    version: '4.x'  # develop: not in Compose file formats 2.x/3.x
    services:
      api:
        build: ./api
        ports:
          - "3000:3000"
        develop:
          watch:
            - action: rebuild  # <--- change this
              path: ./api
        volumes:
          - api_data_bjm:/app/logs
        env_file: ./api/.env
        depends_on:
          db:
            condition: service_healthy