
얼마 전 작은 웹사이트를 옮기면서 도커 설치부터 다시 확인할 일이 있었다. 서버 사양은 넉넉했는데, 실제로 시간을 잡아먹은 건 메모리가 아니라 패키지 출처와 포트 설정이었다. 컨테이너가 실행됐다는 메시지만 보고 이전을 시작하면 이런 부분을 놓치기 쉽다.
설치 전에 서버 상태부터 확인한다
여기서는 우분투 24.04 서버를 기준으로 한다. 접속한 서버의 운영체제와 버전은 cat /etc/os-release, CPU 구조는 uname -m으로 확인한다. 다른 배포판에 같은 패키지 명령을 그대로 넣으면 설치가 실패하거나 관리 방식이 달라질 수 있다. 웹호스팅 상품도 구분해야 한다. SSH 접속이 가능해도 관리자 권한이 없는 공유 호스팅에서는 도커 엔진을 직접 설치할 수 없는 경우가 많다.
설치 전에는 기존 도커 패키지와 운영 중인 컨테이너가 있는지 확인한다. docker --version으로 명령이 이미 잡히는지 보고, 사용 중이라면 sudo docker ps -a와 sudo docker volume ls를 확인한다. 기존 서버에 설치된 도커를 새 명령으로 덮어쓰는 작업은 신규 설치와 다르다. 이미지보다 볼륨에 들어 있는 데이터와 서비스 중단 시간을 먼저 살펴야 한다.
작은 테스트용 컨테이너 하나라면 비싼 VPS부터 고를 이유는 없다. 다만 메모리 1GB 서버에 데이터베이스, 웹서버, 관리 도구를 한꺼번에 올리면 이미지 다운로드와 재시작 과정에서도 여유가 부족할 수 있다. CPU 사용률보다 사용 가능한 메모리와 디스크 공간을 먼저 확인하는 편이 실무에서는 도움이 됐다.
우분투 패키지로 도커 설치하기
우분투 24.04의 기본 저장소를 쓰는 가장 단순한 방법은 sudo apt update를 실행한 뒤 sudo apt install docker.io docker-compose-v2를 실행하는 것이다. docker.io는 우분투가 관리하는 엔진 패키지이고, docker-compose-v2는 여러 컨테이너를 묶어 실행할 때 쓰는 Compose 명령을 제공한다. 패키지를 찾지 못한다면 저장소 설정을 확인한다. 설치 명령을 여러 출처에서 한 줄씩 섞어 쓰지는 않는다.
최신 기능이나 도커가 배포하는 버전을 특정해 운영해야 한다면 도커 공식 패키지 저장소를 등록하는 방식이 맞다. 그 경우 서명 키와 패키지 저장소를 설정한 다음 docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, docker-compose-plugin을 설치한다. 우분투의 docker.io와 공식 저장소의 docker-ce는 출처가 다르므로, 기존 패키지가 있는 서버에서는 도커 공식 설치 문서의 충돌 패키지 목록을 확인한 뒤 전환해야 한다. 운영 서버에서는 설치 스크립트를 바로 내려받아 실행하는 방식보다 패키지 출처와 업그레이드 경로가 보이는 쪽을 택한다.
설치가 끝나면 sudo systemctl enable --now docker로 서비스를 시작하고 부팅 시 자동 실행되도록 설정한다. 이어서 sudo systemctl status docker로 실행 상태를 본다. 상태 화면이 길게 열리면 q를 눌러 나온다. 여기까지는 엔진이 켜졌다는 뜻이지, 외부 서비스가 정상이라는 뜻은 아니다.
테스트 컨테이너로 설치 상태 확인하기
sudo docker run --rm hello-world를 실행하면 테스트 이미지를 받아 짧은 메시지를 출력한 뒤 컨테이너가 종료된다. 이 명령이 성공하면 명령 도구가 엔진에 연결되고, 이미지를 내려받아 컨테이너를 실행하는 기본 경로가 통과한 것이다. sudo docker compose version도 실행해 Compose 명령이 준비됐는지 확인한다. 버전 명령만 성공하고 테스트 이미지 실행이 실패한다면 설치 파일보다 엔진 상태나 이미지 다운로드 경로를 봐야 한다.
sudo 없이 docker ps를 실행했을 때 권한 오류가 나는 것은 흔하다. 편의상 사용자를 docker 그룹에 넣는 안내도 많지만, 도커 공식 문서에 따르면 이 그룹에는 사실상 관리자 수준의 권한이 따른다. 운영 서버에서는 관리 계정을 무턱대고 그룹에 추가하기보다 sudo 사용 범위를 정하는 편이 낫다. 여러 사람이 접속하는 서버라면 더 신중해야 한다.
테스트가 성공한 다음에야 실제 웹 서비스를 올린다. 이때 컨테이너의 포트를 공개하면 호스트 방화벽 규칙만 보고 접근 가능 범위를 판단해서는 안 된다. 도커가 만든 포트 전달 규칙 때문에 예상과 다르게 외부에서 접속될 수 있다. 내부 관리 화면이나 데이터베이스는 외부 공개 포트로 열지 말고, 서버 안에서만 써야 하는 포트는 로컬 주소에 묶어 설정한다. 클라우드 방화벽과 서버의 포트 설정도 함께 확인한다.
첫 서비스 전에는 백업 경로를 정한다
도커 설치 자체보다 사고가 많이 나는 지점은 데이터 저장 위치다. 컨테이너를 지우고 다시 만들 수 있어도 데이터베이스 파일과 업로드 파일은 그렇게 다룰 수 없다. 서비스 설정에서 이름 있는 볼륨이나 호스트 디렉터리 중 무엇을 쓰는지 확인하고, 백업 대상에 포함한다. 이미지 목록만 저장해 두는 것은 데이터 백업이 아니다.
데이터베이스는 파일을 사용 중일 때 단순 복사하면 복원 시점에 문제가 생길 수 있다. 데이터베이스가 제공하는 덤프 기능을 쓰거나 서비스를 멈춘 상태에서 백업 절차를 잡는다. 백업 파일은 같은 서버의 같은 디스크에만 두지 말고 다른 저장소에도 보관한다. 저는 새 서버에 도커를 올린 날 백업 명령보다 복원 과정을 먼저 한 번 실행해 본다. 복원이 되는지 확인해야 이전 날짜를 잡을 수 있다.
설치 뒤 웹사이트가 열리지 않으면 순서를 좁혀 가면 된다. 먼저 sudo systemctl status docker로 엔진을 보고, sudo docker ps -a로 컨테이너가 종료됐는지 확인한다. 종료됐다면 sudo docker logs 컨테이너이름으로 애플리케이션 오류를 본다. 컨테이너가 살아 있다면 포트 연결, 서버 방화벽, 클라우드 방화벽 순으로 확인한다. 작은 사이트일수록 서버를 키우기 전에 이 순서를 지키는 편이 빠르고 비용도 적게 든다.
