시스템 관리에 대한 프로젝트. 도커와 웹 서버 세팅하기.
시스템 관리. 업무 자동화를 위해 스크립트를 사용하는 것의 중요성 알기. 도커를 이용해서 완전한 웹 서버 설치하기. 워드프레스,phpMyAdmin, SQL 데이터베이스를 웹 서버 위에서 구동하기.
나의 로컬 환경 (macOS Catalina 10.15.3)에서 도커를 활용하여 웹 서버 만들기
sohpark 님의 기술 블로그를 참조.
동적 웹 어플리케이션을 구현하기 위해 필요한 Linux + Nginx + MySQL(or MariaDB) + PHP(or Perl, Python)을 모아서 부르는 단어이다. 데비안 운영체제의 9버전부터 MySQL이 아닌 MariaDB를 사용한다. 우리 프로젝트에서 요구하는 데비안 버스터는 데비안 10 버전이다.
위와 마찬가지인데, Linux + Apache + MySQL(or MariaDB) + PHP(or Perl, Python)
(yeosong 님의 42wiki에서 도움을 받았습니다.)
컨테이너를 끄고 킬 때마다 앞 과정을 모두 반복하지 않고, 컨테이너를 끌 때마다 저장을 한다. 컨테이너를 특정 단계에서 저장한다는 것은 이미지를 생성한다는 것과 마찬가지다. 단계는 아래와 같다.
컨테이너 종료 후 docker ps -a
한 뒤, 닫은 컨테이너 ID를 복사한다.
docker commit [CONTAINER ID] [NAME]
을 하고, docker images
를 입력하면 특정 단계까지 반영된 컨테이너 이미지가 생성된다.
Docker is a set of platform as a service (PaaS) products that uses OS-level virtualization to deliber software in packages called containers.
도커는 2013년에 등장한 컨테이너 기반의 가상화 도구이다. Go 언어로 개발되고 있다. 리눅스 상에서 컨테이너 방식으로 프로세스를 격리해서 실행하고 관리할 수 있도록 도와주고, 계층화된 파일 시스템에 기반해 효율적으로 이미지(특정한 프로세스의 실행 환경)을 구축할 수 있도록 해준다. 도커를 사용하면 이 이미지를 기반으로 컨테이너를 만들거나 실행할 수 있고, 컨테이너를 파일로 보관하거나 원격 저장소를 사용해 쉽게 공유할 수 있다.
가상 머신이란, 실제 컴퓨터 시스템을 여러 명의 사용자가 동시에 사용할 수 있게 하기 위해 컴퓨터 시스템을 여러 대의 작은 컴퓨터 시스템으로 분할하여 만든 것. 즉 실재하는 컴퓨터 위에 소프트웨어를 통해 논리적으로 만들어 낸 컴퓨터이다. Virtual Storage가 메모리의 가상화인데 대하여, CPU(중앙처리장치), I/O(입출력장치)등 컴퓨터의 모든 자원을 가상화해서 1대의 컴퓨터에서 여러 개의 시스템을 동작시킬 수 있다.
Containers are an abstraction at the app layer that packages code and dependencies together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space. Containers take up less space than VMs (container images are typically tens of MBs in size), can handle more applications and require fewer VMs and Operating systems.
컨테이너는 코드와 의존성들을 하나로 묶어주는 어플리케이션 계층에서의 추상화라고 말할 수 있다. OS kerner (운영체제의 커널)을 다른 컨테이너와 공유할 수 있고, 여러 개의 컨테이너를 하나의 기기에서 실행시킬 수 있다. 각각의 실행은 유저 공간 내에서 독립된 과정들로 실행된다. 가상 머신보다 공간을 덜 잡아먹고, 더 많은 어플리케이션을 실행시킬 수 있고, 더 적은 가상 머신이나 운영 시스템을 필요로 한다.
Learn how to build and share a containerized app 이라는 문장이 눈에 띈다. containerize 라는 동사를 사용한 것을 보니, container은 하나의 특정한 실체라기 보다는 어떤 행위에 대한 전체적인 방법론이라고 이해하면 좋을 듯 하다.
101 튜토리얼은 데스크톱에서 데스크톱 애플리케이션을 이용하거나, 클라우드 서비스를 통해 리눅스 터미널에서 명령을 내리는 식으로 진행할 수 있다. 무엇을 선택하는 것이 좋을지 모르겠지만, 가상 머신과 컨테이너에 대한 개념을 공부하기 위해 나의 로컬 환경에 직접 설치를 해 보자.
우선 Docker Desktop을 설치한다. Edge (최신) 버전이 아닌, stable (안정성) 버전을 설치했다. 도커 허브에서 Free 계정을 생성해 준 후, 애플리케이션을 실행시켜 보았다.
첫번 째로 뜨는 화면.
이미지를 빌드하기 위해 필요한 것들 (everything)과 컨테이너로 실행하기 위해 필요한 모든 것이 들어있는 레포지터리를 클론하라고 나와 있다. 오른 쪽에 자체 터미널이 실행되고 있는데, 이를 통해 프로젝트 폴더를 하나 만들어서 클론 해 보자. 버튼을 누르면 바로 실행되고, getting-started라는 이름으로 폴더가 생성된다.
다음 스텝으로 넘어가면, 이미지를 빌드하는 단계이다. 설명에는 '도커 이미지는 컨테이너를 위한 프라이빗(개인) 파일 시스템이다. 컨테이너를 위해 필요한 모든 파일과 코드를 제공한다.' 라고 쓰여 있다.
docker build -5 docker101tutorial .
명령어를 입력하면, 커맨드 라인에 실행 결과가 뜬다. 다음 단계는 실행 단계이다. 첫번 째 컨테이너를 실행한다. 이전 단계에서 빌드한 이미지를 기반으로 컨테이너를 실행한다. 기기 (컴퓨터) 상에서 안전하게 독립된 프라이빗 자원과 함께, 컨테이너가 어플리케이션을 실행하게 된다. 마지막 단계는 이미지를 저장하고 도커 허브에 공유하여 다른 사람들이 접근할 수 있게 한다. 어떤 목적 기기에서도 쉽게 다운로드 받고 실행할 수 있는 이미지를 생성한다.
실행 결과는 여기에서 볼 수 있다.
데비안은 데비안 프로젝트가 개발한 자유(free)컴퓨터 운영 체제이다.
그럼 이제 도커파일을 이해해 보자.
sohpark 님의 설명에 따르면, 도커파일과 도커의 관계는 Makefile과 make 명령어의 관계와 비슷하다. 파일 형식을 보니 정말 그런 듯하다. 스크립트를 작성하여 도커 이미지들을 컨테이너의 요구 사항에 맞게 정리해 도커파일에 명시한다.
도커를 설치하면, 맥에서 터미널을 이용해 docker를 실행해볼 수 있다.
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
docker images [OPTIONS] [REPOSITORY[:TAG]]
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker attach [OPTIONS] CONTAINER
디폴트로 실행중인 목록만 출력한다. -a 옵션을 주면 정지된 컨테이너도 볼 수 있다.
docker ps [OPTIONS]
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker rm [OPTIONS] CONTAINER [CONTAINER...]
docker rmi [OPTIONS] IMAGE [IMAGE...]
-it 옵션으로 실행해서 exit으로 shell을 종료시켜도 컨테이너는 계속 실행된다
docker exec [OPTIONS] CONTAINER COMMAND [ARG]
docker build [OPTIONS] PATH | URL | -
touch Dockefile
기본 커맨드라인 명령으로 파일을 작성한다.
가장 기본적인 커맨드로, 어떤 이미지를 기반으로 새로운 이미지를 생성할 것인지를 나타낸다. 아래 커맨드는 우분투의 버전 14.04를 바탕으로 이미지를 생성한다는 명령어이다.
FROM ubuntu:14.04
저장하고 빠져나와서 빌드를 해 보자. 빌드할 때는 아래 명령어를 사용한다.
docker build -t fromtest:0.0 .
build 명령어의 -t 옵션은 새롭게 생성될 이미지의 이름을 정하는 것이다. 마지막의 구두점(.)은 Dockerfile의 위치이다. 위의 명령어를 실행하고, docker images
명령어를 통해 빌드된 이미지를 확인해 본다.
이렇게 하면, 도커파일을 데비안 버스터를 기반으로 작성하는 커맨드는 아래와 같다.
FROM debian:buster
해당 이미지의 환경 변수를 지정해 주는 옵션이다. 이는 RUN, CMD, ENTRYPOINT
에 적용할 수 있다.
FROM
커맨드에서 설정한 이미지 위에서 명령을 실행한다. shell script와 같다고 보면 된다.
파일을 이미지에 추가한다.
COPY <복사할 파일> <이미지에서 파일이 복사될 경로>
형식으로 사용한다. 인터넷 URL을 사용할 수 없고, <이미지에서 파일이 복사될 경로>의 경우에는 언제나 절대경로를 취한다. 여러 파일들을 복사할 경우, dockerignore
에 설정한 내용은 제외된다.
RUN, CMD, ENTRYPOINT
커맨드가 실행되는 디렉토리를 설정한다.
host와 연결할 포트 번호를 설정한다.
컨테이너가 시작되었을 때 실행되는 명령어이다. Dockerfile에서는 한 번만 사용 가능하다.
ENTRYPOINT
와 비슷하게 쓰이지만, 앞에 ENTRYPOINT
가 있다면, 거기에 매개변수를 넘겨주는 목적으로 쓰인다.
해당 디렉터리의 내용을 컨테이너에 저장하지 않고 호스트에 저장한다.
요약하자면, ft_server 프로젝트는 결국 동적 웹사이트를 설계하기 위한 환경을 나의 로컬 컴퓨터에 마련해 주는 일이라고 할 수 있다. 내가 만들고 싶은 웹사이트를 만들기 위해서, 힘이 많이 들고 자원이 많이 소요되는 방식 (가상 머신, VM) 대신에, 빠르고 간편한 방식 (Docker)을 이용해서 내 컴퓨터에 자리를 하나 마련해 주는 것과 같다. 우리는 웹사이트 설계를 LEMP 스택(Linux + Nginx + MySQL(MariaDB) + Php(or Perl, Python)을 통해 진행할 것이다.
여담이지만, 나의 경우에는 C언어를 사용하여 특정한 문제를 해결하기 위해 알고리즘을 설계해야 했던 get_next_line이나 ft_printf보다 ft_server의 경우가 이해하기 더 쉬웠다. 웹개발자를 꿈꾸고 있고, 프론트엔드를 공부하고 있으며, 이 과정에서 관련한 백엔드 지식들을 어느 정도 알고 있어서 ft_server의 요구 사항들이 완전히 엥? 스럽지는 않았다.
내가 처음 ft_printf를 시작해야 했을 때나, cub3D를 앞두고의 막막한 기분을 ft_server에서 비슷하게 느끼고 있으실 분들도 있을 것 같다. 그래서 컴퓨터공학 기초 지식은 있지만, 웹개발에 선행 지식이나 관련 경험이 없는 분들을 위해 조금 더 자세히 설명을 해 보고자 한다.
우리가 ft_server에서 구성해야 하는 LEMP Stack이란 무엇일까?
LEMP: Linux, Nginx, MySQL, Php
운영체제, 웹 서버 프로그램, 데이터베이스, 개발 언어의 합성이다.
Linux는 컴퓨터 운영체제(OS, Operating System) 중 하나이다. 동일 계층에는 Windows, Unix가 있다.
Nginx는 웹 서버 프로그램이다. 동일 계층에는 Apache가 있다. 웹 서버는 HTML, CSS, Javascript, 이미지 파일 등의 정보를 HTTP 프로토콜을 준수하여 클라이언트의 웹 브라우저 (Chrome, Explore, Opera, Firefox 등)에 전송하는 역할을 한다.
MySQL은 데이터베이스 관리 시스템 (DBMS)의 하나로, 동일 계층에는 Oracle이 있다. DBMS는 계층형, 네트워크형, 관계형으로 나뉘어지고, 현재 관계형이 주류이다. 데이터베이스를 관리하기 위해 필요한 수행 과정인 데이터의 추가, 변경, 삭제, 검색 등의 기능을 집대성한 소프트웨어 패키지이다.
php(Hypertext Preprocessor)는 C언어를 기반으로(!!)만들어진, 서버 측에서 실행되는 서버 사이드 스크립트 언어이다. 동적 웹 페이지를 쉽고 빠르게 만들 수 있도록 해 준다. PHP로 작성된 코드를 HTML 코드 안에 추가하면, 웹 서버가 해당 PHP 코드를 해석하여 동적 웹 페이지를 생성한다.
컴퓨터를 사용할 때, 혹은 특정 목적을 위해서 개발 환경을 구성할 때 목적에 따라 다른 컴퓨터 환경이 필요할 수 있다. 프로그래머가 아닌 유저의 입장에서, 20대 초반 첫 개인 랩탑으로 맥을 사용했던 나는 윈도우즈에 특화되어 있던 한국의 웹사이트들을 이용하기 위해 패러랠즈, 부트캠프 등의 가상 머신을 사용해 윈도우즈 운영체제를 가상화하여 사용해 본 경험이 있다. 프로그래머의 입장에서는, 개발하려는 목적에 맞게 다른 환경을 구성해야 할 때가 빈번할 것이다. 도커는 이러한 문제점을 컨테이너와 이미지를 통해 편리하고 빠르게 제공해 준다.
여담은 이쯤 하고... Dockerfile 작성으로 돌아가 보자. 다음 포스팅에서는, 실제로 도커 파일을 작성하고 이미지를 생성해 본다.