Tools: Breaking: Run Your First Podman Container: Images, Lifecycle, and Flags (2026)

Tools: Breaking: Run Your First Podman Container: Images, Lifecycle, and Flags (2026)

🐳 Run Your First Podman Container: Images, Lifecycle, and Flags (2026)

🤔 Why This Matters

✅ Prerequisites

🔍 Finding Images

🐳 Running Your First Container

📊 Checking Container Status

💻 Accessing the Container Shell

🛑 Stopping and Cleaning Up

⚙️ Environment Variables

🔄 Key Differences: Podman vs Docker

🏋️ Exercise

Part 1: Run Redis and Store Data

Part 2: Run PostgreSQL and Add Data

Part 3: Remove Both and Lose Everything Quick one-liner: Pull images, run containers, manage their lifecycle, and understand the flags that make Podman different from Docker. 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: 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. 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: 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: Look for the official images (from docker.io/library/). They're maintained by the software's creators and receive regular security updates. Let's run nginx from the SUSE registry: Let me break down each flag: If this is the first time running this image, Podman downloads it: Note: podman ps and docker ps produce identical output. If you've used Docker, the commands feel the same. To see all containers (including stopped ones): 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_heyrovsky or agitated_villani. You can rename it anytime: Now podman ps -a shows dthello instead. Much easier to manage. To clean up stopped containers, use podman rm: Open a shell inside the running container: You're now inside the container. Check the nginx default page: Since we used --rm, it's automatically removed. Confirm: 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: Or remove all stopped containers at once: 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: 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: To connect to the database from inside the container: 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: You'll notice the commands are nearly identical. But here's what's different under the hood: In practice: alias docker=podman works for 95% of daily commands. Redis isn't in the SUSE registry (the available image is 8 years old), so we fall back to Docker Hub: Wait ~10 seconds for PostgreSQL to initialize, then create a table and insert some data: Alice is in the database. Everything looks good. Both are gone (thanks to --rm). Now start fresh containers: Redis data is gone. Now check PostgreSQL: 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? 🙌 Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to ? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Code Block

Copy

registry.suse.com $ 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 $ 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 $ 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 $ 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 $ 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 $ 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 docker.io/library/ $ podman run -d --rm --name dtnginx suse/nginx $ podman run -d --rm --name dtnginx suse/nginx $ podman run -d --rm --name dtnginx suse/nginx --name dtnginx registry.suse.com 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 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 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 $ 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 $ 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 $ 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 $ 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 $ 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 $ 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 hopeful_heyrovsky agitated_villani $ podman rename hopeful_heyrovsky dthello $ podman rename hopeful_heyrovsky dthello podman ps -a $ podman rm dthello dthello $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman rm dthello dthello $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman rm dthello dthello $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman exec -it dtnginx /bin/bash $ podman exec -it dtnginx /bin/bash $ podman exec -it dtnginx /bin/bash 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> 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> 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> bash-5.2# exit bash-5.2# exit bash-5.2# exit $ podman stop dtnginx $ podman stop dtnginx $ podman stop dtnginx $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman rm dtnginx $ podman rm dtnginx $ podman rm dtnginx $ podman container prune $ podman container prune $ podman container prune $ podman run -d --rm --name dtmariadb \ -e MARIADB_ROOT_PASSWORD=podman \ -e MARIADB_DATABASE=testdb \ suse/mariadb $ podman run -d --rm --name dtmariadb \ -e MARIADB_ROOT_PASSWORD=podman \ -e MARIADB_DATABASE=testdb \ suse/mariadb $ podman run -d --rm --name dtmariadb \ -e MARIADB_ROOT_PASSWORD=podman \ -e MARIADB_DATABASE=testdb \ suse/mariadb MARIADB_ROOT_PASSWORD $ podman exec dtmariadb env | grep MARIADB MARIADB_ROOT_PASSWORD=podman MARIADB_DATABASE=testdb $ podman exec dtmariadb env | grep MARIADB MARIADB_ROOT_PASSWORD=podman MARIADB_DATABASE=testdb $ podman exec dtmariadb env | grep MARIADB MARIADB_ROOT_PASSWORD=podman MARIADB_DATABASE=testdb $ podman exec -it dtmariadb mariadb -u root -ppodman -e "SHOW DATABASES;" Database information_schema mysql performance_schema testdb $ podman exec -it dtmariadb mariadb -u root -ppodman -e "SHOW DATABASES;" Database information_schema mysql performance_schema testdb $ podman exec -it dtmariadb mariadb -u root -ppodman -e "SHOW DATABASES;" Database information_schema mysql performance_schema testdb POSTGRES_PASSWORD MYSQL_ROOT_PASSWORD REDIS_PASSWORD $ podman stop dtmariadb $ podman stop dtmariadb $ podman stop dtmariadb podman generate systemd podman pod create alias docker=podman $ podman run -d --rm --name dtredis docker.io/library/redis $ podman exec -it dtredis redis-cli $ podman run -d --rm --name dtredis docker.io/library/redis $ podman exec -it dtredis redis-cli $ 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 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 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 $ podman run -d --rm --name dtpg \ -e POSTGRES_PASSWORD=podman \ -e POSTGRES_DB=testdb \ suse/postgres $ podman run -d --rm --name dtpg \ -e POSTGRES_PASSWORD=podman \ -e POSTGRES_DB=testdb \ suse/postgres $ 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 $ podman exec -it dtpg psql -U postgres -d testdb $ 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', '[email protected]'); INSERT 0 1 testdb=# SELECT * FROM users; name | email -------+-------------------- Alice | [email protected] (1 row) testdb=# \q testdb=# CREATE TABLE users (name VARCHAR(50), email VARCHAR(50)); CREATE TABLE testdb=# INSERT INTO users VALUES ('Alice', '[email protected]'); INSERT 0 1 testdb=# SELECT * FROM users; name | email -------+-------------------- Alice | [email protected] (1 row) testdb=# \q testdb=# CREATE TABLE users (name VARCHAR(50), email VARCHAR(50)); CREATE TABLE testdb=# INSERT INTO users VALUES ('Alice', '[email protected]'); INSERT 0 1 testdb=# SELECT * FROM users; name | email -------+-------------------- Alice | [email protected] (1 row) testdb=# \q $ podman stop dtredis dtpg $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman stop dtredis dtpg $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman stop dtredis dtpg $ podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES $ podman run -d --rm --name dtredis docker.io/library/redis $ podman exec -it dtredis redis-cli $ podman run -d --rm --name dtredis docker.io/library/redis $ podman exec -it dtredis redis-cli $ podman run -d --rm --name dtredis docker.io/library/redis $ podman exec -it dtredis redis-cli 127.0.0.1:6379> GET mykey (nil) 127.0.0.1:6379> GET mykey (nil) 127.0.0.1:6379> GET mykey (nil) $ 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 $ 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 $ 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 - 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 run and docker run - Podman installed, rootless on SLES 16 (see Ep 1) - Shared storage configured (multi-user UID/GID setup) - 5 minutes to run your first workload - LinkedIn: Share with your network - Twitter: Tweet about it - Questions? Drop a comment below or reach out on LinkedIn