๐ณ Running Containers with Podman: Simple Guide
Want to run containers without Docker? This guide shows you how with Podman! ๐ Weโll learn how to pull images, run containers, and manage them easily. Itโs rootless and secure! ๐ป
๐ค What is Podman?
Podman (Pod Manager) is a container engine that lets you run containers without a daemon. Itโs like Docker but safer and doesnโt need root access!
Podman helps with:
- ๐ Running containers without root privileges
- ๐ง Managing container images and pods
- ๐ก Building custom container images easily
๐ฏ What You Need
Before we start, you need:
- โ Alpine Linux system with basic setup
- โ Regular user account (no root required!)
- โ Internet connection for downloading images
- โ Access to the command line interface
๐ Step 1: Install Podman
Install from Alpine Packages
Letโs install Podman on your Alpine system! ๐
What weโre doing: Installing Podman and its dependencies.
# Update package list
apk update
# Install Podman
apk add podman
# Install additional container tools
apk add buildah skopeo
# Check Podman version
podman --version
# Check Podman system info
podman system info
What this does: ๐ Installs Podman container engine and related tools.
Example output:
podman version 4.7.2
โ
Podman installed successfully
What this means: Podman is ready to run containers! โ
๐ก Important Tips
Tip: Podman works as regular user - no sudo needed! ๐ก
Warning: First run might take time to set up namespaces! โ ๏ธ
๐ ๏ธ Step 2: Run Your First Container
Pull and Run Basic Container
Time to run your first container! ๐
What weโre doing: Downloading and running a simple container image.
# Pull a basic Alpine image
podman pull alpine:latest
# List downloaded images
podman images
# Run interactive Alpine container
podman run -it alpine:latest /bin/sh
# Inside container - test commands
cat /etc/os-release
echo "Hello from container!"
exit
# Run container with command and auto-remove
podman run --rm alpine:latest echo "Container says hello!"
Code explanation:
podman pull
downloads container imagespodman run -it
runs interactive containers--rm
automatically removes container after exit
Expected Output:
Alpine Linux v3.18
Hello from container!
Container says hello!
โ
Container ran successfully
What this means: Youโre now running containers with Podman! ๐
๐ง Step 3: Container Management
List and Control Containers
Letโs learn how to manage running containers! This is powerful! ๐ฏ
What weโre doing: Running containers in background and managing them.
# Run container in background (detached)
podman run -d --name my-web-server -p 8080:80 nginx:alpine
# List running containers
podman ps
# List all containers (including stopped)
podman ps -a
# Check container logs
podman logs my-web-server
# Execute command in running container
podman exec -it my-web-server /bin/sh
ls /usr/share/nginx/html
exit
# Stop container
podman stop my-web-server
# Start stopped container
podman start my-web-server
# Remove container
podman rm my-web-server
Code explanation:
-d
runs container in background--name
gives container a friendly name-p
maps ports (host:container)exec
runs commands inside running containers
Good output looks like:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx:alpine nginx -g daemon off 10 seconds ago Up 8 seconds 0.0.0.0:8080->80/tcp my-web-server
โ
Container management ready
๐ ๏ธ Step 4: Working with Images
Build Custom Images
Letโs create our own container images! Hereโs how:
What weโre doing: Building custom container images using Dockerfile.
# Create project directory
mkdir ~/my-container-app
cd ~/my-container-app
# Create simple HTML file
cat > index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>My Podman App</title>
</head>
<body>
<h1>Hello from Podman Container!</h1>
<p>This container was built with Podman ๐ณ</p>
</body>
</html>
EOF
# Create Dockerfile
cat > Dockerfile << 'EOF'
FROM nginx:alpine
# Copy our HTML file
COPY index.html /usr/share/nginx/html/
# Expose port 80
EXPOSE 80
# Start nginx
CMD ["nginx", "-g", "daemon off;"]
EOF
# Build custom image
podman build -t my-web-app:latest .
# List images to see our new one
podman images
# Run our custom container
podman run -d --name my-app -p 8080:80 my-web-app:latest
# Test our application
curl http://localhost:8080
# Clean up
podman stop my-app
podman rm my-app
What this does: Creates custom container images from scratch! ๐
Working with Container Registries
Letโs learn how to share container images:
What weโre doing: Pushing and pulling images from registries.
# Tag image for registry
podman tag my-web-app:latest localhost:5000/my-web-app:latest
# Save image to file
podman save -o my-app.tar my-web-app:latest
# Load image from file
podman load -i my-app.tar
# Export running container as image
podman run -d --name temp-container alpine:latest
podman commit temp-container my-custom-alpine:latest
podman rm -f temp-container
# Search for images in registries
podman search nginx
# Show image details
podman inspect my-web-app:latest
Code explanation:
tag
creates new names for imagessave/load
exports/imports image filescommit
creates images from containerssearch
finds images in registries
๐ Quick Summary Table
Command | Purpose | Example |
---|---|---|
๐ง podman run | Start containers | โ
podman run -it alpine sh |
๐ ๏ธ podman ps | List containers | โ
podman ps -a |
๐ฏ podman images | List images | โ
podman images |
๐ podman build | Build images | โ
podman build -t myapp . |
๐ฎ Practice Time!
Letโs practice what you learned! Try these simple examples:
Example 1: Database Container ๐ข
What weโre doing: Running a database container for development.
# Run PostgreSQL database
podman run -d \
--name my-postgres \
-e POSTGRES_PASSWORD=mypassword \
-e POSTGRES_DB=testdb \
-p 5432:5432 \
postgres:alpine
# Check if database is running
podman ps
# Connect to database
podman exec -it my-postgres psql -U postgres -d testdb
# Inside database
\l
CREATE TABLE users (id serial, name text);
INSERT INTO users (name) VALUES ('Alice'), ('Bob');
SELECT * FROM users;
\q
# Stop and remove database
podman stop my-postgres
podman rm my-postgres
What this does: Runs a complete database in a container! ๐
Example 2: Multi-Container Application ๐ก
What weโre doing: Running multiple connected containers together.
# Create a pod (group of containers)
podman pod create --name my-app-pod -p 8080:80 -p 3306:3306
# Run database in pod
podman run -d \
--pod my-app-pod \
--name app-database \
-e MYSQL_ROOT_PASSWORD=rootpass \
-e MYSQL_DATABASE=appdb \
mysql:8.0
# Run web application in same pod
podman run -d \
--pod my-app-pod \
--name app-web \
nginx:alpine
# List pod contents
podman pod ps
podman ps --pod
# Stop entire pod
podman pod stop my-app-pod
# Remove pod and all containers
podman pod rm my-app-pod
What this does: Creates grouped containers that work together! ๐
๐จ Fix Common Problems
Problem 1: Container wonโt start โ
What happened: Container exits immediately with error. How to fix it: Check container logs and image!
# Check container logs
podman logs container-name
# Run container interactively for debugging
podman run -it --entrypoint /bin/sh image-name
# Check image details
podman inspect image-name
# Try different command
podman run image-name /bin/ls -la
Problem 2: Port already in use โ
What happened: Cannot bind to port because itโs busy. How to fix it: Check whatโs using the port!
# Find what's using port 8080
ss -tulpn | grep 8080
# Use different port
podman run -p 8081:80 nginx:alpine
# Stop container using port
podman stop $(podman ps -q --filter "publish=8080")
Problem 3: Permission denied errors โ
What happened: Container cannot access files or directories. How to fix it: Check file permissions and user mapping!
# Run container with your user ID
podman run --user $(id -u):$(id -g) alpine:latest id
# Mount directory with proper permissions
podman run -v ~/data:/data:Z alpine:latest ls -la /data
# Fix SELinux context (if needed)
podman run -v ~/data:/data:z alpine:latest touch /data/test
Donโt worry! These problems happen to everyone. Youโre doing great! ๐ช
๐ก Simple Tips
- Use rootless containers ๐ - Safer than running as root
- Name your containers ๐ฑ - Easy to manage with meaningful names
- Clean up regularly ๐ค - Remove unused containers and images
- Use pods for multi-container apps ๐ช - Better organization
โ Check Everything Works
Letโs make sure everything is working:
# Test basic container functionality
podman run --rm alpine:latest echo "Podman test successful!"
# Check images are available
podman images
# Test building images
echo "FROM alpine:latest" | podman build -t test-build -
# Test pod functionality
podman pod create --name test-pod
podman pod rm test-pod
# Check system status
podman system info | grep -E "(version|rootless)"
echo "Podman is working perfectly! โ
"
Good output:
Podman test successful!
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine latest c059bfaa849c 2 days ago 5.59 MB
test-build latest a1b2c3d4e5f6 now 5.59 MB
version: 4.7.2
rootless: true
Podman is working perfectly! โ
๐ What You Learned
Great job! Now you can:
- โ Install and configure Podman on Alpine Linux
- โ Run and manage containers without root access
- โ Build custom container images with Dockerfile
- โ Use pods to group related containers together!
๐ฏ Whatโs Next?
Now you can try:
- ๐ Learning about container networking and volumes
- ๐ ๏ธ Building CI/CD pipelines with Podman
- ๐ค Setting up container registries and image sharing
- ๐ Creating microservices with container orchestration!
Remember: Every container expert was once a beginner. Youโre doing amazing! ๐
Keep practicing and youโll become an expert too! ๐ซ