######################## 8.2 Your First Container ######################## .. image:: ../diagrams/containers.png :alt: A diagram showing the process of running your first container :width: 600 px **From Installation to Action** You've got Docker or Podman installed - now comes the exciting part: running your first container. This isn't just a "hello world" exercise; we'll explore what's actually happening behind the scenes and build practical skills you'll use every day. By the end of this section, you'll understand how containers start, how they differ from traditional processes, and how to inspect and manage them effectively. =================== Learning Objectives =================== By the end of this section, you will: • **Run** your first container and understand what happens during execution • **Explore** container internals using inspection and debugging commands • **Manage** container lifecycle (start, stop, remove, list) • **Understand** container networking and port mapping basics • **Build** confidence with essential container management commands **Prerequisites:** Completed container platform installation from the previous section ========================= The Classic "Hello World" ========================= **Your First Command** Let's start with the most famous container command in the world: .. code-block:: bash # Docker users: docker run hello-world # Podman users: podman run hello-world **What Just Happened?** When you ran this command, several important things occurred: 1. **Image Pull:** The platform downloaded the `hello-world` image from the registry 2. **Container Creation:** A new container was created from that image 3. **Process Execution:** The container ran its default command 4. **Output Display:** The program printed a message and exited 5. **Container Termination:** The container stopped (but still exists) **The Output Explained:** .. code-block:: text Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. This simple example demonstrates the entire container lifecycle in action. =========================== Understanding What Happened =========================== **Behind the Scenes** Let's verify what actually occurred and learn essential management commands: .. code-block:: bash # List all containers (including stopped ones) docker ps -a # or: podman ps -a You should see output similar to: .. code-block:: text CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES abc123def456 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago inspiring_newton **Key Information Revealed:** - **Container ID:** Unique identifier (abc123def456) - **Image:** Source image used (hello-world) - **Command:** What the container executed (/hello) - **Status:** Current state (Exited with code 0 = success) - **Names:** Random name assigned (inspiring_newton) **Inspect Container Details:** .. code-block:: bash # Get detailed container information (replace with your container ID) docker inspect abc123def456 # or: podman inspect abc123def456 This reveals everything about the container: network settings, mounted volumes, environment variables, and more. ====================== Interactive Containers ====================== **Beyond Hello World** Let's run something more interesting - an interactive Linux container: .. code-block:: bash # Run an Ubuntu container with interactive terminal docker run -it ubuntu:22.04 /bin/bash # or: podman run -it ubuntu:22.04 /bin/bash **Command Breakdown:** - `run`: Create and start a new container - `-i`: Keep STDIN open (interactive) - `-t`: Allocate a pseudo-TTY (terminal) - `ubuntu:22.04`: Use Ubuntu 22.04 LTS image - `/bin/bash`: Run bash shell instead of default command **Inside the Container:** Once inside, you're in a complete Linux environment: .. code-block:: bash # Check the operating system cat /etc/os-release # See running processes ps aux # Check available disk space df -h # Install software (try it!) apt update && apt install -y curl # Test network connectivity curl -s https://httpbin.org/ip # Exit the container exit **What's Fascinating Here:** - You're in a complete Ubuntu system, but it started in seconds - It's isolated from your host operating system - You can install software without affecting your host - When you exit, all changes are lost (unless saved) ==================== Container Management ==================== **Essential Lifecycle Commands** **Listing Containers:** .. code-block:: bash # Show running containers only docker ps # Show all containers (running and stopped) docker ps -a # Show container sizes docker ps -s # Custom formatting docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" **Starting and Stopping:** .. code-block:: bash # Start a stopped container docker start container_name_or_id # Stop a running container gracefully docker stop container_name_or_id # Force stop a container docker kill container_name_or_id # Restart a container docker restart container_name_or_id **Connecting to Running Containers:** .. code-block:: bash # Execute commands in running containers docker exec -it container_name /bin/bash # Run a single command docker exec container_name ls -la /app # Check container logs docker logs container_name # Follow logs in real-time docker logs -f container_name **Container Cleanup:** .. code-block:: bash # Remove a stopped container docker rm container_name_or_id # Remove multiple containers docker rm container1 container2 container3 # Remove all stopped containers docker container prune # Force remove a running container docker rm -f container_name ======================== Running Web Applications ======================== **A Real-World Example** Let's run a web server to understand networking: .. code-block:: bash # Run nginx web server with port mapping docker run -d -p 8080:80 --name my-web-server nginx:alpine # or: podman run -d -p 8080:80 --name my-web-server nginx:alpine **Command Explanation:** - `-d`: Run in detached mode (background) - `-p 8080:80`: Map host port 8080 to container port 80 - `--name my-web-server`: Give the container a friendly name - `nginx:alpine`: Use lightweight Alpine-based nginx image **Test Your Web Server:** .. code-block:: bash # Check if container is running docker ps # Test the web server curl http://localhost:8080 # Or open in your browser: http://localhost:8080 **Modify the Web Content:** .. code-block:: bash # Copy a file into the running container echo "