---
description: 과제 시작 전 공부한 내용 정리.
---

# 1. 선행지식-Docker? Debian Buster? Nginx? ...

> **ft\_server** 는 시스템 관리 개념을 소개하기 위한 과제이다. **스크립트를 이용해 업무를 자동화**하는 것의 중요성을 깨닫게 될 것이다. 이를 위해 `Docker` 기술을 학습하고 완전한 웹 서버를 설치해본다.

**일반 지침사항**

* **srcs** 라는 폴더 안에 서버 환경설정을 위한 모든 파일을 위치시켜라.
*   **Dockerfile** 은 깃 저장소의 루트에 있어야 한다. 이건 당신의 container를 build할 것이다.

    docer-compose는 사용할 수 없다. (docker-compose : container실행을 간편히 해주는 것 )
* WordPress 웹 사이트에 필요한 모든 파일은 srcs안에 있어야 한다.

**필수 사항**

*   오직 하나의 Docker container 안에 `Ngnix` 웹 서버를 설치해야 한다.

    이 container의 OS는 `Debian Buster`여야 한다.
* 당신의 웹 서버는 여러 서비스가 연동되어야한다. 여기서 말하는 서비스는 다음을 의미한다 .
  * `Wordpress` 웹사이트
  * `phpMyAdmin`
  * `MySQL` : SQL 데이터베이스는 phpMyAdmin과 워드프레스에서 연동하여 사용이 가능해야 한다.
