Docker 처음 시작하기: 컨테이너로 서버 환경 만들기

Docker 처음 시작하기: 컨테이너로 서버 환경 만들기

솔직히 처음엔 도커? 컨테이너? 대체 이게 뭐 하는 건가 싶었어요. 뭔가 개발자들만 쓰는 엄청 복잡한 기술처럼 들리기도 했고요. 제가 한 5년 전쯤 처음 웹 개발 시작했을 때만 해도 서버 환경 세팅한다고 밤새 씨름하고 그랬거든요. 막 버전 충돌 나고, 라이브러리 없다고 에러 뿜어대고… 생각만 해도 혈압 오르네요. 그런데 요즘은 그런 옛날이야기 하면 신기하게 쳐다보더라고요. 다 도커(Docker) 덕분입니다. 저처럼 삽질 많이 해본 분들이라면 도커가 얼마나 고마운 존재인지 아마 공감하실 거예요. 오늘은 제가 직접 도커로 서버 환경을 구축하면서 느꼈던 점들, 그리고 여러분도 쉽게 시작할 수 있도록 아주 기본적인 내용들을 풀어보려 합니다.


도커, 왜 그렇게 난리일까? (ft. 내 경험담)

요즘 개발자 커뮤니티나 기술 블로그 보면 도커 이야기가 끊이질 않죠? 심지어 올해 초 한 설문조사에서는 개발자 셋 중 둘은 도커를 실제 프로젝트에 사용하고 있거나 사용할 계획이라고 하더군요. 제가 보기엔 이런 인기의 핵심은 ‘일관성’과 ‘가벼움’ 때문인 것 같아요.

옛날에는 제 노트북에서 잘 돌아가던 코드가 서버에 올리면 왠지 모르게 에러를 뿜는 경우가 태반이었어요. 개발 환경이랑 운영 환경이 달라서 생기는 문제인데, 진짜 이럴 땐 답이 없었거든요. 그런데 도커는 애플리케이션이랑 그 주변 환경(운영체제, 라이브러리 등)을 컨테이너라는 독립적인 박스에 싹 담아버려요. 이 컨테이너는 어디에서든 똑같이 작동하니까, ‘내 컴퓨터에선 되는데!’ 하는 변명은 이제 통하지 않는 거죠. 저도 작년에 신규 서비스 배포할 때 도커 덕분에 밤샘 없이 퇴근할 수 있었던 기억이 나네요. 정말… 그때 그 쾌감이란!

블로거의 팁: 도커는 단순히 가상머신을 대체하는 도구가 아니에요. 가상머신보다 훨씬 가볍고 빠릿빠릿하죠. 가상머신이 집 한 채를 통째로 복사하는 거라면, 도커 컨테이너는 필요한 방 하나만 똑같이 만들어내는 느낌이랄까요?

게다가 컨테이너는 시작하고 멈추는 게 찰나의 순간이에요. 덕분에 서버 자원도 훨씬 효율적으로 쓸 수 있고, 필요한 서비스만 그때그때 띄울 수도 있고요. 클라우드 환경에서 특히 빛을 발하는 이유이기도 합니다. 솔직히 처음엔 반신반의했는데 써보니 ‘아, 왜 이제야 썼을까’ 싶더라고요.

Docker 설치, 생각보다 간단하다!

자, 그럼 이 좋은 도커, 어떻게 시작해야 할까요? 생각보다 간단합니다! 저는 주로 윈도우나 맥에서 개발 환경을 잡기 때문에 Docker Desktop을 사용해요. 리눅스 환경이라면 패키지 매니저로 직접 설치하는 게 일반적이고요.

Windows/macOS 사용자: Docker Desktop 설치하기

Docker Desktop은 윈도우와 macOS 사용자들을 위해 도커 환경을 편리하게 사용할 수 있도록 도와주는 프로그램이에요. 그냥 설치 파일 다운로드 받아서 다음-다음-마침 누르면 끝입니다. 참고로, Windows에서는 WSL 2(Windows Subsystem for Linux 2)가 활성화되어 있어야 제대로 동작해요. 요즘 윈도우 업데이트하면 WSL 2는 거의 기본으로 깔려있어서 크게 신경 쓸 일은 없을 거예요.

  1. Docker 공식 웹사이트에 접속합니다.
  2. 운영체제에 맞는 Docker Desktop 다운로드 버튼을 클릭합니다.
  3. 다운로드 받은 설치 파일을 실행하고 안내에 따라 설치를 완료합니다.
  4. 설치 후 Docker Desktop을 실행하면 끝! 트레이 아이콘에 고래 모양이 뜨면 성공입니다.

