Docker Run Groupadd && Useradd Directives Have No Effect

When does Dockerfile executes, and why groupadd and usereadd not working

There are two significant problems in the setup you show.

volumes:
- ./:/var/www

In the Dockerfile, you COPY --chown content to a different user, but then this volumes: mount hides everything the image setup does in the /var/www directory and replaces it with content from the host. Inside the container you'll see the host's numeric user ID and the possibly-unrelated code from the host. I'd recommend just deleting this line.

build: .
image: php:8.1.4-fpm

This combination tells Compose to build your application from its Dockerfile, then to label the result as the original php:8.1.4-fpm image. When you re-run docker-compose build it will start from the thing labeled as php:8.1.4-fpm, which means you're repeatedly reinstalling your application on top of itself.

Delete the image: line if you're not planning to push the built image to a registry (and if you are, use the name and tag for the built image, not the base image). docker pull php:8.1.4-fpm manually to make sure you have a "good" copy of this base image.

In the context of a Compose project, you don't usually need to use basic docker commands; there are docker-compose wrappers for most operations. If you want to update your application and restart its container it should be enough to

docker-compose build
docker-compose up -d

will will recreate the changed app container but leave the others alone. If you do need to stop an individual container for some reason ("stopped" is a somewhat unusual state) then docker-compose stop can do it.

Dockerfile - Docker directive to switch home directory

You can change user directory using WORKDIR in the dockerfile, this will become the working directory. So whenever you created the container the working directory will be the one that is pass to WORKDIR instruction in Dockerfile.

WORKDIR

Dockerfile reference for the WORKDIR instruction

For clarity and reliability, you should always use absolute paths for
your WORKDIR. Also, you should use WORKDIR instead of proliferating
instructions like RUN cd … && do-something, which are hard to read,
troubleshoot, and maintain.

FROM buildpack-deps:buster

RUN groupadd -r someteam --gid=1280 && useradd -r -g someteam --uid=1280 --create-home --shell /bin/bash someteam

# Update and allow for apt over HTTPS
RUN apt-get update && \
apt-get install -y apt-utils
RUN apt-get install -y apt-transport-https
RUN apt update -y
RUN apt install python3-pip -y

# switch user from 'root' to ‘someteam’ and also to the home directory that it owns
USER someteam
WORKDIR /home/someteam

Sample Image

using $HOME will cause error.

When you use the USER directive, it affects the userid used to start
new commands inside the container.Your best bet is to either set ENV
HOME /home/aptly in your Dockerfile, which will work dockerfile-home-is-not-working-with-add-copy-instructions

Should I run things inside a docker container as non root for safety?

Running the container as root brings a lot of risks. Although being root inside the container is not the same as root on the host machine (some more details here) and you're able to deny a lot of capabilities during container startup, it is still the recommended approach to avoid being root.

Usually it is a good idea to use the USER directive in your Dockerfile after you install some general packages/libraries. In other words - after the operations that require root privileges. Installing sudo in a production service image is a mistake, unless you have a really good reason for it. In most cases - you don't need it and it is more of a security issue. If you need permissions to access some particular files or directories in the image, then make sure that the user you specified in the Dockerfile can really access them (setting proper uid, gid and other options, depending on where you deploy your container). Usually you don't need to create the user beforehand, but if you need something custom, you can always do that.

Here's an example Dockerfile for a Java application that runs under user my-service:

FROM alpine:latest
RUN apk add openjdk8-jre
COPY ./some.jar /app/
ENV SERVICE_NAME="my-service"

RUN addgroup --gid 1001 -S $SERVICE_NAME && \
adduser -G $SERVICE_NAME --shell /bin/false --disabled-password -H --uid 1001 $SERVICE_NAME && \
mkdir -p /var/log/$SERVICE_NAME && \
chown $SERVICE_NAME:$SERVICE_NAME /var/log/$SERVICE_NAME

EXPOSE 8080
USER $SERVICE_NAME
CMD ["java", "-jar", "/app/some.jar"]

As you can see, I create the user beforehand and set its gid, disable its shell and password login, as it is going to be a 'service' user. The user also becomes owner of /var/log/$SERVICE_NAME, assuming it will write to some files there. Now we have a lot smaller attack surface.



Related Topics



Leave a reply



Submit