<p>I'm trying to understand why sometimes I update a <code>.php</code> in my project it completely rebuilds the image everytime and other times it doesn't seem to do anything. Actually regarding the latter it says <code>Syncing 1 files for ...</code>, but none of my changes are reflected.</p>

<p>This is my project structure:</p>

<pre><code>/app
  /admin
    /conf
      app.conf
    /src
      /lib
        lib.php
      index.php
    Dockerfile.dev
  /manifests
    /dev
      ingress.yaml
      admin.yaml
  skaffold.yaml
</code></pre>

<p>When I make changes to <code>./admin/conf/app.conf</code> or <code>./admin/src/index.php</code>, I just get the <code>Syncing 1 files for...</code>, but none of the changes are reflected in the application. I have to <code>CTRL+C</code> to kill Skaffold and restart it... just <code>CTRL+S</code> in a <code>.yaml</code> or <code>lib.php</code> to trigger a rebuild.</p>

<p>When I make changes to <code>./admin/src/lib/lib.php</code>, it rebuilds the entire image from scratch.</p>

<p>Here are my configs:</p>

<pre><code># skaffold.yaml

apiVersion: skaffold/v1beta15
kind: Config
build:
  local:
    push: false
  artifacts:
    - image: postgres
      context: postgres
      docker:
        dockerfile: Dockerfile.dev
      sync:
        manual:
          - src: "***/*.sql"
            dest: .
    - image: testappacr.azurecr.io/test-app-admin
      context: admin
      docker:
        dockerfile: Dockerfile.dev
      sync:
        manual:
          - src: "***/*.php"
            dest: .
          - src: "***/*.conf"
            dest: .
          - src: "***/*.tbs"
            dest: .
          - src: "***/*.css"
            dest: .
          - src: "***/*.js"
            dest: .
deploy:
  kubectl:
    manifests:
      - manifests/dev/ingress.yaml 
      - manifests/dev/postgres.yaml
      - manifests/dev/admin.yaml
</code></pre>

<pre><code># Dockerfile.dev

FROM php:7.3-fpm
EXPOSE 4000
COPY . /app
WORKDIR /app/src
RUN apt-get update \ 
    &amp;&amp; apt-get install -y libpq-dev zlib1g-dev libzip-dev \
    &amp;&amp; docker-php-ext-install pgsql zip
CMD ["php", "-S", "0.0.0.0:4000"]
</code></pre>

<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: admin-deployment-dev
spec:
  replicas: 1
  selector:
    matchLabels:
      component: admin
  template:
    metadata:
      labels:
        component: admin
    spec:
      containers:
        - name: admin
          image: testappacr.azurecr.io/test-app-admin
          ports:
            - containerPort: 4000
          env:
            - name: PGUSER
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGUSER
            - name: PGHOST
              value: postgres-cluster-ip-service-dev
            - name: PGPORT
              value: "1423"
            - name: PGDATABASE
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGDATABASE
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: PGPASSWORD
            - name: SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: SECRET_KEY
            - name: SENDGRID_API_KEY
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: SENDGRID_API_KEY
            - name: DOMAIN
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: DOMAIN           
            - name: DEBUG
              valueFrom:
                secretKeyRef:
                  name: test-app-dev-secrets
                  key: DEBUG
          # livenessProbe:
          #   tcpSocket:
          #     port: 4000
          #   initialDelaySeconds: 2
          #   periodSeconds: 2
          # readinessProbe:
          #   tcpSocket:
          #     port: 4000
          #   initialDelaySeconds: 2
          #   periodSeconds: 2
          volumeMounts:
          - mountPath: "/docs/"
            name: file-storage
      volumes:
        - name: file-storage
          persistentVolumeClaim:
            claimName: file-storage
---
apiVersion: v1
kind: Service
metadata:
  name: admin-cluster-ip-service-dev
spec:
  type: ClusterIP
  selector:
    component: admin
  ports:
    - port: 4000
      targetPort: 4000
</code></pre>

<p>I guess I'm trying to understand a few things:</p>

<ol>
<li>Why is a complete rebuild being triggered in one case?</li>
<li>Why are files being "Synced", but the changes aren't reflected until I trigger a rebuild?</li>
<li>How can I get the my changes to reflect in the app without triggering a complete rebuild?</li>
</ol>

<p>Thanks!</p>

<p>So there are a few issues.  First, your wildcards should be <code>**</code> not <code>***</code>.  The globbing library used by Skaffold doesn't recognize <code>***</code> and so it treats it as a literal part of the path name.  And since you have no directory literally named <code>***</code>, no sync rules are matched and so your file changes cause the image to be rebuilt.</p>

<p>When I correct the wildcards, your setup still didn't work for me.</p>

<p>First, I see a warning when I modify the <code>index.php</code>:</p>

<pre><code>Syncing 1 files for testappacr.azurecr.io/test-app-admin:4c76dec58e1ef426b89fd44e3b340810db96b6961c5cacfdb76f62c9dc6725b8
WARN[0043] Skipping deploy due to sync error: copying files: didn't sync any files
</code></pre>

<p>Skaffold by default cuts logs off at the warning level.  If I instead run <code>skaffold dev -v info</code> I get some more information:</p>

<pre><code>INFO[0011] files modified: [admin/src/index.php]        
Syncing 1 files for testappacr.azurecr.io/test-app-admin:4c76dec58e1ef426b89fd44e3b340810db96b6961c5cacfdb76f62c9dc6725b8
INFO[0011] Copying files: map[admin/src/index.php:[/app/src/src/index.php]] to testappacr.azurecr.io/test-app-admin:4c76dec58e1ef426b89fd44e3b340810db96b6961c5cacfdb76f62c9dc6725b8 
WARN[0011] Skipping deploy due to sync error: copying files: didn't sync any files 
</code></pre>

<p>Note the destination being reported, <code>/app/src/src/index.php</code>.  This double <code>src</code> arises as your image's <code>WORKDIR</code> is set to <code>/app/src</code>, and your PHP sync rule is preserving the path under <code>app/admin</code>.  You can fix this by amending your <code>skaffold.yaml</code> to strip off the leading <code>src</code>:</p>

<pre><code>      - src: "src/**/*.php"
        dest: .
        strip: src
</code></pre>

<p>You might need to adjust your other rules too, and note that you can use <code>dest: ..</code> in your rules.</p>

<p>(Side note: I was still seeing <code>didn't sync any files</code> error.  I was actually running <code>skaffold dev --status-check=false</code> so as to prevent Skaffold from waiting on the deployment status — I figured the deployment would never succeed as I didn't have any valid PHP files.  But it turns out the deployments were actually failing because I didn't have your persistent volume claim available, and so the pod failed to start.  And since there were no running containers, the files were never synced, and so Skaffold reported that syncing failed.  So the moral of the story is that file syncing only works to running containers.)</p>
