撰寫 Dockerfile 時遇到的怪問題 , 使用 rm 指令無法移除某些檔案

撰寫 Dockerfile 時遇到的怪問題 , 使用 rm 指令無法移除某些檔案

才剛剛學習docker, 就遇到這個怪現象, 在dockerfile 中 使用 rm 可能會造成某些檔案無法移除.

我的使用環境如下:

Hardware     : odroid-c2 
Linux Kernel : Linux odroidc2 3.14.73-odroidc2 #2 SMP PREEMPT Mon Aug 1 14:01:38 CST 2016 aarch64 GNU/Linux
OS           : Armbian Debian-Jessie 
Docker       : Docker version 1.12.1, build 23cf638

原始的dockerfile 如下:

FROM ebspace/aarch64-debian:latest

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends mysql-server mysql-client  && \
    apt-get autoremove && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN /etc/init.d/mysql stop

RUN  rm -rf /var/lib/mysql/*

RUN mkdir /docker-entrypoint-initdb.d

VOLUME /var/log/mysql
VOLUME /var/lib/mysql

EXPOSE 3306

COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

CMD ["mysqld"]

搞了好久, 才發現問題出現在 RUN rm -rf /var/lib/mysql/* 這行, 當我建立出一個container後, 進去裡面看, /var/lib/mysql/ 竟然還有殘留兩個空目錄. 以至於造成entrypoint.sh 執行失敗. 至於為何 rm 指令無法刪除, 我做了許多實驗, 包括 added delay, sync, mv then delete, delete twice…..etc 某些組合會成功,某些組合會失敗. 搞得我好亂啊!! 乾脆先去睡一覺. 隔天起床後去問google 大神.

找的可能的原因了如下:

  1. Cannot (force) remove directory in Docker build
  2. unexpected file permission error in container

根據上面的討論, 懷疑是AUFS filesystem, 或者是有可能是linux kernel 的bug (或許在 4.4.6 版已經解決). 但是我的linux kernel 還太舊, 而且又不是x86 系統. 根本無法更新啊.

突然想到, 既然懷疑是AUFS 在存取 lower layer 和 upper layer 所造成的問題. 那就把它做在同一個 layer 就好了啊. 於是改寫dockerfile 如下:

FROM ebspace/aarch64-debian:latest

RUN apt-get update && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends mysql-server mysql-client  && \
    apt-get autoremove && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    /etc/init.d/mysql stop && \
    rm -rf /var/lib/mysql/* 

RUN mkdir /docker-entrypoint-initdb.d

VOLUME /var/log/mysql
VOLUME /var/lib/mysql

EXPOSE 3306

COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]

CMD ["mysqld"]

果然一試就成功. 讚!! 趕緊留下紀錄, 這樣就不怕腦袋又把這個經驗給 erase 掉了.

This entry was posted in docker, embedded system, Linux and tagged . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *