가희의자기개발블로그

Docker 에 개발환경 세팅해보기 본문

백엔드/Docker

Docker 에 개발환경 세팅해보기

가희gahui 2021. 1. 21. 12:57
반응형

Laravel Framwork를 Docker 환경에서 구동시켜 보도록 하겠습니다. 사용하고자하는 서버와 데이터 베이스는 아래와 같이 설정하도록 하겠습니다. 

Server : Nginx

DataBase : MySql

 

 

가장먼저 아무 디렉터리나 만들어 보겠습니다. dockertest라는 폴더를 하나 만들고 이 폴더 안에 docker-compose, Dockerfile 등의 파일을 작성하겠습니다.

 

1. dockertest 폴더 생성

이제 우리는 이 폴더 안에서 작업을 진행하겠습니다. 대략적인 디렉터리 구조는 아래와 같습니다.

dockertest 폴더에 들어간후, docker-compose.yml, Dockerfile 을 먼저 생성해 보겠습니다. 

 

2. docker-compose.yml 코드 작성

도커 컴포즈에 대해 간략히 설명해 보자면, 도커 컴포즈는 빠르게 개발 환경을 올려 사용할 수 있도록 만들어진 도구입니다.  yaml 파일을 이용해 여러 컨테이너들의 설정을 저장합니다. 우리는 이렇게 한번 설정한 파일을 통해서 매번 도커 명령어나 스크립트를 작성할 필요 없이, 'docker compose up -d'와 같은 명령어 한번만 입력하면 컨테이너를 시작시키고 업데이트 하고 중지하는 작업을 쉽게 할 수 있습니다.

 

아래는 docker-compose.yml에 대한 전체 내용인데 하나씩 살펴보도록 하겠습니다. 

< docker-compose.yml > 

version: '3.9'

networks: 
    laravel:

services: 
    nginx: 
        image: nginx:stable-alpine
        container_name: nginx
        ports: 
            - "8088:80"
        volumes:
            - ./src:/var/www/html
            - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
        depends_on: 
            - php
            - mysql
        networks: 
            - laravel
    mysql:
        image: mysql:5.7.22
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports: 
            - "4306:3306"
        volumes: 
            - ./mysql:/var/lib/mysql
        environment: 
            MYSQL_DATABASE: homestead
            MYSQL_USER: homestead
            MYSQL_PASSWORD: secret
            MYSQL_ROOT_PASSWORD: secret
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
        networks: 
            - laravel
    php: 
        build: 
            context: .
            dockerfile: Dockerfile
        container_name: php
        volumes: 
            - ./src:/var/www/html
        ports:
            - "9000:9000"
        networks: 
            - laravel

2-1 Version: 3.9

docker-compose 엔진의 버전을 명시합니다. (도커 공식문서에서 가장 최신의 버전을 확인할 수 있다.)

version: '3.9'

2-2 Networks:

해당 어플리케이션내에 같은 네트워크로 구성합니다. laravel은 임의로 생성한 이름이고, 원하는 이름으로 변경 가능합니다. 이 실습에서는 다른 어플리케이션과의 통신이 필요없으므로 생략해도 무관합니다.

 

참고 ) 같은 어플리케이션내에 작성된 서비스들은 기본적으로 같은 네트워크에 포함되어있습니다. 즉, 네트워크 옵션은 사용하지 않아도 무관합니다. 단, 다른 어플리케이션과 통신이 되어야 할 때에는 해당 옵션이 필요합니다.

networks: 
    laravel:

2-3 services:

하나의 애플리케이션에는 여러 개의 서비스들이 연결되어 사용된다. 즉 각각의 컨테이너들을 정의한다고 생각하면 된다.

예를 들면 사진을 공유하는 어플리케이션을 만들고자 할 때, 클라이언트 웹 서비스도 필요하고 , 빽단에 사진을 가공하고 DB에 저장시키는 , spring 서버나 node 서버 서비스도 필요하고, DB 서버도 필요하며, 검색엔진도 필요할 수 있다. 이렇게 하나의 어플리케이션에 필요한 서비스들을 services: 하위에 작성하면 된다.

 

2-4 Nginx 추가

서비스 헤딩 아래에 아래의 코드를 추가하자.

nginx: 
        image: nginx:stable-alpine
        container_name: nginx
        ports: 
            - "8088:80"
        volumes:
            - ./src:/var/www/html
            - ./nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf
        depends_on: 
            - php
            - mysql
        networks: 
            - laravel

