撰寫 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 大神.
找的可能的原因了如下:
根據上面的討論, 懷疑是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 掉了.