File not being copied over correctly from host to container on build (even with --no-cache flag)

I have a Flask app that is part of a larger group of containers, all deployed via docker swarm. I recently began having issues where I change the startup script (boot.sh) but those changes are not reflected when I re-build the containers and bring up the swarm. I’m trying to understand exactly why that would happen and what I can do to fix it. I am confident I can fix the issues with the app itself once I understand why this file is not being copied over with the changes I made.

Essentially, I’ve tried adding/removing debugging statements from the boot.sh script to just make sure it is actually changing and it appears it is NOT and I’m not clear why. I’ve tried building with docker-compose build --no-cache as well as completely removing all containers and re-building from scratch, and nothing seems to change. I still see the same old echo statements that were in the first version. I’ve also tried changing the filename thinking that would force it to re-build from scratch, but no dice. It seems like I’m misunderstanding something fundamental about how docker images are built and how the cache works. I would love to know why this happens and how I can fix it!

The structure of the app is as follows:

Folder/App Structure

app/
conf/
tests/
migrations/
.dockerignore
.gitignore
boot.sh
config.py
docker-compose.yml
docker-compose.override.yml
Dockerfile
manage.py
requirements.txt

The Dockerfile looks like:

Dockerfile

FROM python:3.6-slim-stretch
LABEL maintainer="<maintainer-here>"

RUN useradd -m <name-repl> -s /bin/bash
WORKDIR /home/<folder-here>

COPY requirements.txt poetry-reqs.txt
RUN python -m venv venv

RUN apt-get update -yq && apt-get upgrade -yq && \
    apt-get install -yq curl libpq-dev libffi-dev tzdata gnupg build-essential supervisor && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

# replace with v12?
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash && apt-get install -yq nodejs

RUN pip install --upgrade pip
RUN venv/bin/pip install gunicorn --no-cache-dir --compile
RUN venv/bin/pip install psycopg2-binary --no-cache-dir --compile
RUN venv/bin/pip install -r poetry-reqs.txt --no-cache-dir --compile

ADD package.json /tmp
RUN cd /tmp && npm install

RUN mv /tmp/node_modules /home/<folder-here>/node_modules

RUN cd /home/<folder-here>

COPY app app
COPY migrations migrations
COPY manage.py config.py boot.sh boot-workers.sh pyproject.toml ./
RUN chmod +x boot.sh 
RUN chmod +x boot-workers.sh

# this layer adds 0.541GB!!
RUN chown -R quantaq:quantaq ./
USER <user-repl>

EXPOSE 5000
ENTRYPOINT ["./boot.sh"]

docker-compose.yml

version: "3.3"

services:
  app-primary:
    image: <image-name>

  reverse-proxy:
    <redacted>

  redis_db:
    <redacted>

volumes:
  redis-data:


docker-compose.override.yml

version: "3.3"

services:
  app-primary:
    image: <image name>
    build: .
    env_file: conf/dev/app.env
    ports:
      - "8000:8000"
    depends_on:
      - postgres-primary
      - redis_db

configs:
  nginx_conf:
    file: ./conf/dev/nginx.conf
  redis_conf:
    file: ./conf/dev/redis.conf
  supervisor_conf:
    file: ./conf/dev/supervisor.conf

volumes:
  db:

I removed/left-out a few things that I don’t think we’re relevant for succinctness. I can add back if needed.

Other Important Info

  • Docker version 2.3.0.3
  • Compose: 1.25.5
  • Engine: 19.03.8

Docker Info

Client:
 Debug Mode: false
 Plugins:
  app: Docker Application (Docker Inc., v0.8.0)
  buildx: Build with BuildKit (Docker Inc., v0.3.1-tp-docker)
  mutagen: Synchronize files with Docker Desktop (Docker Inc., testing)

Server:
 Containers: 16
  Running: 6
  Paused: 0
  Stopped: 10
 Images: 79
 Server Version: 19.03.8
 Storage Driver: overlay2
  Backing Filesystem: <unknown>
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: active
  NodeID: ryd06ymf1dosx7mi7530u4efs
  Is Manager: true
  ClusterID: 7225atxknsy5w3kh9i5uc786p
  Managers: 1
  Nodes: 1
  Default Address Pool: 10.0.0.0/8  
  SubnetSize: 24
  Data Path Port: 4789
  Orchestration:
   Task History Retention Limit: 5
  Raft:
   Snapshot Interval: 10000
   Number of Old Snapshots to Retain: 0
   Heartbeat Tick: 1
   Election Tick: 10
  Dispatcher:
   Heartbeat Period: 5 seconds
  CA Configuration:
   Expiry Duration: 3 months
   Force Rotate: 0
  Autolock Managers: false
  Root Rotation In Progress: false
  Node Address: 192.168.65.3
  Manager Addresses:
   192.168.65.3:2377
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
 init version: fec3683
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.19.76-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 5.811GiB
 Name: docker-desktop
 ID: 6SU5:FS3A:BRBI:SPGE:5FMQ:FIHD:TGNI:M3R4:POXS:ECTM:BUJS:DEX7
 Docker Root Dir: /var/lib/docker
 Debug Mode: true
  File Descriptors: 128
  Goroutines: 268
  System Time: 2020-05-28T19:56:02.871137Z
  EventsListeners: 15
 HTTP Proxy: gateway.docker.internal:3128
 HTTPS Proxy: gateway.docker.internal:3129
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: true
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine``