화. 8월 12th, 2025

G: Are you ready to dive into the world of containers and supercharge your development workflow? 🚀 If you’re an Ubuntu user, you’ve chosen a fantastic platform to host your Docker adventures. This comprehensive, A-Z guide will walk you through installing the latest versions of Docker Engine and Docker Compose on Ubuntu, perfect for beginners! No more “it works on my machine” excuses! 😉


Table of Contents:

  1. What is Docker and Why Should You Care? 🐳
  2. What is Docker Compose and Why Do You Need It? ✨
  3. Prerequisites for Installation ✅
  4. Step 1: Preparing Your Ubuntu System (Updates & Cleanup) 🧹
  5. Step 2: Installing Docker Engine (The Official Way!) 📦
  6. Step 3: Post-Installation Steps (Crucial for a Smooth Experience) ⚙️
  7. Step 4: Installing Docker Compose (The Easy Way!) 🚀
  8. Basic Docker & Docker Compose Usage Examples 💡
  9. Troubleshooting Common Issues ⚠️
  10. Conclusion & Next Steps 🎉

1. What is Docker and Why Should You Care? 🐳

Imagine you’re building a fantastic web application. It needs Python, a specific version of Node.js, PostgreSQL for the database, and maybe Redis for caching. Traditionally, you’d install all these directly on your machine. But what happens when you work on another project that needs different versions of these tools? Or when you want to deploy your app to a server? Version conflicts, missing dependencies, and “it worked on my machine!” nightmares ensue. 😱

Docker solves this by packaging your application and all its dependencies into a standardized unit called a container. Think of a container as a lightweight, standalone, executable package that includes everything needed to run a piece of software: code, runtime, system tools, libraries, and settings.

Key Benefits of Docker:

  • Consistency: Your application runs the same way, everywhere – from your laptop to the production server. Say goodbye to “works on my machine”!
  • Isolation: Containers isolate applications from each other and from the host system, preventing conflicts.
  • Portability: Containers can run on any system that has Docker installed, regardless of the underlying operating system (Linux, Windows, macOS).
  • Efficiency: Containers are much lighter than traditional virtual machines (VMs), starting in seconds and using fewer resources.
  • Scalability: Easily scale your applications by running multiple instances of your containers.

2. What is Docker Compose and Why Do You Need It? ✨

While Docker is amazing for individual containers, real-world applications often consist of multiple services. For example, a web app might have a web server, a database, and a caching service. Managing these interdependent containers manually can become cumbersome.

Docker Compose comes to the rescue! It’s a tool for defining and running multi-container Docker applications. You use a YAML file (usually docker-compose.yml) to configure all your application’s services, networks, and volumes. Then, with a single command (docker compose up), Compose spins up and orchestrates all the services you defined.

Key Benefits of Docker Compose:

  • Simplifies Multi-Container Apps: Define all services in one easy-to-read file.
  • Single-Command Setup: Start your entire application stack with just one command.
  • Reproducibility: Easily share your application stack with team members; everyone gets the exact same environment.
  • Environment Management: Define different environments (development, testing, production) using separate Compose files or environment variables.

3. Prerequisites for Installation ✅

Before we begin, make sure you have:

  • An Ubuntu System: This guide is specifically for Ubuntu (LTS versions like 20.04, 22.04, or the latest stable release are recommended).
  • Sudo Privileges: You’ll need sudo access to run administrative commands.
  • Internet Connection: To download packages and Docker images.

4. Step 1: Preparing Your Ubuntu System (Updates & Cleanup) 🧹

First, let’s ensure your system is up-to-date and remove any old, conflicting Docker installations.

  1. Update Your Package Lists: This command refreshes the list of available packages and their versions from the Ubuntu repositories.

    sudo apt update

    You’ll see output indicating it’s fetching package information.

  2. Upgrade Installed Packages: This upgrades all your currently installed packages to their latest versions. It’s always a good practice before installing new software.

    sudo apt upgrade -y

    The -y flag automatically confirms any prompts, saving you some typing. This might take a few minutes.

  3. Remove Old Docker Versions (if any): If you’ve had Docker installed before, let’s clean it up to prevent conflicts. Don’t worry if these commands return “package not found” errors; it just means those packages weren’t installed.

    sudo apt remove docker docker-engine docker.io containerd runc -y
    sudo apt autoremove -y

    These commands remove the old Docker packages and any automatically installed dependencies that are no longer needed.


