Update:
Seems like this isn't a Docker-specific thing, but maybe an Ubuntu or useradd thing.. What I've found is that /var/log/lastlog
and /var/log/faillog
are the main culprit.. After doing:
RUN useradd -ms /usr/bin/tcsh -u 1000 -g users id1000
the file /var/log/lastlog
is ~288 kB in size.. But doing:
RUN useradd -ms /usr/bin/tcsh -u 10000000 -g users id10000000
instead, the file /var/log/lastlog
is 2.8 GB in size..
Adding the ubuntu tag now that I've got this new information..
Is there a reason this file would grow as a function of the UID of an added user?
Original Post:
I have the following Dockerfile (obviously not very useful, minimized for demonstrating the issue):
FROM ubuntu
RUN apt-get update
WORKDIR /usr/src/
RUN useradd -ms /usr/bin/tcsh -u 1001 -g users daroo ; adduser daroo sudo ; echo daroo:daroo | chpasswd
USER daroo
#RUN useradd -ms /usr/bin/tcsh -u 16777249 -g users otheruser ; adduser otheruser sudo ; echo otheruser:otheruser | chpasswd
#USER otheruser
#RUN useradd -ms /usr/bin/tcsh -u 2000 -g users anotherone ; adduser anotherone sudo ; echo anotherone:anotherone | chpasswd
#USER anotherone
CMD ["/usr/bin/tcsh"]
At the bottom, I create a user, add the user to the sudo group, and set the user's password (to the same as the username for this demonstration).. I then specify the USER so that when a container is started from the image, that user account is the one used within the running container..
Now the problem: If I make three separate images (one for each of the users listed), for the user with the large user id, the image size is HUGE.. For the others, it is totally reasonable.. What is causing this?
% sudo docker build --no-cache -t docker-check-daroo .
[...]
% [edit Dockerfile -> comment RUN and USER lines associated with daroo user, uncomment those for otheruser]
% sudo docker build --no-cache -t docker-check-otheruser .
[...]
% [edit Dockerfile -> comment RUN and USER lines associated with otheruser user, uncomment those for anotherone]
% sudo docker build --no-cache -t docker-check-anotherone .
[...]
% sudo docker images | grep check
docker-check-anotherone latest 669db89e8558 4 minutes ago 151MB
docker-check-otheruser latest adcd7cd4906a 5 minutes ago 5.59GB
docker-check-daroo latest e9569a538777 7 minutes ago 150MB
In case anyone else comes across this issue, here's what I've found and a quick workaround..
Apparently, /var/log/lastlog is a sparse file that has something to do with how Ubuntu makes sure it doesn't re-use UIDs when new users are created.
The workaround that seems to do the trick is to simply include a "-l" argument to the useradd command.. From the useradd man page:
-l, --no-log-init
Do not add the user to the lastlog and faillog databases.
By default, the user's entries in the lastlog and faillog databases are resetted to avoid reusing the entry
from a previously deleted user.
For the compatibility with previous Debian's useradd, the -O option is also supported.
So, I just updated the lines near the end of the Dockerfile to be:
RUN useradd -ms /usr/bin/tcsh -l -u 16777249 -g users otheruser ; adduser otheruser sudo ; echo otheruser:otheruser | chpasswd
USER otheruser
and the resulting size was consistent regardless of the UID used.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With