Create a new C# Minimal API project (use at least dotnet 8) and use this Program.cs file:
In this exercise you will have to perform a lot of steps without any explanation. Your goal is to find your own conclusions on how data is stored inside and outside containers and how volumes work. It is highly recommended that you document your findings after each step.
#Ā Instructions
- Dockerize this application using aĀ
Dockerfile
. You will need these commands:-
can also be done in Rider when creating a new project + add .dockerfile
-
dotnet restore <path to .csproj file>
-
dotnet build <path to .csproj file> -c Release -o <output path>
-
dotnet publish <path to .csproj file> -c Release -o <output path> /p:UseAppHost=false
-
- Create an image using the tagĀ
volumes-exercise
In my case it gets cached, because I built it a second time for a screenshot.
- Start a container using this image usingĀ
docker run -d -p 8080:8080 --name volumescontainer volumes-exercise
Now the container is running on port 8080 and forwards also to port 8080.
- Try using the provided API to generate and access files within the container
Now open your browser and visit your loopback-address:8080 + swagger. Here the minimal API should work properly.
Post-Endpoint:
Get-Endpoint:
- UseĀ
docker exec -it volumescontainer bash
Ā to connect to a bash shell inside the container. Analyse which files are generated.
Two folders are generated.
- /temp - saves files temporarely using the File.CreateText(fileNames.TempFilePath) create method
- /persistent - here the posted file is stored & generated
- āzwettl.txtā
- Stop and restart the container usingĀ
docker stop volumescontainer
Ā andĀdocker start volumescontainer
Stopping container:
Starting container:
- Analyse if the files are still there.
The 2 folder & files are still there.
/temp:
/persistent
- Stop and remove the container.
Stopping & removing container:
- Start a new container from the image usingĀ
docker run -d -p 8080:8080 --rm --name volumescontainer volumes-exercise
Here we make sure, that our container gets removed (āārmā-flag) after it is stopped.
- Analyse if the files are still there.
As you can see the files are not here, since we have not defined a specific volume. Because of this, the data gets saved in the container. Above we removed our container = data is lost.
- Stop the container (this should also remove the container since you used theĀ
--rm
Ā flag)
Exactly, our container was deleted automatically when it got stopped.
- Define a volume inside the container, adding this line to the Dockerfile:Ā
VOLUME ["/app/persistent"]
With the specified volume, files are not saved in the container-filesystem, they are saved in a volume outside of the container.
new dockerfile:
- Rebuild the image
- Inspect the image and check if the volume is defined
Here we can see, that there is a volume ā/app/persistentā
-
Start a new container from the image usingĀ
docker run -d -p 8080:8080 --rm --name volumescontainer volumes-exercise
-
Note: In recent Images provided by Microsoft, the App runs under the userĀ app, yet if you create a volume as described above, the created folder will be owned by the root user. Therefore, the application wonāt have write access to this folder. To change the ownership of that folder add these lines to the Dockerfile:
-
new Dockerfile:
Also make sure to rebuild the image, since the dockerfile has been changed.
- Again use the API and check if the files are created accordingly.
Post:
Get:
/temp & /persistent are available.
- Use Docker desktop to analyse if a volume has been created.
Under āVolumesā we see a new volume has been created.
If we klick on it, we see the stored data inside the volume (Note: If we would stop the container - the container would be automatically removed & the volume too):
- Stop the container (thus removing it).
Now, the container was removed:
- Check if the volume is still there
As we can see, the volume gets automatically removed:
- Start a new container and analyse if the files are still there.
There is no data inside the volume.
- Stop the container (thus removing it).
- Start a new container from the image usingĀ
docker run -d -p 8081:8080 -v myvolume:/app/persistent --rm --name volumescontainer volumes-exercise
This runs a new container, that has a āNamed Volumeā. We switched from āAnonymous Volumeā to a āNamed Volumeā.
As we can see, a new volume has been allocated in a specific path by docker:
- Generate data
Using the API in our webbrowser swagger
- POST-Request
- Stop and remove the container
- Check if the volume is still there
The volume is still there (Status āin useā switches to ā-ā, since no container uses the volume)
Note: The data persists.
- Start a new container from the image usingĀ
docker run -d -p 8081:8080 -v myvolume:/app/persistent --rm --name volumescontainer volumes-exercise
- Check if the files are still there.
The files are still there & since we refer to āmyvolumeā, the container automatically gets our previously created āvolume.txtā assigned.
Volume-Info: