2024년 6월 10일 월요일

Laravel +docker

Laravel +docker

Laravel 설치(Docker이용)

Docker에 Ubuntu깔고 PHP composer 를 이용해서 Laravel설치 순서는 다음과 같이 한다.

1.우분투 이미지 가져오기

docker pull ubuntu:latest

2.이미지로 부터 docker 컨테이너 작성후 컨테이너의 bash 쉘로 진입.( run 으로 실행하면 attach,즉 포어그라운드모드이다. )

docker run -it -p 80:80 --name laravel_test ubuntu bash

개발서버나 php자체서버를 이용하여 테스트하고 싶을때는

docker run -it -p 8090:8000 --name laravel_test ubuntu bash

으로 지정한다. 주의할점은 run 으로 컨테이너가 생성되면 내-외부의 포트포워딩은 변경할수없다.

3.php 를 설치하자.

apt update && apt install -y php-fpm

4.php 의 의존성 관리도구인 composer 를 설치하자.(npm, pip 처럼 라이브러리 설치와 업데이트를 관리해주는 도구이다)
일단, curl로 커멘드라인에서 인터넷자료를 다운로드 받도록 준비하자.

 apt install -y curl

composer 를 다운받자.

curl -sS https://getcomposer.org/installer | php

현재디렉토리에 다운받아졌으므로, 어디서나 가능하도록 /usr/bin에 넣자

mv composer.phar /usr/bin/composer

5.Laravel은 php 웹프레임워크이니까 composer 를 통해서 다운받거나 관리할수있으므로 composer 를 이용해서 설치해보자.
일단 Laraveld의 설치관리자 를 전역 으로 설치해서 어디서나 laravel 프로젝트를 만들수 있도록 하자.

composer global require laravel/installer

설치시에 zip 관련 모듈이 필요하기에

apt install -y php8.3-zip 

을 설치한다.
또한 나중에 laravel로 프로젝트 시작할때 php관련 몇몇 라이브러리가 없다고 에러가 나올테니 미리 아래의 두개를 설치해놓자.

apt install -y php8.3-mbstring && apt install -y php8.3-xml  && apt install -y php8.3-sqlite3

6.이제 laravel 이라는 명령어를 어디서든 이용할수있다.
단, laravel 명령어를 어디서든 실행하기 위해서는 경로에 환경변수 추가해주자.

export PATH=$PATH:~/.config/composer/vendor/laravel/installer/bin/

7.이제 laravel 명령어를 이용해서 프로젝트를 만들수 있다.

laravel new 프로젝트이름

laravel에서는 새프로젝트 시작시에 starter kit 과 프론트엔드에서 같이 연동해서 보여줄 vuejs, reactjs 등의 설정을 쉽게 미리 해주는 선택옵션들을 제공한다. 일단 스타터킷 없이 해보자.

┌ Would you like to install a starter kit? 
 │ No starter kit                                        │
 미리 이래저래 구성되어있는 가벼운 breeze 키트를 선택한다.

 ┌ Which testing framework do you prefer? 
 │ Pest                                                         │
테스트 프로엠워크

 ┌ Would you like to initialize a Git repository? 
 │ Yes                                                          │
Git 로 소스 이력관리한다.

8.DB선택화면에서는 SQLite(경령디비엔진)를 사용하자.
9.일단 가볍게 php에서 제공하는 서버(개발용)로 라라벨을 띄워보자.
단 우리는 docker에 설정했으므로 host와 port 지정이 필요하다.

php artisan serve --host 0.0.0.0 --port 8000

