화. 7월 22nd, 2025

Hello fellow developers and tech enthusiasts! 👋 Have you ever found yourself in “dependency hell” or struggling to get your application to run consistently across different environments? If so, then you’ve likely heard of Docker, the revolutionary platform that has transformed how we build, ship, and run applications.

Docker isn’t just a buzzword; it’s an indispensable tool in the modern developer’s arsenal. At its core, Docker simplifies the process of packaging applications into standardized units called “containers.” These containers include everything an application needs to run: code, runtime, system tools, libraries, and settings. This ensures your software works seamlessly, regardless of where it’s deployed.

In this comprehensive guide, we’ll peel back the layers and explore the most commonly used Docker features that will empower you to streamline your development workflow, ensure consistency, and deploy with confidence. Let’s dive in! 🚀


1. Understanding the Core Concepts: Images & Containers 📦

Before we jump into commands, it’s crucial to grasp Docker’s fundamental building blocks:

  • Docker Image: Think of an image as a lightweight, standalone, executable package that includes everything needed to run a piece of software, including the code, a runtime, libraries, environment variables, and config files. It’s a read-only template that defines what a container will be. You can create your own images (via a Dockerfile) or pull pre-built ones from registries like Docker Hub.

  • Docker Container: A container is a runnable instance of an image. When you run an image, you create a container. You can have multiple containers running from the same image, each isolated from the others and from the host system. Containers are ephemeral by default – they don’t save their state when stopped unless explicitly configured.


2. The Command Line Interface (CLI): Your Docker Control Panel 🛠️

Most of your interactions with Docker will be through its powerful command-line interface. Let’s explore the essential commands.

2.1. Getting and Building Images

  • docker pull – Fetching Images from Registries This command allows you to download pre-built Docker images from Docker registries (like Docker Hub, Google Container Registry, etc.) to your local machine.

    # Pull the latest Ubuntu image
    docker pull ubuntu:latest
    
    # Pull a specific version of Node.js
    docker pull node:16-alpine

    This is often the first step when you want to use an existing base image for your application.

  • docker build – Creating Your Custom Images While docker pull gets you pre-made images, docker build is how you create your own custom images based on a Dockerfile. A Dockerfile is a text file that contains a set of instructions on how to build a Docker image.

    Example Dockerfile for a simple Python Flask application:

    # Use an official Python runtime as a parent image
    FROM python:3.9-slim-buster
    
    # Set the working directory in the container
    WORKDIR /app
    
    # Copy the current directory contents into the container at /app
    COPY . /app
    
    # Install any needed packages specified in requirements.txt
    RUN pip install --no-cache-dir -r requirements.txt
    
    # Expose port 5000 (Flask default)
    EXPOSE 5000
    
    # Define environment variable
    ENV FLASK_APP=app.py
    
    # Run app.py when the container launches
    CMD ["flask", "run", "--host=0.0.0.0"]

    Building the image: Navigate to the directory containing your Dockerfile and run:

    # Build an image named 'my-flask-app' with tag '1.0'
    # The '.' indicates the build context (current directory)
    docker build -t my-flask-app:1.0 .

    This command reads the Dockerfile and executes each instruction, creating a new image layer by layer.

2.2. Running and Managing Containers

  • docker run – Launching Containers This is arguably the most frequently used command! It creates and starts a new container from a specified image.

    # Run an Nginx web server in detached mode (-d)
    # Map host port 8080 to container port 80 (-p 8080:80)
    # Give the container a custom name (--name my-web-server)
    docker run -d -p 8080:80 --name my-web-server nginx:latest
    
    # Run the Flask app image we built earlier
    docker run -d -p 5000:5000 --name my-python-app my-flask-app:1.0

    You can now access your Nginx server at http://localhost:8080 and your Flask app at http://localhost:5000.

  • docker ps – Listing Running Containers Need to see what containers are currently active?

    # List all running containers
    docker ps
    
    # List all containers (including stopped ones)
    docker ps -a

    This gives you a quick overview of container IDs, images, commands, creation time, status, ports, and names.

  • docker stop, docker start, docker restart – Managing Container Lifecycle These commands allow you to control the state of your containers.

    # Stop a running container by name or ID
    docker stop my-web-server
    
    # Start a stopped container
    docker start my-web-server
    
    # Restart a running or stopped container
    docker restart my-python-app
  • docker rm – Removing Containers Once you’re done with a container, it’s good practice to remove it to free up resources.

    # Remove a stopped container
    docker rm my-web-server
    
    # Force remove a running container (use with caution!)
    docker rm -f my-python-app
  • docker rmi – Removing Images Similarly, you can remove images that you no longer need. Note that you can’t remove an image if a container is still using it.

    # Remove an image by name and tag
    docker rmi my-flask-app:1.0
    
    # Remove an image by ID (useful if multiple tags point to same image)
    docker rmi 

3. Interacting with Your Running Containers 💬

