Showing posts with label docker. Show all posts
Showing posts with label docker. Show all posts

Wednesday, April 27, 2022

DEVSECOPS: Docker Level 2


Reference: https://www.youtube.com/c/TechnoDine/videos

  • NodeJS web app
  • Dockerfile
  • Including Outside files into the base image FS snapshot
  • Port Networking
  • Dockerfile with build cache

NodeJS webapp 1 - package.json (Configuration for the Web Server)

package.json (when npm install is run in Dockerfile later, it will find this file (can say similar to yaml) ).


NodeJS webapp 2 - index.js (Web Server Logic)


index.js is server logic (express is a library and it is the dependency stated from package.json)



Understanding Dockerfile:

 


 Including File into the Base Image FS Snapshot (COPY):


Port Forwarding:






Dockerfile with Build Cache:


docker build Cache (COPY only the configuration, not the server logic as the logic may change)
it is important to only copy the necessary files (bare minimum) to allow reduction of running time.
it does make a difference, the order of the commands in Dockerfile.

Thursday, April 21, 2022

Docker - Compressing an Image


Reference: https://www.ardanlabs.com/blog/2020/02/docker-images-part1-reducing-image-size.html


Compressing an image is a simple, automated, and basic task that can be handled at all stages of the CI/CD pipeline. The Docker executable even does this for you by default by producing a tarball of your container. Compressed images don’t run; their primary function is to move smoothly through the pipeline and reduce transfer costs and disk space.


In summary, ways to compress an image:

  1. multi-stage builds, because that’s where anyone should start if they want to reduce the size of their images.
  2. popular languages. We will talk about Go, but also Java, Node, Python, Ruby, and Rust. We will also talk more about Alpine and how to leverage it across the board.
  3. languages and frameworks, like using common base images, stripping binaries and reducing asset size. We will wrap up with some more exotic or advanced methods like Bazel, Distroless, DockerSlim, or UPX. We will see how some of these will be counter-productive in some scenarios, but might be useful in some particular cases.

Look at this trivial “hello world” program in C:

/* hello.c */
int main () {
  puts("Hello, world!");
  return 0;
}

We could build it with the following Dockerfile:

FROM gcc
COPY hello.c .
RUN gcc -o hello hello.c
CMD ["./hello"]

… But the resulting image will be more than 1 GB, because it will have the whole gcc image in it!

If we use e.g. the Ubuntu image, install a C compiler, and build the program, we get a 300 MB image; which looks better, but is still way too much for a binary that, by itself, is less than 20 kB:

$ ls -l hello
-rwxr-xr-x   1 root root 16384 Nov 18 14:36 hello       

Let’s see how to drastically reduce the size of these images. In some cases, we will achieve 99.8% size reduction (but we will see that it’s not always a good idea to go that far).

Pro Tip: To easily compare the size of our images, we are going to use the same image name, but different tags. For instance, our images will be hello:gcchello:ubuntuhello:thisweirdtrick, etc. That way, we can run docker images hello and it will list all the tags for that hello image, with their sizes, without being encumbered with the bazillions of other images that we have on our Docker engine.


Multi-stage builds

This is the first step (and the most drastic) to reduce the size of our images. We need to be careful, though, because if it’s done incorrectly, it can result in images that are harder to operate (or could even be completely broken).

Multi-stage builds come from a simple idea: “I don’t need to include the C or Go compiler and the whole build toolchain in my final application image. I just want to ship the binary!”

We obtain a multi-stage build by adding another FROM line in our Dockerfile. Look at the example below:

FROM gcc AS mybuildstage
COPY hello.c .
RUN gcc -o hello hello.c
FROM ubuntu
COPY --from=mybuildstage hello .
CMD ["./hello"]

We use the gcc image to build our hello.c program. Then, we start a new stage (that we call the “run stage”) using the ubuntu image. We copy the hello binary from the previous stage. The final image is 64 MB instead of 1.1 GB, so that’s about 95% size reduction:

$ docker images minimage
REPOSITORY          TAG                    ...         SIZE
minimage            hello-c.gcc            ...         1.14GB
minimage            hello-c.gcc.ubuntu     ...         64.2MB

Warning: use classic images