리눅스 사용자: 직접 설치하기 (Ubuntu 기준)

리눅스는 조금 더 터미널 친화적이죠. 우분투를 예로 들어볼게요.


# 기존 도커 관련 패키지 삭제 (혹시 모를 충돌 방지)
sudo apt-get remove docker docker-engine docker.io containerd runc

# apt 패키지 인덱스 업데이트 및 필요 패키지 설치
sudo apt-get update
sudo apt-get install  
    ca-certificates  
    curl  
    gnupg  
    lsb-release

# Docker 공식 GPG 키 추가
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# Docker APT 저장소 설정
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

# Docker 설치
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 설치 확인
sudo docker run hello-world

hello-world 이미지를 실행했을 때 축하 메시지가 뜨면 성공적으로 설치된 거예요. 혹시 sudo 없이 도커 명령어를 쓰고 싶다면, 사용자 계정을 docker 그룹에 추가해주면 됩니다. (sudo usermod -aG docker $USER 입력 후 로그아웃/로그인)

나만의 첫 도커 컨테이너 만들어보기

설치를 마쳤으니 이제 실제로 컨테이너를 한번 만들어봐야겠죠? 저는 Node.js 기반의 간단한 웹 서버를 예시로 들어볼게요. 뭐, 어떤 언어든 개념은 똑같습니다.

1단계: 프로젝트 폴더 및 파일 준비

먼저, 프로젝트를 위한 폴더를 만들고 그 안에 간단한 app.js 파일과 Dockerfile을 생성합니다.


// app.js
const http = require('http');