Sometimes you need to peek inside a running container or see its output.

  • docker exec – Running Commands Inside a Container This is incredibly useful for debugging or performing administrative tasks within a running container.

    # Get an interactive shell (bash) inside 'my-web-server'
    # -i: interactive, -t: allocate a pseudo-TTY
    docker exec -it my-web-server bash
    
    # Once inside, you can run Linux commands, e.g.,
    # ls -l /etc/nginx
    # exit (to leave the container's shell)
    
    # Run a non-interactive command (e.g., check process status)
    docker exec my-python-app ps aux
  • docker logs – Viewing Container Logs Containers typically output logs to stdout and stderr. docker logs allows you to view them.

    # View logs for 'my-python-app'
    docker logs my-python-app
    
    # Follow the logs in real-time (like 'tail -f')
    docker logs -f my-python-app
    
    # Show only the last 10 lines
    docker logs --tail 10 my-python-app

    This is your go-to for troubleshooting why an application isn’t behaving as expected.


4. Data Persistence and Networking: Keeping Things Connected & Safe 💾🌐

Containers are designed to be ephemeral. What if your application needs to store data persistently, or communicate with other services?

  • Volumes – Persistent Data Storage By default, any data written inside a container is lost when the container is removed. Volumes solve this by allowing you to persist data outside the container on the host machine.

    There are two main types of volumes:

    1. Bind Mounts: You explicitly map a directory on your host machine to a directory inside the container. Great for development, as changes on your host are immediately reflected in the container.
      # Mount the current directory (where app code lives) into /app inside the container
      # This is great for development as code changes on host instantly reflect in container
      docker run -d -p 5000:5000 --name dev-app -v $(pwd):/app my-flask-app:1.0
    2. Named Volumes: Docker manages the location of the data on the host. This is preferred for production data.

      # Create a named volume
      docker volume create my-data
      
      # Run a PostgreSQL container and store data in 'my-data' volume
      docker run -d \
        --name my-postgres \
        -e POSTGRES_PASSWORD=mysecretpassword \
        -v my-data:/var/lib/postgresql/data \
        postgres:13

      Even if you stop and remove my-postgres, the my-data volume (and your database) will persist.

  • Networks – Enabling Container Communication By default, containers on the same Docker host can communicate via the default bridge network. However, for more complex setups, creating custom networks provides better isolation and easier service discovery.

    # Create a custom bridge network
    docker network create my-app-network
    
    # Run a database container on this network
    docker run -d \
      --name db-service \
      --network my-app-network \
      -e MYSQL_ROOT_PASSWORD=secret \
      mysql:8
    
    # Run your application container on the same network
    # It can now resolve 'db-service' by its name
    docker run -d \
      --name app-service \
      --network my-app-network \
      -p 80:80 \
      my-web-app:latest

    Containers on the same user-defined network can communicate with each other using their container names as hostnames (e.g., your app can connect to db-service).


5. Docker Compose: Orchestrating Multi-Container Applications 🚀

While individual Docker commands are powerful, real-world applications often consist of multiple services (e.g., a web app, a database, a cache, a message queue). Manually managing these with docker run commands can quickly become tedious and error-prone.

Enter Docker Compose! It’s a tool for defining and running multi-container Docker applications. You define your entire application stack in a single YAML file (docker-compose.yml), and then launch it with a single command.

Example docker-compose.yml for a simple Flask app with a PostgreSQL database:

version: '3.8' # Specify Compose file format version

services:
  web:
    build: . # Build the image from the Dockerfile in the current directory
    ports:
      - "5000:5000" # Map host port 5000 to container port 5000
    volumes:
      - .:/app # Bind mount current directory for live code changes during development
    environment:
      DATABASE_URL: postgresql://user:password@db:5432/mydatabase
    depends_on:
      - db # Ensure 'db' service starts before 'web'

  db:
    image: postgres:13 # Use a pre-built PostgreSQL image
    environment:
      POSTGRES_DB: mydatabase
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data # Persist DB data using a named volume

volumes:
  postgres_data: # Define the named volume

Using Docker Compose:

Navigate to the directory containing your docker-compose.yml file and run:

# Build images (if specified) and start all services in detached mode
docker compose up -d

# View the status of all services
docker compose ps

# Stop and remove all services, networks, and volumes (if not explicitly declared external)
docker compose down

Docker Compose simplifies complex deployments, making your application reproducible and easy to manage across different environments. It’s a game-changer for local development and CI/CD pipelines.


Conclusion: Your Journey with Docker Starts Now! 🐳

You’ve now got a solid understanding of Docker’s most frequently used features: from pulling and building images to running and interacting with containers, managing persistent data, connecting services via networks, and orchestrating entire applications with Docker Compose.

Docker empowers you to:

  • Ensure Consistency: “It works on my machine” becomes “It works everywhere.”
  • Simplify Deployment: Package your app and all its dependencies into one portable unit.
  • Isolate Environments: Prevent conflicts between applications and dependencies.
  • Accelerate Development: Spin up services quickly and consistently for local testing.

This guide covers the essentials, but Docker is a vast and powerful ecosystem. The best way to learn is by doing! Experiment with these commands, containerize your own applications, and explore advanced topics like Docker Swarm, Kubernetes, and continuous integration.

Happy containerizing! If you have any questions or want to share your Docker journey, drop a comment below. 👇 G

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다