내가 만든 소스코드는 서버에 배포되어야 비로소 사용 가치가 생깁니다. 개발자는 머리가 아픕니다. 클라이언트의 요구사항에 맞춰 소스코드를 작성하는 데 온전히 집중하고 싶지만, 기획부터 디자인, 개발부터 배포까지 과정이 왜 이리 험난한지 모르겠습니다.
도커를 알기 전, 개발자 고땡땡은 서버에 배포 환경을 직접 구성하는 방법을 사용해왔습니다. 기본적인 준비물은 다음과 같습니다.
고땡땡은 이렇게 환경을 구성한 후, 기능 개발이 완료될 때마다 파일 전송 프로토콜(FTP)을 통해 소스코드 결과물을 서버에 전송하여 배포했습니다.
어느 날, 개발자 고땡땡은 난처한 상황과 마주하게 됩니다. 시간이 지나 새로운 프로젝트에 참여하게 되었고, 배포하려고 기존에 세팅되어 있는 서버에 소스코드를 올렸더니 에러가 발생한 것입니다.
상황은 이렇습니다.
겁 없는 개발자 고땡땡은 과감하게 서버의 Node.js 버전을 14.x로 올렸고, 다행히도 기존 프로젝트에 별 문제가 발생하지 않았습니다. 정말 운이 좋게 큰일 없이 넘어갔지만, 기존 프로젝트는 여전히 운영 중이었고, 문제가 생겼다면 어떻게 되었을지 생각만 해도 끔찍합니다. 실제로 그 당시에는 마음고생이 컸던 것도 사실입니다.
위에서 보는 사례는 생각보다 흔하게 접할 수 있는 문제들 입니다. 하나의 물리적인 서버에 여러 애플리케이션을 배포하게 될 경우 애플리케이션이 사용하는 의존성들이 얽히기 때문에 일어나는 일인데요. 이것은 하나의 예일 뿐이지만, 도커는 이 상황에서 충분히 사용할만한 가치가 생깁니다. 프로젝트의 개발환경을 독립적으로 가져갈 수 있기 때문이죠.
도커를 사용하기 전 위 사례의 모습은 다음과 같습니다. 여러 프로젝트가 OS에 설치된 같은 의존성을 바라보기 때문에 충돌 문제나 버전을 달리 가져가야하는 문제, 설정이 겹치는 등 관리하기가 까다롭습니다.
반면 도커를 이용하여 서버를 구성하게 되면 다음과 같이 보일거에요. os 에 도커를 설치하고 이미 프로젝트를 실행시킬 수 있는 모든 구성을 로컬 환경에서 도커 이미지로 만들어 서버에 전달을 하는거죠. 그리고 서버는 전달받은 이미지를 컨테이너화 하여 실행시킵니다. 각각 개별적인 환경을 가지고 있기 때문에 충돌이 날 걱정은 없겠죠? 어썸합니다.
물론 도커가 장점만 있는것은 아닙니다. 각 프로젝트마다 개별적인 개발환경을 가져가기 위해 각각의 프로젝트의 몸집이 더 커질 수 밖에 없습니다. 서버입장에서는 더 많은 리소스가 들어간다고 생각할 수 있겠네요.
위 상황은 개발하면 떠오르는 절대적인 구도 성능VS유지보수 입니다. 두 가지 모두 중요하지만 유지보수성과 성능은 반비례합니다. 둘 다 완벽하게 챙기기 힘들기 때문에 적당한 타협을 봐야한다고 생각하는데요. 다들 어떤 것이 더 중요하다고 생각하는지 궁금합니다 ㅎㅎ
일반적인 도커 사용방법
이제 도커를 사용하여 소스코드를 배포하도록 해보죠. 먼저 로컬, 서버 환경에 모두 도커 시스템이 설치되어있어야 합니다.
프로젝트를 실행시킬 수 있는 환경을 미리 구성을 해야합니다. 바로 Dockerfile 이라는 파일에 프로젝트를 실행시키기 위해 설치해야하는 의존성부터 실행 스크립트까지 명세를 작성하는건데요.
프로젝트 root 경로에 Dockerfile을 만들어 다음과 같이 구성할 수 있습니다. Dockerfile은 프로젝트에 맞게 구성해야하며, GPT와 협력하고 삽질하며 구성해보시기 바랍니다.
Dockerfile이 작성되어 있다면, 이를 사용하여 Docker 이미지를 생성할 수 있습니다. 이 이미지에는 프로젝트를 실행하는 데 필요한 모든 구성 요소가 포함됩니다.
Docker 이미지를 생성하는 명령어는 다음과 같습니다. 프로젝트 root 경로에서 cli를 통해 명령어를 실행해주세요.
docker build -t 이미지명 .
ex) docker build -t test-server .
여기서 .
은 Dockerfile이 위치한 경로를 나타냅니다.
이미지를 생성하면 위와 같이 Docker Desktop을 통해 생성된 이미지 정보를 볼 수 있습니다. 또한 아래 명령어를 통해 cli로 확인하는 것도 가능합니다.
docker images
도커 이미지가 만들어졌다면, 이제 이 이미지를 서버에 전달하여 컨테이너로 실행할 수 있습니다. 하지만 도커 이미지는 직접 서버로 전송할 수 없으므로, tar 파일로 변환한 후 FTP를 통해 서버로 전송하는 방법을 사용해 보겠습니다.
// 도커 이미지 tar 파일로 생성하기
docker save 이미지명 | gzip > 파일명(확장자포함)
ex) docker save test-server | gzip > test-server.gz
명령어를 작성한 위치에 test-server.gz
파일이 생성된 것을 확인 할 수 있습니다. 이 파일을 실행시키려는 서버에 전달하면 되는데요. FTP 를 쉽게 해주는 파일질라 등의 툴을 사용하거나 scp 명령어를 통해 파일을 이동시킬 수 있습니다.
scp는 다음과 같이 사용할 수 있습니다.
scp [파일경로] [user@hostname:복사할서버경로]
ex) scp ./test-server.gz [email protected]:/opt/example
GPT 선생님 왈
scp
명령어는 "Secure Copy"의 약자입니다.scp
는 SSH(Secure Shell) 프로토콜을 이용해 파일을 안전하게 복사할 수 있는 명령어로, 로컬 컴퓨터에서 원격 서버로, 또는 원격 서버 간에 파일을 전송할 때 사용됩니다.
이제 서버에 원격으로 접속하여 작업을 이어가야합니다. ssh
를 이용하여 서버에 접속해보도록 하죠.
// pem 키를 통해 접속할 경우
ssh -i 접속키(pem)경로 [user@hostname]
ex) ssh -i ./hoho-private.pem [email protected]
// 비밀번호를 통해 접속할 경우
ssh [user@hostname]
ex) ssh [email protected]
// 비밀번호를 입력하라고 하면 비밀번호 입력
성공적으로 작업이 완료되면 다음과 같이 서버에 접속된 것을 확인할 수 있습니다.
이제 파일을 복사한 경로로 이동해줍니다.
cd /opt/kiumin-server
(실제 전달한 파일이 없어서 기존에 있는 파일로 예제를 진행합니다) test-server3.gz 이라는 파일이 잘 전달 되었네요.
이 gz 파일은 이미지를 tar파일로 변환한 것이기 때문에 반대로 다시 이미지로 만드는 것이 가능합니다.
docker load -i test-server3.gz
부가적인 옵션을 주지 않으면 test-server3가 이미지 이름이 될거에요. 아래 명령어를 통해 도커 이미지로 잘 변환 되었는지 확인해보시죠.
sudo docker images
마지막 단계입니다. 도커이미지를 컨테이너로 실행시키면 우리의 애플리케이션이 작동하는 것을 확인할 수 있어요.
도커 이미지를 컨테이너로 실행시키는 명령어는 다음과 같습니다.
sudo docker run -p 외부접속포트:도커내부포트 -d 이미지명
ex) docker run -p 8000:80 -d test-server3
문제 없이 잘 실행되었다면 다음 명령어로 실행중인 도커 컨테이너 목록에서 확인 해볼 수 있습니다.
sudo docker ps
위 과정은 docker-compose 를 사용하는 것으로 좀 더 단축할 수 있고, shell 스크립트 또는 저도 경험해보지 않았지만 CI/CD 를 통해 쉽고 편하게 배포할 수 있습니다. 도움이 되는 글이었으면 좋겠습니다. 화이팅입니다~
무작위 포스트가 추천됩니다.
조건식을 만족하느냐 아니냐에 따라 프로그램의 실행을 제어할 수 있는 문법이다. 이 때 조건식은 true나 false 같은 boolean형 타입을 반환할 수 있는 식을 말한다. 자바 문법 중에서 조건문은 if, switch, 조건연산자등이 있다.
우분투 도커 환경에서 PostgreSQL 데이터베이스 간 데이터 마이그레이션을 수행하는 방법을 안내합니다.
앨리스는 더 이상 도구가 아닙니다.