5. Step 2: Installing Docker Engine (The Official Way!) 📦

We’ll install Docker Engine from its official repository, which ensures you always get the latest stable version and updates.

  1. Install Required Packages: These packages are necessary for apt to use repositories over HTTPS.

    sudo apt install ca-certificates curl gnupg lsb-release -y
    • ca-certificates: Allows web browsers and other programs to check the authenticity of secure websites.
    • curl: A tool to transfer data from or to a server, used here to download Docker’s GPG key.
    • gnupg: Enables handling of GnuPG signatures, used for verifying the authenticity of downloaded packages.
    • lsb-release: Provides information about the Linux Standard Base release, which Docker needs to determine the correct repository.
  2. Add Docker’s Official GPG Key: This key is used to verify the authenticity of Docker packages. This ensures you’re downloading genuine Docker software.

    sudo mkdir -p /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
    • sudo mkdir -p /etc/apt/keyrings: Creates the directory to store GPG keys if it doesn’t exist.
    • curl -fsSL ... | sudo gpg --dearmor ...: Downloads the GPG key, de-armors it (converts to a binary format), and saves it to the specified file.
      • -f: Fail silently on HTTP errors.
      • -s: Silent mode (don’t show progress meter or error messages).
      • -S: Show error messages (used with -s).
      • -L: Follow redirects.
  3. Set Up the Docker Repository: Now we add the Docker repository to your apt sources, telling your system where to find Docker packages.

    echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    • dpkg --print-architecture: Automatically detects your system’s architecture (e.g., amd64).
    • lsb_release -cs: Returns the codename of your Ubuntu release (e.g., jammy for Ubuntu 22.04, focal for Ubuntu 20.04).
    • deb ...: This line tells apt that Docker packages are available from the specified URL for your architecture, signed by the docker.gpg key.
    • sudo tee /etc/apt/sources.list.d/docker.list: Writes the line to a new docker.list file in your apt sources directory.
    • > /dev/null: Suppresses output to the terminal.
  4. Update apt Package Index Again: After adding a new repository, you must update your package index for the changes to take effect.

    sudo apt update
  5. Install Docker Engine, CLI, and Containerd: Finally, install the core Docker components!

    sudo apt install docker-ce docker-ce-cli containerd.io -y
    • docker-ce: The Docker Community Edition engine.
    • docker-ce-cli: The command-line interface for Docker.
    • containerd.io: A high-performance container runtime (used by Docker).
  6. Verify Docker Installation: Run the classic “hello-world” container to ensure Docker is installed and running correctly.

    sudo docker run hello-world

    You should see output similar to this, indicating a successful installation:

    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    ...
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    ...

    If you see this, give yourself a pat on the back! 🙌 Docker Engine is ready!


6. Step 3: Post-Installation Steps (Crucial for a Smooth Experience) ⚙️

By default, you need sudo to run Docker commands. This can be annoying and is not always ideal. Let’s fix that!

  1. Manage Docker as a Non-Root User (Recommended!): Add your user to the docker group so you can run Docker commands without sudo.

    sudo usermod -aG docker $USER
    • usermod: Modifies user account information.
    • -aG: Add the user to the specified group (Docker in this case).
    • $USER: A shell variable that expands to your current username.

    IMPORTANT: For this change to take effect, you need to either:

    • Log out and log back in to your Ubuntu session.
    • Run newgrp docker in your current terminal session. (This is temporary for the current session, logging out/in is more permanent for all future sessions).
    • Reboot your system (least efficient, but works).

    Let’s log out and back in for a clean start! 🚪↩️

  2. Verify Non-Root Access: After logging back in, try the hello-world command again, but without sudo:

    docker run hello-world

    If it runs successfully, you’ve done it! 🎉

  3. Configure Docker to Start on Boot: Docker is usually configured to start automatically, but it’s good to explicitly enable it.

    sudo systemctl enable docker

    This command ensures the Docker daemon starts when your system boots up.