I strongly recommend that you stick to classic images for your “run” stage. By “classic”, I mean something like CentOS, Debian, Fedora, Ubuntu; something familiar. You might have heard about Alpine and be tempted to use it. Do not! At least, not yet. We will talk about Alpine later, and we will explain why we need to be careful with it.


Warning: COPY --from uses absolute paths

When copying files from a previous stage, paths are interpreted as relative to the root of the previous stage.

The problem appears as soon as we use a builder image with a WORKDIR, for instance the golang image.

If we try to build this Dockerfile:

FROM golang
COPY hello.go .
RUN go build hello.go
FROM ubuntu
COPY --from=0 hello .
CMD ["./hello"]

We get an error similar to the following one:

COPY failed: stat /var/lib/docker/overlay2/1be...868/merged/hello: no such file or directory

This is because the COPY command tries to copy /hello, but since the WORKDIR in golang is /go, the program path is really /go/hello.

If we are using official (or very stable) images in our build, it’s probably fine to specify the full absolute path and forget about it.

However, if our build or run images might change in the future, I suggest to specify a WORKDIR in the build image. This will make sure that the files are where we expect them, even if the base image that we use for our build stage changes later.

Following this principle, the Dockerfile to build our Go program will look like this:

FROM golang
WORKDIR /src
COPY hello.go .
RUN go build hello.go
FROM ubuntu
COPY --from=0 /src/hello .
CMD ["./hello"]

If you’re wondering about the efficiency of multi-stage builds for Golang, well, they let us go (no pun intended) from a 800 MB image down to a 66 MB:

$ docker images minimage
REPOSITORY     TAG                              ...    SIZE
minimage       hello-go.golang                  ...    805MB
minimage       hello-go.golang.ubuntu-workdir   ...    66.2MB




Sunday, March 13, 2022

ASSIGNMENTS: Docker Network Part 1 (Using Custom Network)

 


Challenge: Create a bridge network and run a web app container which stores the data in a database container.

Docker images:
webapp: ramansharma95/webapp
db: ramansharma95/mysql

webapp: This image is used as a webserver container which runs on apache. There is an index.php file hosted on this server in this directory (/var/www/html/index.php) and it is a simple webform to enter details in the database container.

db: This image is used as database container which runs on mysql and stores the data recorded/collected/received from the webserver - webapp. This database container's details should be a part of webapp's connection string.

For webapp container to be connected and functional, we need to create a database called company and a table in the company database called employee which has name, mobile fields IN the db container.

Saturday, March 12, 2022

Docker Hub / Dockerhub / Hub.docker

 



To push an image to your own public repo in docker hub:

1. you need to tag the image in this format (docker hub username/image name)

        docker image tag alpine ifanrahman/hisalpine


2. login to docker hub

        docker login

you will need to put in your username and password


3. push the tagged image into docker hub

        docker push ifanrahman/hisalpine



EXAMPLES: Dockerfile MultiStage file




Docker MultiStage file

THIS IS UNI STAGE DOCKER FILE

Step1:-
Download a sample git maven project for this example

    git clone https://github.com/onlineTrainingguy/jenkinscicd.git

Step2:-
go to jenkinscicd dir

    cd jenkinscicd

Step3:-
Modify Dockerfile content as given below

    FROM maven:latest
    WORKDIR /
    COPY src /src
    COPY pom.xml /
    RUN mvn clean package
    CMD java -cp /target/myproj-1.0-SNAPSHOT.jar com.raman.App



Step4:-
Build the image using docker build command

    docker build . -t unistagemavenimg

Step 5:-
Check the image size it will approximate 700 MB+

    docker images unistagemavenimg

Step 6:-
Create container with above image and check the output

    docker run -it unistagemavenimg

output will be
Maven Job is running on Build Server! (but if you following this steps, you will get a different output. why? because in jenkinscicd/src/main/java/com/raman/App.java, the app.java file has a different output. you can check by vi into it and even edit it to your liking!)



Now lets create multi stage Docker file
Step 1: Modify Dockerfile content as given below (notice the AS build)

    FROM maven:latest AS build
    WORKDIR /
    #copy from localfile system to docker file system
    COPY src /src
    COPY pom.xml /
    RUN mvn clean package

    #(if above Dockerfile haven't been run before, include below as well) 
    CMD java -cp /target/myproj-1.0-SNAPSHOT.jar com.raman.App

    FROM openjdk:alpine
    COPY --from=build /target/myproj-1.0-SNAPSHOT.jar /myproj-1.0-SNAPSHOT.jar
    EXPOSE 8080
    CMD java -cp /myproj-1.0-SNAPSHOT.jar com.raman.App



