Search code examples
dockerpermissionspackagedockerfileroot

Working on user in dockerfile and installing packages on it permission denied


I want to install packages on dockefile as user in /home/user .

FROM ubuntu:16.04

ENV user lg

RUN useradd -m -d /home/${user} ${user} \
 && chown -R ${user} /home/${user}

USER ${user}

WORKDIR /home/${user}

RUN apt-get update

RUN apt-get -y install curl

RUN apt-get -y install lsb-core

RUN apt-get -y install lsb

RUN apt-get -y upgrade -f

Docker throws error on executing apt-get update

E: List directory /var/lib/apt/lists/partial is missing. - Acquire (13: Permission denied) The command '/bin/sh -c apt-get update' returned a non-zero code: 100

Thanks :)


Solution

  • It's because your lg user simply doesn't have necessary permissions. In this case, it doesn't matter that ubuntu is dockerized. It's like in any other Linux distro - you need permissions to do certain actions. An example: if you'd create a new user on your native system I bet command apt-get install X would raise the exact same error, wouldn't it?

    In order to install anything, you'll need sudo to authenticate as root for this user. This can be achieved like so:

    FROM ubuntu:16.04
    
    RUN apt-get update && \
        apt-get -y install sudo
    
    ENV user lg
    
    RUN useradd -m -d /home/${user} ${user} && \
        chown -R ${user} /home/${user} && \
        adduser ${user} sudo && \
        echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
    
    USER ${user}
    
    WORKDIR /home/${user}
    
    RUN sudo apt-get -y install curl && \
        sudo apt-get -y install lsb-core && \
        sudo apt-get -y install lsb && \
        sudo apt-get -y upgrade -f
    

    A little explanation:

    1. First, you'll need to install sudo package
    2. Add your user to sudo
    3. And you also need to add NOPASSWD to the sudoers file (I've done it for ALL but you can easily set it for a specific user). Without this, you will encounter following error: sudo: no tty present and no askpass program specified
    4. Now you can install stuff with this user

    Also try avoiding using multiple times the same Dockerfile instruction (In your case you had redundant 4x RUN). Each instruction is a separate layer in later build image. This is known Dockerfile best practice.

    Minimize the number of layers In older versions of Docker, it was important that you minimized the number of layers in your images to ensure they were performant. The following features were added to reduce this limitation:

    In Docker 1.10 and higher, only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not directly increase the size of the build.