7. Step 4: Installing Docker Compose (The Easy Way!) 🚀

Docker Compose is now distributed as a plugin for the Docker CLI. We’ll download the latest stable release directly from GitHub.

  1. Determine the Latest Docker Compose Version: We can fetch the latest stable release version dynamically to ensure you always get the newest one.

    LATEST_COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep -Po '"tag_name": "\K[^"]*')
    echo "Latest Docker Compose version: $LATEST_COMPOSE_VERSION"

    This command queries the Docker Compose GitHub releases API and extracts the latest tag name. You’ll see the version printed (e.g., v2.23.3).

  2. Download Docker Compose: Now, download the docker compose plugin binary for your architecture.

    sudo curl -L "https://github.com/docker/compose/releases/download/$LATEST_COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/lib/docker/cli-plugins/docker-compose
    • uname -s: Returns the operating system kernel name (e.g., Linux).
    • uname -m: Returns the machine hardware name (e.g., x86_64).
    • /usr/local/lib/docker/cli-plugins/: This is the recommended directory for Docker CLI plugins.
  3. Apply Executable Permissions: Make the downloaded binary executable.

    sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
  4. Verify Docker Compose Installation: Check the installed version.

    docker compose version

    You should see the version number printed (e.g., Docker Compose version v2.23.3).

    Note on docker-compose vs. docker compose: You might have seen docker-compose used in older tutorials. The newer, official way to invoke Docker Compose (especially for versions v2 and above, and when installed as a CLI plugin as we did) is docker compose (with a space). Both generally work, but docker compose is the future! ✅


8. Basic Docker & Docker Compose Usage Examples 💡

Let’s put your new tools to the test with some simple examples!

8.1 Basic Docker Commands

  • Pull an image: Download a Docker image from Docker Hub.

    docker pull ubuntu:latest

    This downloads the latest Ubuntu base image.

  • Run a container: Start a new container from an image.

    docker run -it --rm ubuntu:latest bash
    • -it: Interactive and pseudo-TTY (allows you to type commands inside the container).
    • --rm: Automatically remove the container when it exits.
    • ubuntu:latest: The image to use.
    • bash: The command to run inside the container (starts a bash shell). You’ll be inside the Ubuntu container’s bash prompt. Type exit to leave it.
  • List running containers:

    docker ps

    Shows only actively running containers.

  • List all containers (running and stopped):

    docker ps -a
  • List images:

    docker images

    Shows all downloaded Docker images.

  • Stop a container:

    docker stop 
    <container_id_or_name>

    _Replace `

    ` with the actual ID or name from `docker ps`._
  • Remove a container:

    docker rm 
    <container_id_or_name>
  • Remove an image:

    docker rmi 
    <image_id_or_name>

8.2 Basic Docker Compose Example (Nginx Web Server)