위 코드에서 하고싶은 일을 정의하자면, 바로 nginx라는 이름을 가진 컨테이너를 원한다고 도커에게 말을해주는것과 같다. nginx:stable-alpine이라는 이미지이름을 빌드해달라는 명령어 이다. 

그 다음 컨테이너이름으로 nginx라는 이름을 정해주었다.(원하는대로 정할수있다.)

아래 ports는 로컬 머신의 8088포트와 해당 컨테이너의 80번 포트를 연결해준다는 의미이다. 그래서 localhost:8088 이라는 주소를 입력하면 알아서 컨테이너의 80포트와 연결되어 서버를 이용할 수 있게 해준다.

 

아래 volumes은 로컬의 /src 폴더와 /var/www/html 패스를 바운드시켜준다는 의미이다. 간단히 설명하자면, 우리는 윈도우 환경에서 작업을 하고 해당 코드들을 src폴더에 저장을 한다. 그러면 서버가 이 해당 폴더의 경로를 알아서 읽어줘야하는데 서버를 컨테이너에서 돌리고 있다. 그렇게 되면 서버는 어디에 해당폴더가 있는지 모른다.(컨테이너 안에 서버가 있기 때문에) 그래서 로컬의 /src 폴더에 들어있는 파일을 컨테이너의 /var/www/html 경로에 똑같이 넣어주는 것이다. 실제로 컨테이너에 들어가서 해당 경로로 들어가면 src에 있는 파일과 같은 파일을 볼 수 있다.

 

서버의 환경설정을 위해 nginx/conf.d/default.conf 폴더를 생성해주고 컨테이너의 해당경로와 연결시켜준다. 이렇게 연결 시켜주면 nginx container에서 서버의 환경설정을 우리 로컬환경에서 수정해줄 수 있다.

 

depends_on이라는 항목에 php와 mysql을 추가시켜준다.(아래에서 생성할 것이다.) 이 항목의 의미는 nginx 컨테이너가 생성되기전에 php 와 mysql 컨테이너를 생성해 달라고 요청하는 것이다. 그렇기 때문에 만약 nginx 컨테이너만을 가동시킨다면 자동으로 이 php 와 mysql 컨테이너를 먼저 생성한다. 

 

마지막으로 도커에게 이 해당 컨테이너는 laravel이라는 이름의 네트워크 아래에서 동작한다는 것을 알려준다. 

 

2-5 Mysql 추가

그 다음으로 mysql 설정을 해준다. 

mysql:
        image: mysql:5.7.22
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports: 
            - "4306:3306"
        volumes: 
            - ./mysql:/var/lib/mysql
        environment: 
            MYSQL_DATABASE: homestead
            MYSQL_USER: homestead
            MYSQL_PASSWORD: secret
            MYSQL_ROOT_PASSWORD: secret
            SERVICE_TAGS: dev
            SERVICE_NAME: mysql
        networks: 
            - laravel

nginx 를 설정해줬던 것과 같이 먼저 다운받고싶은 image명을 명시하고 container_name을 mysql로 지정해줬다.

Mysql의 기본 포트는 3306포트이기때문에 로컬 포트는 4306포트를 이용했고 mysql을 담고있는 컨테이너는(무조건) 3306포트로 연결시켜줘야 한다. 

restart옵션은 docker desktop을 실행시킬때 마다 container를 항상 같이 띄울수 있는다. 혹은 서버에서 docker container가 죽는 경우 재시작을 할 수 있도록 설정하는 것이다. restart옵션중 unless-stopped옵션은 container를 stop시키지 전 까지 항상 재시작 시키도록 하는 것이다.

 

tty란 tty모드를 사용하겠다는 의미이다. 

tty란? 콘솔및 터미널 환경을 tty라고 한다. 

아래로 environment  를 설정해준다. 데이터베이스를 생성해주기 위한 몇몇 기초적인 변수들을 설정해주면 된다. 

 

그리고 nginx에서 설정해주었던것과 같이 laravel network안에서 돌아가는 서비스라는 것을 명시해 준다.

 

2-6 php 추가

nginx와 mysql 설정해준것과 다르게 php 컨테이너는 조금 다르고 더 복잡하게 구성되어있다. 이전 두 서비스는 직접 이미지를 참조해 컨테이너를 빌드시켰다. 하지만, 라라벨이 요구하는 디펜던시 때문에 Dockerfile을 작성해서 이미지를 빌드시켜야 한다. 

 

아래코드를 추가해보자

php: 
        build: 
            context: .
            dockerfile: Dockerfile
        container_name: php
        volumes: 
            - ./src:/var/www/html
        ports:
            - "9000:9000"
        networks: 
            - laravel

