# 6.1.Docker as Root

This demo builds a standard docker image from the demo application just using a standard *Dockerfile*. For details on the demo application see [hello spring boot application](https://github.com/andifalk/cloud-native-microservices-security/tree/5863aa127045cf59dba51f838aa535ad1d9ce45f/lab6/step1-hello-spring-boot/README.md).

## Java Base Images

* [OpenJDK](https://hub.docker.com/_/openjdk)
* [AdoptJDK](https://hub.docker.com/_/adoptopenjdk)
* [Google Distroless](https://github.com/GoogleContainerTools/distroless)
* [Amazon Corretto](https://hub.docker.com/_/amazoncorretto)

## Standard Dockerfile

```
FROM openjdk:11.0.6-jre-buster
COPY step2-hello-root-1.0.0-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT java -jar /app.jar
```

## Runs with Root by default

When using defaults for building a container image the container will run using the **root** user by default.

You can prove this by using these commands:

```bash
docker container run --rm --detach --name hello-root \
-p 9090:9090 andifalk/library-server-container-root:latest
docker exec hello-root whoami
```

This should return the following user information (it really is root)

```bash
root
```

You should also be able to reach the dockerized application via [localhost:8080](http://localhost:8080).

Finally stop the running container by using the following command:

```bash
docker stop hello-root
```

## Linux capabilities

Docker runs with a balanced set of capabilities between security and usuablity of containers. You can print the default capabilities by using this command:

```
docker container run --rm -it alpine sh -c 'apk add -U libcap; capsh --print'
```

If you even run the container in privileged mode (you should usually never do that) then you get full privileged root access with all linux capabilities set:

```
docker container run --privileged --rm -it alpine sh -c 'apk add -U libcap; capsh --print'
```

In privileged mode you can for example list and change partition tables:

```
docker container run --privileged --rm -it alpine sh -c 'apk add -U libcap; capsh --print; fdisk -l'
```

Usually you even don't need the default capabilities defined by docker. A common use case is to run a container listening on a [privileged tcp port (below 1024)](https://www.w3.org/Daemon/User/Installation/PrivilegedPorts.html), e.g. using a http server.\
For this you just need the capability *CAP\_NET\_BIND\_SERVICE*:

```
docker container run --cap-drop=ALL --cap-add=net_bind_service --rm -it alpine sh -c 'apk add -U libcap; capsh --print'
```

## Check image for Vulnerabilities

Now we can check our image for vulnerabilities with critical severities using this command:

```bash
trivy --severity CRITICAL andifalk/hello-root:latest
```

## Next

[Next: Rootless Container](https://github.com/andifalk/cloud-native-microservices-security/tree/5863aa127045cf59dba51f838aa535ad1d9ce45f/lab6/step3-hello-rootless/README.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://andifalk.gitbook.io/cloud-native-microservices-security/hands-on-labs/lab6/library-server-container-root.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