작업컴퓨터의 브라우져에서 http://localhost:8090 으로 접속하면 도커내부의 php 서버(0.0.0.0:8000)내용이 작업컴퓨터의 localhost:8090 에 매치되어 화면에 laravel웰컵화면이 표시된다.
만약 접속이 안된다면 앞에서 docker run 으로 시작할때, -p 내컴퓨터포트:도커내부포트 를 다른 값으로 지정했기 때문이다.
(참고로 docker run -it -p 8090:8000 --name laravel_test ubuntu bash 으로 실행했다.)
포트가 다르게 되었다면, 현재의 컨테이너를 docker stop 으로 멈추고, 현재의 컨테이너를 이미지로 만든다음, 새로운 컨테이너를 생성(run)하여 -p 옵션을 적절하게 주면된다.

 INFO  Server running on [http://0.0.0.0:8000].

  Press Ctrl+C to stop the server

Nginx 설치연동

php artisan 으로 서버를 구동해도 되지만, 실제 서비스에서는 전문 웹서버를 이용해야 한다. Nginx가 가장 많이 사용되므로 설치해보자.

1.nginx 설치 .

apt install -y nginx

2.설치가 되면 서버구동에 필요한 설정파일이 /etc/nginx/sites-available/default 에 생성된다. 이 파일을 이용하여 php-fpm 연동, 웹서버포트, 홈디렉토리 등을 설정해보자.

server {
    ...
    # 웹서버의 기본 홈디렉토리를 지정한다. 아까 Laravel을 설치한장소의 public 폴더이다.
    root /home/test3/public; 
    # 접속시 최초 실행될 php파일을 적는다. 
    index index.php
    # .php파일에 대한 설정을 한다.
	location ~ \.php$ {
		# 파일을 찾을수 없을때 404 오류처리
        try_files $uri =404;
        # 요청된 url주소에서 .php로 끝나는 OOO.php 를 찾아내서 php-fpm에 전달
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        # php-frm.sock을 통해서 소켓과 통신하여 php스크립트를 처리
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
        # 요청된 파일이 디렉토리인 경우, 해당 디렉토리에서 기본으로 실행할 php 파일을 지정
        fastcgi_index index.php;
        # 추가적인 FastCGI 매개변수를 포함하기 위한 설정 파일을 포함
        include fastcgi_params;
        # PHP-FPM에 전달되는 SCRIPT_FILENAME 매개변수를 설정
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # PHP-FPM에 전달되는 PATH_INFO 매개변수를 설정
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

3.설정이 끝났으면 nginx를 재가동한다.

service nginx restart

4.php-fpm 도 가동하자.

service php8.3-fpm start

5 접속(http://localhost:8090/)해보면 파일을 못읽는 에러가 뜬다. 이유는 php-fpm 에서 php파일을 읽을수있는 권한이 정해져있는데 보통 /etc/php/8.3/fpm/pool.d/www.conf 에 있다.

listen.owner = www-data
listen.group = www-data

우리의 홈디렉토리도 php를 읽어내기 위해서 www-data 읽기 권한을 추가하자. 또는 현재 유저/그룹으로 설정해도 된다.

chown -R www-data /home/text3/

6.nginx를 재가동 하면 Laravel 초기화면이 뜬다.

service nginx restart

Laravel8(PHP7.4, Nginx, MySQL5.7)을 Docker Compose로 한방에 구성해보기

Docker Compose로 nginx, php, mysql 을 한방에 설치해서 환경을 구축해보자.

Docker Compose 로 프로젝트를 구성할때는 docker-compose.yml 에 구성하고자 하는 서비스(nginx, php, mysql등) 을 적어서 한번에 컨포넌트들을 기동한다.
보통 폴더 구성은 아래와 같다.

project
 - myservice
 - docker
   - webserver
   - database
   - php
 -docker-compose.yml

docker 밑에 webserver(nginx),database(myslq),php 폴더가 있는이유는 해당 폴더안에 각 서비스별로 지정하고자 하는 내용이나 설정파일들을 저장하여 docker-compose에서 읽어들이기 위해서이다.
myservice 에는 개발자가 작성한 프로그램 소스를 저장하고, 각 서비스(webserver, php, database)에서 myservice 에 들어있는 소스나 자료를 읽어들여 서버를 기동한다든지 화면에 내용을 출력한다.

docker-compose.yml 은 기본적으로 아래처럼 version과 services 항목등으로 구성된다.

version: '3'

services:
   php:
     php 관련 설정과 php 관련 docker image 
   webserver:
     webserver(nginx) 관련 설정과 webserver(nginx) 관련 docker image 
   database:
     database(mysql) 관련 설정과 database(mysql) 관련 docker image 

이제 각 서비스(php,database,myslq)별로 Dockerfile 작성때와 비슷하게 기술하면 된다.
이때 각 서비스의 내용에 직접 적는 방법도 있지만, 각각 project/docker/php(webserver,database) 에 Dockerfile 에 적어도 된다.
Dockerfile 이 필요한 경우를 예를들자면 각 컨테이너별로 필요한 패키지를 설치해야하거나 명령어를 실행해야 할경우에는 docker-compose.yml 에 기술할수 없어서 별도의 Dockerfile에 적어서 build 항목에 지정하고자 할때 사용된다.

  1. docker-compose.yml
    services 아래에 web,php,database 설치하고자 하는 항목이 있는데, 하위 속성으로 build, ports, depends_on, volumes,links 옵션들이 있다.
    간단하게 설명하자면
    build : 각 서비스별로 Dockerfile 이 존재하는 폴더. Dockerfile 을 자동으로 읽어 들인다.
    ports : 컨테이너내부의 포트를 외부에서도 접속할수있도록 포트포워딩을 하도록 적는다. 외부포트:내부포트이다.
    depends_on: 컨테이너가 기동할때 여기에 적혀있는 서비스가 기동되는것에 의존해서 현재 서비스를 기동한다. 아래 화일에서도 database->php->webserivce 순으로 기동되도록 하여 서비스기동 순서가 잘못되는것을 방지할수있다.
    ( condition : service_healthy 는 각 서비스별로 기동되었다는 확인 조건이 있는데 이를 충족해야만 현재 서비스도 기동되도록 조건을 거는것이다)
    volumes : 현재폴더를 컨테이너내부의 폴더로 포워딩 한다. 즉, 지정한 폴더와 컨테이너 내부의 폴더가 동일하도록 해준다. 단, db 의 경우 db_data가 있는데 이는 컨테이너가 종료한 후에도 데이터가 날라가지 않도록 별도의 볼륨(db_data)을 지정하여 주는게 좋다.
    network : 컨테이너 기동시 네트워크 주소가 안바뀌도록한다.
    healthcheck : healthcheck 항목에서 각 서비스별로 가능한 명령어를 통해 서비스가 기동이 되었는지 확인할수있다. 확인된 상태라면 depends_on 으로 기다리고 있던 서비스가 순차적으로 기동하게 된다.

./docker/docker-compose.yml

version: '3.8'

services:
  web:
    build: ./docker/webserver
    ports:
      - 5080:80
    depends_on:
      php:
        condition: service_healthy
      db:
        condition: service_healthy
    volumes:
      - ./myservice:/usr/share/nginx/html
    networks:
      - app-network

  php:
    build: ./docker/php
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - ./myservice:/var/www/html
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "php-fpm -t"]
      interval: 10s
      timeout: 5s
      retries: 3

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: laravel
      MYSQL_USER: db_user
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - app-network
    ports:
      - 53306:3306
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

networks:
  app-network:
    driver: bridge

volumes:
  db_data:

php,nginx경우에는 관련 모듈 설치가 필요해서 build:./docker/webserver, build:./docker/php 항목이 존재하고, 해당 폴더에 Dockerfile이 있어야 한다.
./docker/webserver/Dockerfile

FROM nginx:1.18-alpine

ENV TZ Asia/Tokyo

# nginx config file
COPY ./*.conf /etc/nginx/conf.d/

WORKDIR /var/www/html

위의 예제에서 COPY 라는 항목이 있는데, default.conf 를 복사해서 nginx컨테이너 내부로 복사하기 때문에 ./docker/server/default.conf 도 준비해야한다.
nginx 의 경우에는 nginx의 설정파일을 컨테이너 외부의 파일에서 수정해서 컨테이너 기동시에 반영해주기 위해서 아래와 같은 파일을 만든다.

./webserver/default.conf

server {
  listen 80;
    index index.php index.html;
    root /var/www/public;

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

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

./docker/php/Dockerfile

FROM php:7.4-fpm
COPY php.ini /usr/local/etc/php/


#Composer install
RUN cd /usr/bin && curl -s http://getcomposer.org/installer | php && ln -s /usr/bin/composer.phar /usr/bin/composer

RUN apt-get update \
&& apt-get install -y \
git \
zip \
unzip \
vim
RUN apt-get update \
    && docker-php-ext-install pdo_mysql

ENV COMPOSER_ALLOW_SUPERUSER 1

ENV COMPOSER_HOME /composer

ENV PATH $PATH:/composer/vendor/bin


WORKDIR /var/www

RUN composer global require "laravel/installer" 

위의 예제에서 COPY 라는 항목이 있는데, php.ini 를 복사해서 php컨테이너 내부로 복사하기 때문에 ./docker/php/php.ini 도 준비해야한다.
./docker/php/php.ini

[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

이제 docker-compose를 이용해서 image 를 만들고, 컨테이너를 실행해보자

docker-compose up 또는 docker-compose up -d

브라우저에서 localhost:5080 해봐도 아무것도 안나올것이다.
이제 아까 만든 php 컨테이너에 들어가서 laravel 을 설치하면 된다.

docker-compose exec php bash 

로 php 컨테이너에 접속해서
/var/www/html 폴더에서

composer create-project laravel/laravel:^8.0 . 

을 실행하면 laravel파일들이 설치되고,
브라우져로 localhost:5080 을 접속하면 화면도 보일것이다.

0 comments:

댓글 쓰기