Step 2:- Build image using docker build command

docker build . -t multistageimg

Step 3:- Check the image size it will approximate 100 MB

docker images multistageimg

Step 4:-Create container with above image and check the output

docker run multistageimg

output will be same but the image size is reduced
Maven Job is running on Build Server!


Thursday, March 10, 2022

EXTRA INFOS: Docker Best Practice for Security

 


Best practices to secure Docker containers
a) Regularly update Docker and host (cause hackers are always waiting to pry on you)
b) Run containers as a non-root user
c) Configure resource quotas
d) Set container resource limits
e) Keep images clean (verified and trusted images)
f) Use secure container registries (trusted registries)
g) Monitor API (Application Programming Interface) and Network security


a) Regularly update Docker and host (cause hackers are always waiting to pry on you)

Make sure that Docker and the host are up-to-date. Always make sure that Docker is the most up to date version. Use the updated operating system and containerization software to put a stop to security issues. Each update has security upgrades that are necessary for safeguarding the host and Docker.

b) Run containers as a non-root user

Running containers as a non-root helps to mitigate security vulnerabilities. Running your containers on rootless mode will verify that your application environment is safe.

It also prevents malicious content from accessing the host container. This means not everyone who has pulled your container from Docker can get access to your server.

c) Configure resource quotas

Resource quotas are configured on a per-container basis by Docker. They enable you to limit the number of resources (memory and CPU) that a container can consume.

Configuring resource quotas on containers increases the efficiency of your docker environment. It also prevents the imbalance of resources of the overall containers in the environment.

This feature enhances container security and makes them perform at an expected speed. If one container got infected with malicious code, it won’t let in many resources in as the quota cut it off. This further helps to minimize attacks.

d) Set container resource limits

Containers should have a resource limit. Setting resource limits reduces the ability of containers to consume a lot of the system’s resources. Limiting resources assigned to each container enhances security in the event of an attack.

e) Keep images clean

Downloading container images from untrusted sources and vendors can introduce security vulnerabilities in containers. Make sure that images downloaded from online platforms are from trusted and secure sources.

    To avoid security vulnerabilities:
  1. Use container images that are authentic. Check them out at Docker Hub. It is the largest Docker registry with multiple container images.
  2. Make use of images that are verified by the Docker Content Trust.
  3. Use Docker security scanning tools to help you identify vulnerabilities within container images.


f) Secure container registries

Docker container registry is a content distribution system that stores and issues images for your containers. It makes Docker much more powerful.

With registries, you can build a central repository from where you can download container images more easily and faster. There are many security risks if you fail to use a trusted registry.


Docker Trusted Registry is a legit registry. It is installed behind your firewall to mitigate the risks and breaches on the internet. Even though the registry is reachable from behind the firewall, you should deny users access to upload or download images from the registry.


g) Monitor API (Application Programming Interface) and Network security

Networks and APIs play a significant role in Docker security. Docker containers communicate using APIs and networks. Communication is essential for containers to deploy and run correctly. Thus proper monitoring and security are needed.

API and network security are resources used along with Docker. These resources are also an open risk to Docker security. API and network security should be well monitored and configured to enhance Docker security.


ASSIGNMENTS: Docker Network Part 3 (None Network)


 


None Network

When no IP address is assigned to the container you can run the container in none network. It is mostly used for applications that need to be tested in an isolated environment. After testing, we can disconnect the container from the network and connect it to another network.


Step 1: Create a centos container on none or null network

docker container run -it --name c1 --network none -d centos

Step 2: Inspect the container and verify that it is running on none networks

docker inspect c1

Step 3: Once the testing is done then remove none network from n1 container and attach bridge network

docker network disconnect none c1

docker network connect bridge c1

Step 4: Verify the n1 container is having bridge network

docker inspect c1

Docker Networking


Summary:
1) Bridge Network: Default & Custom
2) Host Network
3) None/Null Network


DOCKER NETWORKING 
In Docker, if 2 containers communicate to each other, it means they are in a network.

Do note that unlike centos, ubuntu does not have ping command in-built. so you need to install it in the containers themselves:

apt-get update
apt-get install iputils-ping  # 333kb 

 