const hostname = '0.0.0.0';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('안녕하세요, Docker 세상에 오신 것을 환영합니다!n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

# Dockerfile
# Node.js 20 버전 이미지를 기반으로 시작합니다. (2026년 최신 LTS 버전)
FROM node:20-alpine

# 컨테이너 내 작업 디렉토리 설정
WORKDIR /app

# package.json과 package-lock.json을 복사 (의존성 설치 최적화)
# COPY package*.json ./
# RUN npm install

# 위 예제에서는 간단하게 진행하기 위해 npm install 생략. 실제 프로젝트에서는 반드시 필요!

# 현재 디렉토리의 모든 파일을 컨테이너의 /app 디렉토리로 복사
COPY . .

# 3000번 포트를 외부에 노출합니다.
EXPOSE 3000

# 애플리케이션 실행 명령어
CMD ["node", "app.js"]

Dockerfile은 Node.js 20 버전의 경량 리눅스(Alpine) 이미지를 기반으로 해서, 우리 app.js 파일을 컨테이너에 넣고, 3000번 포트를 열어서 실행하라는 명령을 담고 있어요. 정말 직관적이죠? 처음엔 이 Dockerfile 문법이 좀 낯설었는데, 몇 번 해보니 금방 익숙해지더라고요.

2단계: 도커 이미지 빌드하기

Dockerfile이 준비되었다면, 이제 이 설계도를 바탕으로 도커 이미지(Docker Image)를 만들어야 합니다. 이미지는 컨테이너를 찍어내는 템플릿이라고 생각하면 돼요. 터미널을 열고 프로젝트 폴더로 이동한 다음 아래 명령어를 입력해보세요.


docker build -t my-node-app .
  • docker build: 이미지를 빌드하는 명령어
  • -t my-node-app: 빌드할 이미지에 my-node-app이라는 이름과 기본 태그(latest)를 부여합니다.
  • .: 현재 디렉토리에서 Dockerfile을 찾아 빌드하라는 의미입니다.

성공적으로 빌드되면 Successfully tagged my-node-app:latest 같은 메시지가 보일 거예요. docker images 명령어로 방금 만든 이미지를 확인할 수 있습니다.

3단계: 컨테이너 실행하기

이미지가 준비되었으니 이제 이 이미지를 가지고 컨테이너를 실행해볼 차례입니다. 이게 바로 우리가 서버 환경을 구축하는 과정인 거죠!


docker run -p 80:3000 --name my-web-server my-node-app
  • docker run: 컨테이너를 실행하는 명령어
  • -p 80:3000: 호스트(내 컴퓨터)의 80번 포트를 컨테이너의 3000번 포트에 연결합니다. 이렇게 해야 내 웹 브라우저에서 접속할 수 있어요.
  • --name my-web-server: 컨테이너에 my-web-server라는 이름을 붙여줍니다. 나중에 관리하기 편해요.
  • my-node-app: 실행할 이미지 이름입니다.

명령어를 실행하면 Server running at http://0.0.0.0:3000/ 같은 메시지가 보일 겁니다. 이제 웹 브라우저를 열고 http://localhost 또는 http://127.0.0.1로 접속해보세요. 제가 작성한 app.js의 메시지가 보인다면 성공입니다! 정말 신기하지 않나요?

블로거의 팁: 컨테이너는 기본적으로 백그라운드에서 실행되지 않아요. -d 옵션을 추가하면 백그라운드에서 실행시킬 수 있습니다. 예: docker run -d -p 80:3000 --name my-web-server my-node-app

컨테이너 관리: 명령어 몇 가지만 알면 끝!

컨테이너를 만들고 실행하는 것만큼 중요한 게 관리하는 거죠. 몇 가지 유용한 명령어들을 알려드릴게요. 저도 처음에 이것저것 검색해가며 익혔는데, 이 정도만 알아도 웬만한 작업은 다 가능해요.

명령어 설명 예시
docker ps 현재 실행 중인 컨테이너 목록 확인 docker ps -a (모든 컨테이너 포함)
docker stop 실행 중인 컨테이너 정지 docker stop my-web-server
docker start 정지된 컨테이너 시작 docker start my-web-server
docker rm 컨테이너 삭제 (정지된 컨테이너만 가능) docker rm my-web-server
docker rmi 도커 이미지 삭제 docker rmi my-node-app
docker logs 컨테이너의 로그 확인 docker logs my-web-server
docker exec 실행 중인 컨테이너 내부에서 명령어 실행 docker exec -it my-web-server /bin/bash (bash 셸 접속)

저는 보통 docker ps -a로 뭐가 돌아가고 있는지 보고, 필요 없는 건 docker stopdocker rm으로 정리하는 편이에요. 덕분에 제 PC도 깔끔하게 유지되고, 프로젝트별로 필요한 환경만 딱딱 띄울 수 있어서 정말 편하더라고요. 여러분도 이것저것 실행해보면서 명령어에 익숙해지는 걸 추천합니다!

오늘 이렇게 도커의 아주 기본적인 내용들을 함께 살펴봤어요. 어떠셨나요? 처음엔 복잡해 보이지만, 한 번 맛 들이면 이 편리함에서 헤어나올 수 없을 거예요. 특히 요즘처럼 마이크로서비스 아키텍처나 클라우드 환경이 대세인 시대에는 도커는 거의 필수적인 기술이 되어가고 있습니다. 2026년 현재, 개발자로서 도커를 모른다면… 음, 조금 답답한 상황을 마주할 수도 있다고 저는 생각해요. 그러니 망설이지 말고 지금 바로 시작해보세요! 궁금한 점이 있다면 언제든 댓글로 남겨주시고요. 제가 아는 선에서 최대한 도와드리겠습니다.

자주 묻는 질문 (FAQ)

도커 컨테이너는 가상 머신(VM)과 뭐가 다른가요?
가상 머신은 호스트 OS 위에 게스트 OS 전체를 가상화하지만, 도커 컨테이너는 호스트 OS의 커널을 공유하며 애플리케이션 실행에 필요한 환경만 격리합니다. 이 덕분에 컨테이너는 VM보다 훨씬 가볍고 빠르며, 자원 효율성이 뛰어납니다.
도커 이미지는 한 번 만들면 계속 재사용할 수 있나요?
네, 맞습니다! 도커 이미지는 한 번 빌드하면 동일한 환경을 가진 여러 개의 컨테이너를 찍어내는 ‘템플릿’처럼 사용할 수 있습니다. 다른 서버에서도 이 이미지를 가져와 똑같은 환경으로 컨테이너를 실행할 수 있어요.
Dockerfile에서 EXPOSE 명령어는 어떤 역할을 하나요?
EXPOSE는 해당 컨테이너가 어떤 포트를 외부에 노출할 것인지 선언하는 역할을 합니다. 실제로 포트가 열리거나 접근 가능하게 되는 것은 아니며, 주로 문서화 목적으로 사용됩니다. 실제 포트 연결은 docker run -p 옵션을 통해 이루어집니다.
도커 컨테이너 안에서 데이터는 어떻게 관리하나요? 컨테이너가 삭제되면 데이터도 사라지나요?
기본적으로 컨테이너 내부에 생성된 데이터는 컨테이너가 삭제되면 함께 사라집니다. 중요한 데이터를 영구적으로 보관하려면 볼륨(Volume)이나 바인드 마운트(Bind Mount) 기능을 사용해야 합니다. 이는 컨테이너 외부의 호스트 파일 시스템과 연결하여 데이터를 보존하는 방법이에요. 이건 다음 기회에 더 자세히 다뤄볼게요!