Let’s create a simple Nginx web server with a custom index.html using Docker Compose.

  1. Create a Project Directory:

    mkdir my-nginx-app
    cd my-nginx-app
  2. Create an index.html file:

    echo "
    <h1>Hello from Docker Compose!</h1>
    <p>Your Nginx web server is up and running!</p>" > index.html
  3. Create a docker-compose.yml file: Open this file in your favorite text editor (e.g., nano docker-compose.yml or code docker-compose.yml):

    version: '3.8' # Specifies the Docker Compose file format version
    
    services:
      webserver:
        image: nginx:latest # Use the latest Nginx image
        ports:
          - "80:80" # Map host port 80 to container port 80
        volumes:
          - ./index.html:/usr/share/nginx/html/index.html:ro # Mount our custom index.html
          # You can also mount a whole directory:
          # - ./nginx-conf:/etc/nginx/conf.d:ro
          # - ./my-web-content:/usr/share/nginx/html:ro
        restart: unless-stopped # Always restart unless explicitly stopped
        container_name: my-nginx-container # Give your container a friendly name
        healthcheck: # Optional: Define a health check for the service
          test: ["CMD", "curl", "-f", "http://localhost"]
          interval: 30s
          timeout: 10s
          retries: 3
    • version: '3.8': Specifies the Compose file format. Always good to use a recent version.
    • services: Defines the different services (containers) that make up your application.
    • webserver: The name of our service.
    • image: nginx:latest: Tells Docker Compose to use the nginx image from Docker Hub.
    • ports: "80:80": Maps port 80 on your host machine to port 80 inside the webserver container. This means you can access Nginx via http://localhost.
    • volumes: Mounts local paths into the container. Here, we’re replacing Nginx’s default index.html with ours. :ro means read-only.
    • restart: unless-stopped: Ensures the container restarts if it crashes or the system reboots, unless you manually stop it.
    • container_name: A custom name for the container instance.
    • healthcheck: Defines how Docker Compose can determine if the service is healthy.
  4. Start Your Application: From inside the my-nginx-app directory, run:

    docker compose up -d
    • up: Builds, creates, starts, and attaches to containers for a service.
    • -d: Detached mode (runs containers in the background).

    You’ll see output indicating Docker pulling the Nginx image (if not already present), creating the network, and starting the webserver container.

  5. Verify the Application is Running:

    docker compose ps

    You should see my-nginx-container listed with Up status.

  6. Access Your Web Server: Open your web browser and go to http://localhost. You should see “Hello from Docker Compose! Your Nginx web server is up and running!” 🎉

  7. Stop and Remove Your Application: When you’re done, you can stop and remove all services defined in your docker-compose.yml file, along with their networks and volumes.

    docker compose down

    This command cleans up all resources associated with your Compose project.


9. Troubleshooting Common Issues ⚠️

Even with a detailed guide, you might run into bumps. Here are some common issues and their solutions:

  • Permission denied or Got permission denied while trying to connect to the Docker daemon socket:

    • Reason: Your user is not in the docker group, or the changes haven’t taken effect.
    • Solution: Make sure you ran sudo usermod -aG docker $USER and then logged out and logged back in (or ran newgrp docker).
  • Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?:

    • Reason: The Docker service isn’t running.
    • Solution:
      • Start the Docker service: sudo systemctl start docker
      • Enable it to start on boot: sudo systemctl enable docker
      • Check its status: sudo systemctl status docker
  • Error response from daemon: driver failed programming external connectivity on endpoint... (Port already in use):

    • Reason: Another application on your host machine is already using the port you’re trying to map (e.g., port 80 for Nginx).
    • Solution:
      • Stop the conflicting application.
      • Change the port mapping in your docker-compose.yml (e.g., "8080:80" to use port 8080 on your host).
  • Docker Compose command not found:

    • Reason: Docker Compose binary isn’t in your PATH or wasn’t installed correctly.
    • Solution: Double-check the installation steps for Docker Compose, especially the sudo mv and sudo chmod +x commands. Ensure it’s in /usr/local/lib/docker/cli-plugins/.
  • No space left on device:

    • Reason: Your disk is full from too many Docker images, containers, or volumes.
    • Solution: Clean up unused Docker objects:
      • docker system prune: Removes stopped containers, dangling images, and unused networks.
      • docker system prune -a: Removes all of the above plus all unused images and build cache. (Use with caution!)

10. Conclusion & Next Steps 🎉

Congratulations! You’ve successfully installed Docker Engine and Docker Compose on your Ubuntu system and run your first multi-container application. You’ve taken a huge leap towards modern, efficient software development! 🚀

What’s next on your Docker journey?

  • Explore Docker Hub: Browse thousands of official and community-contributed images (e.g., databases, message queues, development environments).
  • Build Your Own Images: Learn how to create custom Docker images using Dockerfiles.
  • Persistent Data: Understand Docker volumes for storing data outside containers.
  • Networking: Dive deeper into Docker’s networking capabilities to connect containers.
  • Container Orchestration: For larger applications, explore tools like Kubernetes (though Docker Compose can handle a lot for smaller scales!).

The world of containers is vast and exciting. Keep experimenting, keep learning, and happy “dockering”! 🐳✨

답글 남기기

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