To look at available docker network commands:

Command:-> docker network --help

connect

Connect a container to a network

create

Create a network

disconnect

Disconnect a container from a network

inspect

Display detailed information on one or more networks

ls

List networks

prune

Remove all unused networks

rm

Remove one or more networks


To find all the IP addresses on a system

Command:-> ip a

Find all the networks in docker

Command:-> docker network ls

Types of Networks in Docker

1) Bridge

1a) Default Bridge Network

It is the default network (docker0) in docker, which means if a container is created by default it is created on top of bridge network docker0.

If 2 or more containers get created on the bridge network then they are automatically in the same network, which means they can communicate with each other.

Step 1:- Create container c1 with ubuntu image

docker container run -it --name c1 -d ubuntu

Step 2:- Check c1 container is running on the docker0 network

ip a

you will find one veth.... on docker0

Also, check the CIDR for docker0


Step 3:- Check the IP address of the container, it should be in the CIDR range of the docker0 network. In my case, IP address of c2 is "172.17.0.2"

docker container inspect c1

Step 4:- Create container c2 with centos image

docker container run -it --name c2 -d centos

Step 5:- Check c2 container is running on the docker0 network

ip a

you will find one more veth.... on docker0

Also, check the CIDR for docker0


Step 6:- Check the IP address of the container, it should be in the CIDR range of the docker0 network. In my case IP address of c2 is "172.17.0.3"

docker container inspect c2

Step 7:- Check container c2 ping to c1. It should get a reply from c1 because both are in the same network (default bridge network)

docker exec -it c2 bash

ping 172.17.0.2

 

1b) Custom Bridge Network or User Define Bridge Network

When a network which is created by user or sysadmin so that specified containers can run on it then it is a custom bridge network.

To make your own custom bridge network, follow the steps below:
Step 1: List all the containers

docker network ls

Step 2: Create a new default Bridge network br1 (-d is drive)

docker network create -d bridge br1

Step 3: Verify network is created successfully. It should be listed in docker networks.

docker network ls

Step 4: Inspect br1 network to find more detailed information.

