🐳 Run Your First Podman Container: Images, Lifecycle, and Flags (2026)
Quick one-liner: Pull images, run containers, manage their lifecycle, and understand the flags that make Podman different from Docker.
🤔 Why This Matters
In Ep 1, you installed Podman, set up shared storage, and verified rootless operation. Now it's time to actually do something with it.
This post walks you through:
- Finding and pulling images from container registries
- Running your first container with the right flags
- Managing container lifecycles (start, stop, restart, remove)
- The key differences between
podman runanddocker run
By the end, you'll be comfortable managing containers with Podman. You'll also understand why podman run is a drop-in replacement for docker run.
✅ Prerequisites
- Podman installed, rootless on SLES 16 (see Ep 1)
- Shared storage configured (multi-user UID/GID setup)
- 5 minutes to run your first workload
🔍 Finding Images
Podman uses container registries to pull images. On SLES, the default registry is registry.suse.com. It's SUSE's own registry with images built and maintained for SLES:
$ podman search nginx
NAME DESCRIPTION
registry.suse.com/caasp/v4/nginx-ingress-controller
registry.suse.com/caasp/v4.5/ingress-nginx-controller
registry.suse.com/caasp/v5/ingress-nginx-controller
registry.suse.com/cap/nginx-buildpack
registry.suse.com/cap/stratos-metrics-nginx
registry.suse.com/cap/suse-nginx-buildpack
registry.suse.com/rancher/library-nginx
registry.suse.com/suse/nginx
Start here. If the image you need is in the SUSE registry, use it. It's tested on SLES, receives security updates, and works seamlessly with your system.
But the SUSE registry doesn't have everything. If you can't find an image there, fall back to Docker Hub (docker.io) or Quay (quay.io), which is where most of the world's container images live. To search Docker Hub, prefix with the registry name:
$ podman search docker.io/library/nginx
NAME DESCRIPTION
docker.io/library/nginx Official build of Nginx.
docker.io/nginx/nginx-ingress NGINX and NGINX Plus Ingress Controllers...
docker.io/nginx/nginx-prometheus-exporter NGINX Prometheus Exporter for NGINX...
docker.io/nginx/unit This repository is retired, use the Docker...
docker.io/nginx/nginx-ingress-operator NGINX Ingress Operator for NGINX and NGINX...
docker.io/bitnami/nginx Bitnami Secure Image for nginx
Look for the official images (from docker.io/library/). They're maintained by the software's creators and receive regular security updates.
🐳 Running Your First Container
Let's run nginx from the SUSE registry:
$ podman run -d --rm --name dtnginx suse/nginx
Let me break down each flag:
| Flag | What It Does |
|---|---|
-d |
Detach: runs the container in the background so you get your terminal back |
--rm |
Auto-remove: automatically deletes the container once it stops |
--name dtnginx |
Name it dtnginx instead of a random ID |
suse/nginx |
The image to run. Podman on SLES searches registry.suse.com by default, so the short name works |
If this is the first time running this image, Podman downloads it:
Resolving "suse/nginx" using unqualified-search registries (/etc/containers/registries.conf)
Trying to pull registry.suse.com/suse/nginx:latest...
Getting image source signatures
Checking if image destination supports signatures
Copying blob 5a22de652f81 done |
Copying blob 36e296237f0c done |
Copying config 885ea61474 done |
Writing manifest to image destination
Storing signatures
📊 Checking Container Status
Verify it's running:
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
431e72ff8902 registry.suse.com/suse/nginx:latest nginx -g daemon o... 10 seconds ago Up 10 seconds 80/tcp dtnginx
Note:
podman psanddocker psproduce identical output. If you've used Docker, the commands feel the same.
To see all containers (including stopped ones):
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
431e72ff8902 registry.suse.com/suse/nginx:latest nginx -g daemon o... 2 minutes ago Up 2 minutes 80/tcp dtnginx
2ea01225897d quay.io/podman/hello:latest /usr/local/bin/po... 3 minutes ago Exited (0) 3 minutes ago hopeful_heyrovsky
dtnginx is still running in the background. The hello container from Ep1 is sitting in "Exited" state. Because it was run without --rm, it stayed around after it finished.
💡 Tip: forgot to name your container? Podman assigns random names like
hopeful_heyrovskyoragitated_villani. You can rename it anytime:$ podman rename hopeful_heyrovsky dthelloNow
podman ps -ashowsdthelloinstead. Much easier to manage.
To clean up stopped containers, use podman rm:
$ podman rm dthello
dthello
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
💻 Accessing the Container Shell
Open a shell inside the running container:
$ podman exec -it dtnginx /bin/bash
| Flag | What It Does |
|---|---|
-i |
Keeps stdin open |
-t |
Allocates a pseudo-terminal |
You're now inside the container. Check the nginx default page:
bash-5.2# curl localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the container with the nginx web server is
successfully installed and working.</p>
</body>
</html>
Exit the shell:
bash-5.2# exit
🛑 Stopping and Cleaning Up
Stop the container:
$ podman stop dtnginx
Since we used --rm, it's automatically removed. Confirm:
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
No sign of dtnginx. The --rm flag took care of it.
If you forgot --rm, the container stays around in "Exited" state. Clean it up:
$ podman rm dtnginx
Or remove all stopped containers at once:
$ podman container prune
⚙️ Environment Variables
Many container images are configured through environment variables instead of editing config files. This is how you run databases, web apps, and services without ever touching a config file inside the container.
Use the -e flag to pass variables at runtime. Let's run MariaDB:
$ podman run -d --rm --name dtmariadb \
-e MARIADB_ROOT_PASSWORD=podman \
-e MARIADB_DATABASE=testdb \
suse/mariadb
This starts MariaDB with the root password set to podman and automatically creates a database called testdb. Without MARIADB_ROOT_PASSWORD, the container refuses to start.
You can verify the variables inside a running container:
$ podman exec dtmariadb env | grep MARIADB
MARIADB_ROOT_PASSWORD=podman
MARIADB_DATABASE=testdb
To connect to the database from inside the container:
$ podman exec -it dtmariadb mariadb -u root -ppodman -e "SHOW DATABASES;"
Database
information_schema
mysql
performance_schema
testdb
Each image documents its supported environment variables on its Docker Hub page. Scroll down to the "Environment Variables" section and you'll find everything you need. Things like POSTGRES_PASSWORD, MYSQL_ROOT_PASSWORD, REDIS_PASSWORD, and dozens more. That's always the first place I check before running a new database image.
Stop the container when done:
$ podman stop dtmariadb
🔄 Key Differences: Podman vs Docker
You'll notice the commands are nearly identical. But here's what's different under the hood:
| Feature | Docker | Podman |
|---|---|---|
| Daemon | Required (dockerd) |
No daemon needed. Containers run as direct child processes |
| Rootless | Requires extra setup | Rootless by default, no extra setup needed |
| Systemd integration | Manual | Native support via podman generate systemd
|
| Pod support | Via Compose | Native support via podman pod create
|
| Fork/exec model | Single daemon manages all | Each container is independent |
In practice: alias docker=podman works for 95% of daily commands.
🏋️ Exercise
Part 1: Run Redis and Store Data
Redis isn't in the SUSE registry (the available image is 8 years old), so we fall back to Docker Hub:
$ podman run -d --rm --name dtredis docker.io/library/redis
$ podman exec -it dtredis redis-cli
127.0.0.1:6379> SET mykey "Hello from Podman!"
OK
127.0.0.1:6379> GET mykey
"Hello from Podman!"
127.0.0.1:6379> exit
Part 2: Run PostgreSQL and Add Data
$ podman run -d --rm --name dtpg \
-e POSTGRES_PASSWORD=podman \
-e POSTGRES_DB=testdb \
suse/postgres
Wait ~10 seconds for PostgreSQL to initialize, then create a table and insert some data:
$ podman exec -it dtpg psql -U postgres -d testdb
testdb=# CREATE TABLE users (name VARCHAR(50), email VARCHAR(50));
CREATE TABLE
testdb=# INSERT INTO users VALUES ('Alice', 'alice@example.com');
INSERT 0 1
testdb=# SELECT * FROM users;
name | email
-------+--------------------
Alice | alice@example.com
(1 row)
testdb=# \q
Alice is in the database. Everything looks good.
Part 3: Remove Both and Lose Everything
$ podman stop dtredis dtpg
$ podman ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Both are gone (thanks to --rm). Now start fresh containers:
$ podman run -d --rm --name dtredis docker.io/library/redis
$ podman exec -it dtredis redis-cli
127.0.0.1:6379> GET mykey
(nil)
Redis data is gone. Now check PostgreSQL:
$ podman run -d --rm --name dtpg \
-e POSTGRES_PASSWORD=podman \
-e POSTGRES_DB=testdb \
suse/postgres
$ podman exec -it dtpg psql -U postgres -d testdb -c "SELECT * FROM users;"
ERROR: relation "users" does not exist
Alice is gone. The table is gone. The database is a fresh empty shell.
Containers are ephemeral by design. When they go, everything inside them goes with them.
Next chapter: we rescue Alice. Persistent storage that survives container death.
👉 Coming up: You've got nginx running and MariaDB configured. But here's a problem. Stop the container, remove it, start a new one, and your data is gone. The database you just created? Disappeared.
Next time: we fix that. Persistent storage that survives container death. Your data lives on even when containers come and go.
Found this helpful? 🙌
- LinkedIn: Share with your network
- Twitter: Tweet about it
- Questions? Drop a comment below or reach out on LinkedIn
Top comments (0)