- Now that we know how to run a container,
let's talk about some more environmental stuff,
which is storage and variables and ports.
So first storage, container storage is ephemeral.
What does that mean?
Well, if you run a container, a directory is created,
and in that directory,
the environment for the container is stored,
including all files that you create
or modify from within a container.
And the ephemeral nature is that
if you remove the container,
this directory is removed,
including everything that you have stored.
And that's why we say that files created
in a container don't outlive the container lifetime.
If you want to provide persistent storage,
the common solution is to bind mount a directory
on the host inside a container.
In podman, you use podman run -v mydir:/mydir:Z
to bind mount the mydir host directory inside a container.
And the result is that all files created
in mydir will be stored on the host,
and outlive the container lifetime.
One thing, you can see that
on the slide we have this mydir:Z.
The :Z is taking care of SELinux.
If you are using Docker on a system that doesn't do SELinux,
just skip the colon uppercase Z,
because if you don't have SELinux
you don't have to consider
it while running your containers.
Let me demonstrate.
Okay, let me start with podman images.
There we go, the different images that are available.
And if I use podman inspect and nginx,
then we can figure out what's going on in the Nginx image.
So here we can see everything that is happening
when you are starting Nginx.
Might be good to know
about this before starting your container.
So I'm going to use podman stop myweb.
Now I'm going to start
it again using podman run -D --name=myweb nginx.
And oh boy, what am I getting here?
Well, I'm getting an error message,
"Creating container storage: container name myweb
is already in use
by 0c05a, this long thing here.
That's a unique ID for a container.
Now why am I getting this message?
Well, I'm getting this message
because of podman ps -a,
if you stop a container, then a container is not removed.
So here we can see myweb still exists
and actually if I would use find . -name
on 0c05*,
then you can see that that doesn't work
without sudo privileges.
So let's add sudo privileges as well,
and we can see the directory
where the temporary files created
by this container are stored.
So this directory is what it is all about.
If I use podman rm on myweb,
then this directory is deleted.
And that means that everything
that once existed inside this directory,
all the the files, the ephemeral files
that you have created are deleted as well.
And that's a problem that we need to deal with.
Now let me show you how to do that using mkdir files.
If you are using a rootless container,
which is the the standard in podman,
then the directory that you are going
to expose on the host must be a directory that
is read writeable accessible by the current user.
Oh we already have the files.
Well, I think I don't mind, we already have the files.
Even if there is files existing inside
I do need to check the permission, so-
so ls -ld on files is showing
it's owned by student and group student,
and we have permission mode 775.
That is good enough,
that is what we are going to use.
How are we going to use it?
Well podman run -v /home/student/files,
I like having absolute path names in my containers,
:/files:Z -it
busybox sh.
So now I go in this files directly, and what do we see?
We see all the files from the host,
and if I use touch busyfile,
then I can even create a new file.
Small typo, that doesn't matter,
because that's not what this is about.
What this is about is that
if at this point I use ls on my files,
I can see all these files existing.
The files are on the host,
and they are no longer in the container image.
And that is why this is persistent storage.
The next thing you need to know about
is how to access container applications.
Applications in containers
are accessed using port forwarding.
Containers don't need an IP address
in order to have the application accessible.
And that's because a container is just an application.
And if you run a web server without a container,
you also don't get an IP address, right?
So the container application port is exposed
on the host that runs a container,
and users access this specific host port.
And that guarantees that
the container doesn't even need its own IP address.
Privileged host ports can only be used
by the root container, so if you run a rootless container,
that is something to be aware of.
You can't address a host port below 1024.
Let me show you.
Now let me use podmanrun -p 8080:80
- d nginx,
which is doing the port forwarding.
So -p is for port forwarding,
8080 is what we are exposing on the host,
and 80 is the port inside the container.
Now if I use podman ps,
then we can see that the nginx container,
right here, has the port forwarding.
And the result is that I can use curl localhost:8080.
That's easy enough, isn't it?
"Welcome to nginx".
So that's working.
The last thing we need to know about
is about working with environment variables.
So to use specific parameters in a container,
variables are typically used,
because you cannot hard code your specific parameters
in a container image.
Well you can, but that will be very inefficient.
In order to pass environment variables,
you can use --env key=value
to provide the variable while starting the container.
Like podman run --env key=value busybox env,
which is doing what?
while it's setting the environment variable key
to the value value, and then it runs busybox.
And in busy box, it runs the command env,
which prints the environment variables,
to show you the currently used environment variables.
Now let me show you how to do this in this demo.
So podman run --name
is mydb mariadb.
Oh boy, what do we get here?
Well this is a case where apparently the MariaDB image is
in different registries.
So podman is asking which one do you wanna use?
Well, I want to use docker.io one.
The red hat registries are possible as well,
but sometimes they require authentication,
and that only works if you have an account.
I have an account, maybe you don't,
and that's why I rather go for the docker.io one.
And oh boy, what do we see?
Well, we see an error while starting this container.
If you want to further investigate, podman ps -a.
It's showing right here that this Maria DB
was created 11 seconds ago,
and the status is exited with one 12 seconds ago.
Exited with a one, That means that the main application
has generated an exit status one, exit code one,
which means that it did not run successfully.
So we need to investigate,
if you want to investigate the logs that have been created
by the application, podman logs is the command to use.
And podman logs is printing the message.
And the message is,
"You need to specify one of these variables."
So how are we going to do that?
Well, first I'm going to use podman rm mydb
and then I'm going
to use podman run --name
mydb --env
MARIADB_ROOT_PASSWORD=password
mariadb.
And now what do we see?
Oh boy, we see this MariaDB thing running
in the foreground.
Well, I'm not sure if I want that,
but once it is running in the foreground,
it's not so easy to get rid of it.
Let me open a second terminal,
because from a second terminal node you can manage it.
Podman ps is showing MariaDB,
and I am going to use podman stop MariaDB
to stop it.
That will get me my terminal back.
If I wanted to run it in background,
of course I need to add the option -d.
Oops, am I doing something wrong?
Yeah, I'm doing something wrong.
The name of the container is mydb, not mariadb.
There we go, now it is stopped,
and here it is stopped as well.
The thing is that we have seen that
by passing this environment variable,
the container has now started successfully.