docker network inspect br1

  •         "Driver": "bridge",
  •         "EnableIPv6": false,
  •         "IPAM": {
  •             "Driver": "default",
  •             "Options": {},
  •             "Config": [
  •                 {
  •                     "Subnet": "172.18.0.0/16",
  •                     "Gateway": "172.18.0.1"


Step 4.2: You can create a bridge network with your own subnet

docker network create -d bridge --subnet=192.168.0.0/16 --gateway=192.168.0.1 br2

docker inspect br2

  •         "Driver": "bridge",
  •         "EnableIPv6": false,
  •         "IPAM": {
  •             "Driver": "default",
  •             "Options": {},
  •             "Config": [
  •                 {
  •                     "Subnet": "192.168.0.0/16",
  •                     "Gateway": "192.168.0.1"
  •                 }

It means if the containers get created on this network layer then they have IP addresses in 192.168.0.1/16 range.

Step 6:- Create a container on top of br1 network on ubuntu base image.

docker container run -it --name c1 --network br1 -d ubuntu

Step 7: Inspect the container and it should have IP address within the br1 CIDR range.

docker container inspect c1

Step 8: Remove the container and network.

docker rm -f c1

docker network rm br1

docker network ls

Docker Private Registry (local or remote) (secure or insecure)



SUMMARY:
A. Making a Docker Registry on a host machine and Pulling from that same registry.
B. Pulling a Docker Registry from a registry of another host machine (1st method: insecurely)
C. Pulling a Docker Registry from a registry of another host machine (2nd method: securely)


WHAT is DOCKER PRIVATE REGISTRY (LOCAL / REMOTE SERVER)?

Firstly, we will make a private registry storing our docker image either in local or remote server.
Secondly, we will make a certificate for this registry with openssl.


A) Making a Docker Registry on a host machine and Pulling from that same registry.

A registry is a storage and content delivery system in a host machine, holding secured Docker images (you can know the storage path later below), and can be available in different tagged versions.


1. Create a container with registry docker image (this will download registry image from hub.docker.com) 

       docker container run --name local_registry -d -p 5000:5000 registry

why 5000? because docker registry is running at port 5000.

2. Check if the container is running:

        docker ps -a / docker container ls

Access the container on 5000 port with your serverip ( system's IP) http://<serverip>:5000/v2/_catalog
on CLI: curl localhost:5000/v2/_catalog
on browser: just paste and change to localhost:5000/v2/_catalog

you will not be able to do this unless in vagrant file, you add in this line:
config.vm.network "forwarded_port", guest: 5000, host: 5000


3. Inspect the container (cause we are interested in the Mounts) docker container inspect local_registry



4. check the source by typing ls then the highlighted above. this will show blank.
for my case: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data

it will show here:
/var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data/docker/registry/v2/repositories/myalpine#


5. Clone the ubuntu image to localhost:5000/ubuntu:latest

    docker image tag localhost:5000/myalpine
        OR
    docker image tag ubuntu 127.0.0.1:5000/myalpine

notice how this is different from ifanrahman/hisalpine:latest? this is because the ifanrahman one is to push to docker hub. but localhost is to push to private registry.


6. Push the image to docker registry 

        docker image push localhost:5000/myalpine

can check here: /var/lib/docker/volumes/4de3c67ac5843db5fe70a4d28bfc95e97339bde8900a78a60041f48eb20b8c0b/_data/docker/registry/v2/repositories/myalpine#

7. then delete the image

        docker rmi localhost:5000/myalpine


8. Pull the image from the local/private registry with following command

        docker image pull localhost:5000/myalpine




B) Pulling a Docker Registry from a registry of another host machine (1st method: insecurely)

Store Docker Images into Docker Registry (insecurely)
Consideration for this example

IP address of registry server is 192.168.33.10

1. Tag the docker image (alpine) with 192.168.33.10:5000

IF you haven't pull alpine, follow below. if yes skip:
   1) remove all the containers

                    docker rm -f $(docker ps -a -q)

            2) pull the docker image alpine ( you can take any image)

                    docker pull alpine

2. tag the image with private IP address of Registry server

        docker image tag alpine 192.168.33.10:5000/prvalpine

3. verify the tagged docker image got created

        docker images

4. create Docker registry container (if you haven't create it)

        docker container run -d -p 5000:5000 --name local_registry registry

5. push the tagged docker image (it will throw an error because the repository is not secure)

        docker push 192.168.33.10:5000/prvalpine

Error:-> Get https://192.168.33.10:5000/v2/: http: server gave HTTP response to HTTPS client

Remedy: If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Remember to change your IP as per your docker host system IP)


{

"insecure-registries": ["192.168.33.10:5000"]

}



6. restart the Docker daemon

        systemctl restart docker

7. start  the Docker registry Container (cause once you restart, containers will be exited)

        docker start local_registry

8. push the tagged image (this time it should be pushed to docker registry without any error)

        docker push 192.168.33.10:5000/prvalpine


Pull the insecure private registry on a different remote system
Take another Virtual Machine that is in the same network and install docker into that remote machine

1. Install docker

        apt update && apt install docker.io -y

2. If you want to push the insecure registry then create a file /etc/docker/daemon.json and enter below lines and save the file (Please change IP as per your docker host system IP)

{

"insecure-registries": ["192.168.33.10:5000"]

}


3. restart the Docker daemon

        systemctl restart docker

4. pull the Docker Registry image from the private registry

        docker pull 192.168.33.10:5000/prvalpine

5. verify image is available on this system

        docker images


C) Pulling a Docker Registry from a registry of another host machine (2nd method: securely)

Creating a secure Registry

1. remove daemon.json file on Docker Registry and Remote System

        rm /etc/docker/daemon.json

2. restart docker service

        systemctl restart docker

3. remove local_registry Container on Docker Registry Server ( if it is in running state)

        docker rm -f local_registry

4. create a directory to keep the certificates on Docker Registry Server

        mkdir /certs

5. create a directory certs in /etc/docker directory (when docker container run, it will first search any certification in this directory)

        mkdir /etc/docker/certs.d

6. create a directory for images

        mkdir /my_repo

7. create a self signed certificate with openssl utility. (this will create public key .crt and private key .key)

        openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/domain.key -x509 -days 365 -out /certs/domain.crt

it asks some optional questions but the mandatory step is to provide common name
common Name :- repo.docker.kmit ( you can give any name)
it will ask email address too, just press enter
check:
ls /certs (domain.key and domain.crt will be created)

8. create a directory with repo.docker.kmit:5000 under /etc/docker/certs.d directory (-p is used if certs.d is not created (parent directory))

        mkdir -p /etc/docker/certs.d/repo.docker.kmit:5000

9. go to /certs directory

        cd /certs

10. copy /certs/domain.crt file to /etc/docker/certs.d/repo.docker.kmit:5000 with name ca.crt

        cp domain.crt /etc/docker/certs.d/repo.docker.kmit:5000/ca.crt

11. run a secure registry on a container and config the container (-v is volume, whatever is in my_repo map it into /var/lib/registry -e is environment variable)

docker run -d -p 5000:5000 -v /my_repo:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key --restart on-failure --name myregistry registry

Remedy: provide repo.docker.kmit name by adding entry in /etc/hosts file (192.168.33.10  is docker host ip change it as necessary)

        vi /etc/hosts
        
                        192.168.33.10 repo.docker.kmit

12. download any image and tag it with the common name: repo.docker.kmit:5000

        docker pull mysql

        docker image tag mysql repo.docker.kmit:5000/mysql


13. push it to docker registry

        docker push repo.docker.kmit:5000/mysql


Pulling Images securely on Client or Remote System

1. login to remote system which is on same network and docker is installed on it.

Resolve repo.docker.kmit name by adding entry in /etc/hosts file (
  192.168.33.10 is docker registry ip )

        192.168.33.10 repo.docker.kmit

Create a directory /etc/docker/certs.d/repo.docker.kmit:5000

Copy valid certificate domain.crt file from docker Registry server and keep it at /etc/docker/certs.d/repo.docker.kmit:5000/ (hmm..how?)

        ANSIBLE!
ansible 192.168.33.11 -m copy -a "src=/certs/domain.crt dest=/etc/docker/certs.d/repo.docker.kmit:5000/domain.crt"


Pull docker image from docker registry and it will be sucessfull

        docker pull repo.docker.kmit:5000/mysql

EXAMPLES: Dockerfile Copy Add Entrypoint CMD

 


DOCKERFILE COMMANDS:

Run below command to build the image:

docker build . -t <nameofimage>

To run the image in a container:

    docker run container --name c1 -dit img1

To go into the container:

    docker exec -it c1 bash

to run without container
    
    docker run -it img1

if the file name is not Dockerfile but something else such as abc then use -f:

    docker build . -f abc -t imgnodockfile

EXAMPLES: Docker Images


SUMMARY:
A) LISTING
B) FILTERING
C) FORMATTING