* 당신의 서버는 `SSL 프로토콜`을 사용해야 한다.
* `URL redirection`을 처리해야 한다.
* 언제든 해제할 수 있는 `autoindex`가 적용되어야 한다.
* [채점 매뉴얼](https://yeosong1.github.io/ft_server-%EC%B1%84%EC%A0%90-%EB%B0%A9%EB%B2%95)

## 선행지식

아래 이미지([출처](https://stitchcoding.tistory.com/2))대로 ft\_server 과제를 구현하면 된다. 맨 아래부터 하나씩 개념 공부를 해보자.

undefined

### 1. 도커 (Docker)

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/0b6xq4gbUchSdcNz3CvWO1-img.png)

#### CONTAINERS 란?

* 도커는 **컨테이너 기반의 오픈소스 가상화 플랫폼**이다.
* 기존의 가상화 방식(VM)은 주로 **OS를 가상화**하였지만, **컨테이너는 하드웨어를 분리하지 않고 하나의 머신 위에서 동작하며 OS 커널도 공유**한다. geust OS를 통해 OS를 복제할 필요가 없어 더 효율적인 관리가 가능한 것이다.
* 성능에 대한 감이 잘 안잡혀 찾아보니, 하나의 VM도 버거운 노트북에서 수십 개의 컨테이너를 실행시킬 수 있을 정도라고 한다.

#### IMAGE 란?

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/2017-01-19-docker-guide-for-beginners-1-docker-image.png)

* 도커에서 가장 중요한 개념은 컨테이너와 함께 **이미지**라는 개념이다.
* 이미지는 **컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것**으로 상태값을 가지지 않고 변하지 않는다(**Immutable**).&#x20;
* 컨테이너는 이미지를 실행한 상태라고 볼 수 있고 추가되거나 변하는 값은 컨테이너에 저장된다. 같은 이미지에서 여러 개의 컨테이너를 생성할 수 있고 컨테이너의 상태가 바뀌거나 컨테이너가 삭제되더라도 이미지는 변하지 않고 그대로 남아있다.
* 말그대로 이미지는 컨테이너를 실행하기 위한 모든 정보를 가지고 있기 때문에 더 이상 의존성 파일을 컴파일하고 이것저것 설치할 필요가 없게 된다. 이제 새로운 서버가 추가되면 미리 만들어 놓은 이미지를 다운받고 컨테이너를 생성만 하면 되는 것이다.

#### Docker Hub 란?

* 도커 이미지의 용량은 보통 수백 메가로 수 기가가 넘는 경우도 흔하다. 이렇게 큰 용량의 이미지를 서버에 저장하고 관리하는 것은 쉽지 않은데 도커는 **Docker hub**를 통해 공개 이미지를 무료로 관리해 줍니다.
* [Docker hub](https://hub.docker.com)에서 공개된 이미지를 다운받아 사용하거나, [Docker Registry](https://docs.docker.com/registry/) 저장소를 직접 만들어 관리할 수 있다.
* 현재 공개된 도커 이미지는 50만개가 넘고 Docker hub의 이미지 다운로드 수는 80억회에 이른다고 한다. 누구나 쉽게 이미지를 만들고 배포할 수 있습니다. 이 모든게 무료.

#### Dockerfile 이란?

* 도커는 기본적으로 이미지가 있어야 컨테이너를 생성하고 동작시킬 수 있다. `dockerfile`은 필요한 패키지를 설치하고 동작하기 위한 자신만의 설정을 담은 파일이고, 이 파일로 **이미지를 생성(빌드)**&#xD55C;다. (Makefile과 비슷)
* `dockerfile`은 도커 명령어를 순서에 따라 빌드하며, `dockerfile`을 빌드할 때(이미지 파일로 변환 시킬 때)는 **layer 구조**를 보인다. 이미지가 계층적으로 하나씩 쌓이면서 생성되는 것이다.

**Dockerfile 작성예시 및 명령어**

```
FROM    debian:buster

LABEL    maintainer="daelee@student.42seoul.kr"

RUN    apt-get update && apt-get install -y \
    nginx \
    mariadb-server \
    php-mysql \
    php-mbstring \
    openssl \
    vim \
    wget \
    php7.3-fpm

COPY    ./srcs/run.sh ./
COPY    ./srcs/default ./tmp
COPY    ./srcs/wp-config.php ./tmp
COPY    ./srcs/config.inc.php ./tmp

EXPOSE    80 443

CMD     bash run.sh
```

* **FROM**
  * 유효한 Docker 파일은 FROM 명령으로 시작해야 한다.
  * 새 작업을 시작할 베이스 이미지를 지정한다.&#x20;
  * 우리 과제에서는 `debian:buster`로 설정.
* **LABEL**
  * 이미지에 메타데이터를 추가한다.
    * 이미지의 버전 정보, 작성자, 코멘트와 같이 이미지 상세 정보를 작성해두기 위한 명령.
  *   아래 명령어로 이미지의 메타데이터를 확인할 수 있다.

      ```bash
      docker image inspect --format="{{ .Config.Lables }}" [이미지명]
      ```
* **RUN**
  * **새 이미지 레이어를 만들어 내** 명령을 실행하고 결과를 커밋한다.
  * 백슬래시(`\`)를 사용하여 다음 줄에 RUN 명령을 계속할 수 있다.
  * _주의_ : 항상  `apt-get update` 와 `apt-get install`는 같은 RUN 실행줄에서 동시에 실행해 캐싱 문제를 방지. (같은 결과를 가져오더라도 RUN을 여러줄로 작성하면 image layer가 여러개 생성되고, RUN을 한줄로 작성하면 image layer가 하나 생성된다.)
* **COPY**
  * 호스트OS의 파일 또는 디렉토리를 컨테이너 안의 경로로 복사한다.
  * ft\_server 과제를 위해 수정해줬던 설정 파일들을 이 명령어로 미리 src 폴더에 넣어둘 것이다.
* **EXPOSE**
  * 해당 컨테이너가 런타임에 지정된 네트워크 포트에서 수신 대기중 이라는것을 알려준다.
  * 일반적으로 dockerfile을 작성하는 사람과 컨테이너를 직접 실행할 사람 사이에서 공개할 포트를 알려주기 위해 문서 유형으로 작성할 때 사용한다.
  *   이 명령 자체가 작성된 포트를 실행하여 listening 상태로 올려주거나 하지는 않기 때문에, 실제로 포트를 열기 위해선 container run 에서 -p 옵션을 사용해야 한다.

      ```bash
      docker run -p 80:80/tcp -p 80:80/udp ...
      ```
  * 프로토콜을 지정하지 않으면 기본값은 TCP.
* **CMD**
  * 생성된 컨테이너를 실행할 명령어를 지정한다.
  * 도커 파일에 CMD가 두 개 이상 있는 경우 마지막 CMD만 유효하다.

### 2. 데비안 (Devian)

`데비안`은 우분투 같은 리눅스 OS 종류 중에 하나다. 우분투처럼 APT를 패키지 및 소프트웨어 관리자로 사용하고 있다. 사실 우분투는 데비안에서 나온 운영체제이며, 우분투에서 볼 수 있는 대부분의 핵심 유틸리티는 데비안에서 나왔다.

데비안은 **안정성을 매우 중시하는 리눅스 배포판**이다. 때문에 안정성을 가장 큰 가치로 두어야 할 서버 쪽에서 상당한 인기를 끌고 있다.

2019년 7월 6일 배포된 최신 안정 버전은 **10.0(Buster)** 이다.

* [공식 홈페이지](https://www.debian.org/index.ko.html)

### 3. Nginx

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/06-Google-Search-Trends-Apache-vs-Nginx-1.png)

`엔진엑스`는 무료로 제공되는 오픈소스 웹 서버 프로그램이다. 간단하게 **웹 서버는 클라이언트로 부터 요청이 발생했을 때 요청에 맞는 정적콘텐츠을 보내주는 역할**을 한다. `Nginx`는 규모가 작은 서비스이면서 정적 데이터 처리가 많은 서비스에 적합하다고 한다.

#### 웹 서버가 하는 일

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/typora-user-images-image-20200925160255258.png)

1. 커넥션을 맺는다 _(클라이언트의 접속을 받아들이거나, 원치 않는 클라이언트라면 닫는다)_
2. 요청을 받는다 _(HTTP 요청 메세지를 네트워크로부터 읽어들인다)_&#x20;
3. 요청을 처리한다 _(요청 메세지를 해석하고 행동을 취한다)_&#x20;
4. 리소스에 접근한다 _(메세지에서 지정한 리소스에 접근한다)_
5. 응답을 만든다 _(올바른 헤더를 포함한 HTTP 응답 메세지를 생성한다)_&#x20;
6. 응답을 보낸다 _(응답을 클라이언트에게 돌려준다)_&#x20;
7. 트랜잭션을 로그로 남긴다 _(로그파일에 트랜잭션 완료에 대한 기록을 남긴다)_&#x20;

**프락시 (Proxy)**

* Nginx는 일반적인 HTTP의 웹서버의 역할 외에도 **proxy**, **reverse proxy(대리 프락시) 서버**의 역할 또한 가능하다.
*   웹 프락시 서버는 클라이언트와 서버 사이에서 트랜잭션을 수행하는 중개인이며, 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결한다.

    undefined
* 프락시는 보안을 개선하고, 성능을 높여주며, 비용을 절약한다. 그리고 프락시 서버는 모든 HTTP 트래픽을 감시하고 수정할 수 있다. 프락시는 아래와 같은 일을 한다.
  * 어린이 필터
  * 문서 접근 제어자
  * 보안 방화벽&#x20;
  * 웹 캐시
*   **대리 프락시 (reverse proxy) 란?**

    대리 프락시는 웹 서버인 것처럼 위장해 클라이언트의 요청을 받지만 웹 서버와는 달리 요청 받은 콘텐츠의 위치를 찾아내기 위해 다른 서버와 커뮤니케이션을 시작한다. 대리 프락시는 공용 콘텐츠에 대한 느린 웹 서버의 성능을 개선하기 위해 사용될 수 있다. 이런 식으로 사용되는 대리 프락시를 흔히 서버 가속기라고 부른다.

### 4. phpMyAdmin 및 php-fpm

php를 기반으로 생성된 **mySQL의 GUI**로서 웹에서 실행할 수 있는 프로그램이다.

*   **php란?**

    대표적인 **서버 사이드 스크립트 언어**.
*   **CGI(공통 게이트웨이 인터페이스) 란?**

    nginx는 웹서버이기 때문에 정적 콘텐츠밖에 다루지 못한다. 동적 페이지를 구현하기 위해서는 웹 서버 대신 동적 콘텐츠를 읽은 뒤 html로 변환시켜 웹 서버에게 다시 전달해주는 **외부 프로그램(php 모듈)**&#xC774; 필요하다. 이런 **연결 과정의 방법 혹은 규약을 정의한 것이 CGI**이다.

    ![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/37580034-94646331-fd68a180-0328-11eb-996b-46415f50b285.png)
*   **php-fpm (PHP FastCGI Process Manager) 란?**

    일반 GCI 보다 빠른 처리가 가능한 FastGCI. 정리하자면,

    `php-fpm` 을 통해 **nginx와 php를 연동시켜 우리의 웹 서버가 정적 콘텐츠 뿐만 아니라 동적 콘텐츠를 다룰 수 있도록** 만드는 것이다.

### 5. HTTPS 및 SSL

* HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)는 `SSL`위에서 돌아가는 HTTP의 평문 전송 대신에 **암호화된 통신을 하는 프로토콜**이다.
* 이런 HTTPS를 통신을 서버에서 구현하기 위해서는 _신뢰할 수 있는 상위 기&#xC5C5;_&#xC774; 발급한 인증서가 필요로 한데 이런 발급 기관을 **CA(Certificate authority)**&#xB77C;고 한다. CA의 인증서를 발급받는것은 당연 무료가 아니다.
* self-signed SSL 인증서는 **자체적으로 발급받은 인증서이며, 로그인 및 기타 개인 계정 인증 정보를 암호화**한다. 당연히 브라우저는 신뢰할 수 없다고 판단해 접속시 보안 경고가 발생한다.
* self-signed SSL 인증서를 만드는 방법은 몇 가지가 있는데, 무료 오픈소스인 `openssl` 을 이용해 쉽게 만들수 있다.&#x20;
  * HTTPS를 위해 필요한 `개인키(.key)`, `서면요청파일(.csr)`, `인증서파일(.crt)`을 openssl이 발급해준다.

### 6. Autoindex

*   autoindex 가 뭔지 알고싶다면 먼저 웹서버가 **리소스 매핑과 접근**을 어떻게 하는지 부터 알아야한다.

    > **웹 서버는 어떻게 수 많은 리소스 중 요청에 알맞은 콘텐츠를 제공할까?**
    >
    > 일반적으로 웹 서버 파일 시스템의 특별한 한 폴더를 웹 콘텐츠를 위해 사용한다. 이 폴더를 `문서루트` 혹은 `docroot`라고 부른다. 리소스 매핑의 가장 단순한 형태는 요청 URI를 `dotroot` 안에 있는 파일의 이름으로 사용하는 것이다.
    >
    > 만약 파일이 아닌 디렉토리를 가리키는 url에 대한 요청을 받았을 때는, 요청한 url에 대응되는 디렉토리 안에서 `index.html` 혹은 `index.htm`으로 이름 붙은 파일을 찾아 그 파일의 콘텐츠를 반환한다. 이를 **autoindex** 라고 부른다.

그래서 **우리는 autoindex 기능을 켜줘야한다**. nginx default 파일에서 location / 부분에 `autoindex on` 을 추가한다.

```
# etc/nginx/sites-available/default
# Autoindex
    index index.html index.htm index.php #index.ngiinx-debian.html;

    server_name ft_server;
    location / {
      # autoindex on 추가
        autoindex on;
        try_files $uri $uri/ =404;
    }
```

* 만약 autoindex가 꺼져 있거나 해당 디렉토리에 index 목록에 해당하는 파일이 없다면, 웹 서버는 자동으로 그 디렉토리의 파일들을 `크기`, `변경일`, `해당 파일에 대한 링크`와 함께 열거한 HTML 파일을 반환한다.
*   루트 디렉터리인 /var/www/html 에 존재하는 index.ngiinx-debian.html 을 주석처리해보면, 읽을 파일이 없다고 생각하고 아래처럼 전체 파일 목록을 반환하는 것을 확인할 수 있다.

    ![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/37580034-94646370-107b7180-0329-11eb-8eff-dad2c3ba7561.png)
