---
description: >-
  돌아보니 한 프로젝트의 Dockerfile을 만드는 과정은, 내가 지금까지 차근차근 만들어온 프로젝트를 적절히 분해해서 srcs,
  Dockerfile, 쉘스크립트에 잘 나눠 담는 일인 것 같다.
---

# 3. Dockerfile 만들기

## 해야할 일

* Dockerfile 문법 확인 및 작성하기.
* docker container 내부의 설정파일들 hostOS의 srcs 폴더로 옮기기.
* 빌드 자동화를 위한 쉘 스크립트 작성하기.
* Dockerfile 빌드하기
* ft\_server 과제 요구사항 체크하기

## 고민했던 부분

과제 요구사항에 맞게 프로젝트 루트 폴더에는 `srcs/` 와 `Dockerfile` 만 둬야한다. [총 정리 : 도커 설치부터 워드프레스 구축까지](https://velog.io/@hidaehyunlee/ftserver-%EC%B4%9D-%EC%A0%95%EB%A6%AC-%EB%8F%84%EC%BB%A4-%EC%84%A4%EC%B9%98%EB%B6%80%ED%84%B0-%EC%9B%8C%EB%93%9C%ED%94%84%EB%A0%88%EC%8A%A4-%EA%B5%AC%EC%B6%95%EA%B9%8C%EC%A7%80) 에서 진행한 과정을 그대로 Dockerfile과 쉘스크립트에 옮겨 적는다고 생각하면 된다.

가장 막막했던, 고민했던 부분은 아래 두 가지였다.

> Q1. 많은 **명령어**들과 설정 파일 내용들을 어떻게 도커파일과 쉘스크립트에 **적절히** 나눠 적을 것인지?
>
> Q2. `srcs/` 에 어떤 파일들을 미리 넣어둬야할지?

깃허브와 구글링을 통해 다른 분들의 ft\_server 과제를 최대한 많이 참고하면서 감을 잡아나갔던 것 같다. 돌아보니 한 프로젝트의 Dockerfile을 만드는 과정은, 내가 지금까지 차근차근 만들어온 프로젝트를 적절히 분해해서 **srcs**, **Dockerfile**, **쉘스크립트**에 잘 나눠 담는 일인 것 같다. 어느 하나 간단한 설정이라도 빠져서는 안되고, 순서에 맞게, 다른 사람이 처음 봤을 때 이해하기 쉽게 나눠야한다.

이게 맞는 기준일리는 없고, 어떤 게 배포 및 속도 처리에서 유리할지는 잘 모르겠지만 나는 각각의 세 그릇에 아래와 같은 기준으로 ft\_server 프로젝트를 옮겨 담기로 했다.

*   `srcs` : 채점자(사용자)가 직접 작성하기 복잡한 설정파일들. 1. etc/nginx/sites-available/**default**

    ```
      nginx 서버의 ssl, autoindex, redirection 설정파일.
    ```

    1.  var/www/html/phpmyadmin/**config.inc.php**

        blowfish 설정파일.
    2.  var/www/html/wordpress/**wp-config.php**

        mysql의 wordpress DB 설정파일.
    3. **run.sh**
* `Dockerfile` : 프로젝트 구축에 필수적인 패키지 설치 명령어들.
  * nginx
  * php7.3-fpm
  * mariadb-server, php-mysql, php-mbstring
  * openssl
  * vim
  * wget
* `쉘스크립트(run.sh)` : 그 외 프로젝트 설정을 위해 작성했던 모든 명령어들.

고민이 해결되었으니, 해야할 일을 순서대로 진행해보자.

## 시작하기

### 1. Dockerfile 작성하기

```
FROM    debian:buster 
# 프로젝트를 시작할 베이스 image 를 지정한다.
# 우리 과제에서는 `debian:buster`로 설정.

LABEL    maintainer="daelee@student.42seoul.kr"
# image에 metadata를 추가한다.

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
# HostOS의 파일 또는 디렉토리를 컨테이너 안의 경로로 복사한다.

EXPOSE    80 443
# 이 컨테이너가 해당 포트를 사용할 예정임을 사용자에게 알려준다.
# 실제로 포트를 열기 위해서는 run 명령어에서 -p 옵션을 사용해야한다.

CMD     bash run.sh
# 생성된 컨테이너를 실행할 명령어를 지정한다.
```

### 2. container 내부의 파일들 hostOS/srcs 폴더로 옮기기

```
docker cp [container name]:[container 내부 경로] [host 파일경로]
```

![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/70c908c2-6002-44f1-9d66-c4dec18abd61-image.png)

### 3. 빌드 자동화를 위한 쉘 스크립트 작성하기

#### 3.1. **쉘 스크립트란?**

* 쉘 명령어를 한줄씩 순차적으로 읽어 실행되도록 작성된 프로그램.
* `.sh` 확장자를 가진 파일.

#### 3.2. **작성법**

*   헤더

    아래 내용을 파일 상단에 써주면, 뒤에 나오는 코드를 모두 bash 명령어로 인식한다.

    ```bash
      #!/bin/bash
    ```
*   개행

    모든 명령어는 개행을 기준으로 순서대로 실행된다.
*   주석

    ```bash
      # 을 사용한다.
    ```
* 변수
  * `=`를 이용해서 선언하고 `${변수명}`으로 사용한다.
  * `=`는 공백 없이 붙여써야한다.
  * `""`로 감싸서 사용하면 더 안전하다. (문자열에 공백도 포함해서 값을 이용할 수 있기 때문이다.)
  *   지역변수에는 `local`을 붙인다.

      ```bash
      #!/bin/bash

      test="abc"
      num=100

      echo "${test}"
      echo "${num}"
      ```
*   백그라운드 실행

    한 명령어을 실행하는 동안 다른 명령어를 수행하고 싶다면 `&`를 사용하면 된다.

    ```bash
      [파일명] &
    ```
* 그 외 더 다양한 문법은 [여기](https://twpower.github.io/131-simple-shell-script-syntax) 참고

#### 3.3. **실행방법**

```bash
$ ./파일명
$ sh 파일명
$ bash 파일명
```

### 4. Dockerfile 빌드하기

```bash
docker build <옵션> <Dockerfile 경로>
```

도커의 build 명령어를 사용한다. `-t` 옵션을 사용하면 저장소 이름, 이미지 이름, 태그를 설정할 수 있다. `<저장소 이름>/<이미지 이름>:<태그>` 형식.

아래 처럼 빌드했을 때 localhost에 접속할 수 있다면 성공이다.

```bash
docker build . -t ft_server
docker run -it -p80:80 -p443:443 ft_server
```

### 5. ft\_server 과제 요구사항 체크하기

* [http://localhost](http://localhost/) , [http://localhost:80](http://localhost/) 했을 때 `https`로 리다이렉션 되는지?
* [https://localhost:443](https://localhost/) 로 접속 가능한지?
* [https://localhost/wordpress](https://localhost/wordpress) 로 접속 후 웹 홈페이지 구축 가능한지?
* [https://localhost/phpmyadmin](https://localhost/phpmyadmin) 로 접속 시 설정한 유저명 + 비밀번호로 로그인 가능한지?
* SSL CA 인증서가 있는지?
* autoindex가 잘 동작하는지?
* phpmyadmin 에서 워드프레스 DB 연동이 되는지?
  *   [https://localhost/phpmyadmin](https://localhost/phpmyadmin) 에서 좌측 메뉴를 보면 wordpress 테이블이 있다. 내용을 수정하고 맨 아래 `실행` 버튼을 누르면 자동으로 변경내용이 DB에 저장된다.

      ![](https://github.com/hidaehyunlee/Fork-my-brain/tree/4f7d19f4487fe8d450e22a9b6451bbed865ce125/images/d0b856f3-6700-4564-8307-1b145731ff6f-image.png)
  * [https://localhost/wordpress](https://localhost/wordpress) 로 접속했을 때 아래처럼 수정사항이 잘 반영되었으면 연동이 잘 된 것이다.

```
![](/images/c5ca3d5d-d8a3-4af2-bf15-4299c379d783-image.png)
```

* [출처](https://yeosong1.github.io/ft_server-%EC%B1%84%EC%A0%90-%EB%B0%A9%EB%B2%95)