위에서 보다시피 위 다른 서비스들과의 차이점은 image가 아닌 build 옵션을 사용해줬다는 것이다. build 아래의 내용에는 구체적인 Dockerfile의 디렉터리 위치를 지정해주었다. 

 

nginx에서 설정해준 volumes과 같이 php container도 같은 루트 디렉터리를 연결해주었다. 그리고 9000포트를 열어주었고 라라벨 네트워크에서 돌아가는 서비스라는 것을 명시해 주었다.

 

3. Dockerfile 작성

이제 우리의 서비스를 추가하기위해 Dockerfile을 작성해 보자

전체 코드는 아래와 같다.

FROM php:7.2-fpm-alpine

RUN docker-php-ext-install pdo pdo_mysql

- 가장 먼저 FROM 은 

어떤 이미지를 기반으로 할지 설정하는 것이다. Docker 이미지는 기존에 만들어진 이미지를 기반으로 생성한다. <이미지 이름>:<태그> 형식으로 설정한다. 

즉, 7.2-fpm-alpine이라는 php 이미지로부터 php 컨테이너를 빌드한다는 의미이다.

 

- RUN 

laravel 설치 시 필요한 PHP extension을 설치한다. docker-php-ext-install이라는 명령어를 통해 pdo와 pdo_mysql을 설치하였다.

 

4. nginx 설정

위에서 우리가 nginx 서비스를 설정할때 /nginx/conf.d/default.conf 와 container의 /etc/nginx/conf.d/default.conf 를 연결해 주었던걸 기억해보자

그러면 우리는 로컬의 해당 폴더를 만들고 아래와 같이 설정을 해주자

 

server {
    listen 80;
    index index.php index.html;
    server_name localhost;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;

    }
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

여기서 설명해야할 것은 많지 않다. 보통 라라벨을 동작하는데 설정해줘야하는 기본 nginx설정들이기 때문이다.

주의할 점은 root 패스인데 저 root패스와 라라벨 앱과 연결하는 부분이다.

나는 저부분을 /var/www/html/public 이라고 적어줘서 계속 404 에러가 났다. 실제로 nginx컨테이너의 해당 경로에 들어가면 우리가 작성한 파일들을 볼 수 있다. 

 

4. 간단한 html 파일 작성

src 폴더에 index.html이라는 이름의 파일을 하나만들고 안에 아래와 같이 아주 간단한 코드를 작성해보았다.

 

<h1>It works!</h1>

 

5. docker 빌드 시작하기 

We have all of our individual pieces in order, now it’s finally time to assemble our Docker network! Open up a terminal window and navigate to the root directory of this project. Since one of our containers (php) is using a Dockerfile as its image, and this is the first time we’re spinning up these containers, the first thing we need to do is run the build command to generate the image data:

 

지금까지 우리는 순서대로 개개의 컨테이너를 docker-compose파일에 작성했다. 이제 이것들을 Docker network에 서로 잘 작동되게 올려놓으면 된다! window terminal에서 이 프로젝트의 root로 이동한다. 우리가 만든 php 컨테이너는 Dockerfile을 image로 갖고있다. 이 해당 컨테이너를 실행시키기 위해서는 이것을 image로 만들어 줘야한다.

build커맨드를 이용하면 Dockerfile을 이미지로 만들수 있다.

 

docker-compose build

 

Successfully built와 Successfully tagged라는 메시지가 터미널에 뜨면 성공적으로 이미지를 만든것이고 이제 컨테이너를 실행할 준비를 마친것이다.

 

docker-compose up -d

 

위 명령어를 입력하면 Docker는 laravel network를 생성하고 우리가 docker-compose.yml파일의 services 옵션에 적어주었던 세개의 컨테이너들을 차례로 생성할것이다. -d 옵션은 모든 커맨드가 처리된 후에 컨테이너를 백그라운드로 구동시키라는 의미이다. 이를 적어주지 않으면 container는 실행되자마자 종료되어버린다. 

 

6. 서버 구동 확인하기

우리는 src 폴더에 index.html 의 파일안에 간단한 코드를 작성해주었다.

이제 nginx가 잘 돌아가는지 확인해 보자

localhost:8088 을 입력하고 아래와 같이 뜨면 성공!이다!!

 

반응형

'백엔드 > Docker' 카테고리의 다른 글

[ERROR] Docker /favicon.ico HTTP/1.1 404  (0) 2021.01.31
Docker, Docker-compose 차이  (1) 2020.12.12
[ERROR]Docker for Window : Git Bash에서 docker run 실행 오류  (0) 2020.11.15
Docker 개념  (1) 2020.11.14
Comments