Tuesday, March 1, 2022

Docker Images - Slim Image, Security & Vulnerabilities



SUMMARY:
A) Slim Images
B) Vulnerabilities
C) Security

EXTRA INFOS: Prevent Data Leaks


Below are the ways to prevent Data leaks from the container

  1. Run containers with non-root user.
  2. Secure the container host. Containers should be hosted in a container-focused OS. 
  3. Secure the networking environment. (should not be accessible to unauthorized users)
  4. Secure your management stack. 
  5. Build on a secure foundation. (everything should be on top of secured environment)
  6. Secure your build pipeline. (the particular image/container in the pipeline should be secured)
  7. Secure your application. 


EXTRA INFOS: Distroless Image




Using lightweight distros like Alpine is a very common technique amongst the developers to avoid making the container image bulky. Even though you can achieve that there is always a risk of open vulnerabilities caused by the underneath libraries.

Google solved this problem by introducing Distroless images.
“Distroless” images contain only your application and its runtime dependencies. They do not contain package managers, shells or any other programs you would expect to find in a standard Linux distribution.

EXTRA INFOS: Scratch Docker Images

 


When building Docker containers you define your base image in your Dockerfile. The scratch image is the smallest possible image for docker. Actually, by itself it is empty (in that it doesn't contain any folders or files) and is the starting point for building out images.

This image is most useful in the context of building base images (such as debian and busybox) or super minimal images (that contain only a single binary and whatever it requires, such as hello-world).

While scratch appears in Docker’s repository on the hub, you can’t pull it, run it, or tag any image with the name scratch. Instead, you can refer to it in your Dockerfile. For example, to create a minimal container using scratch:


FROM scratch

COPY hello /

CMD ["/hello"]

Fluentd

Open-source log data collector > why logs? - for compliance (auditing, company, business) - for security (transparency, monitoring, admin...