- 전체
- 명
- 오늘 찾아주신 분
- 명
1편에 이어서 이번 포스팅은 Nginx 와 PHP-FPM 의 세부 설정 파일을 마무리 짓는 내용을 작성해보려 한다.
1. Nginx 필수 설정 파일
Nginx 를 써봤다면, nginx.conf 파일이 메인 설정 파일이라는 것은 알고 있을 것이다. 몇개의 conf 를 만들었더라도 메인은 nginx.conf 이기 때문에 include 되지 않으면 해당 conf 에 대해서는 실행이 되지 않을 것이다. 그렇다고 많은 양의 설정들을 nginx.conf 에 넣는 것은 비효율적이기 때문에 유연하게 변경을 해보도록 한다.
우선, 저번 포스팅에서 Docker 작업을 위한 폴더 구성을 할 때 만들었던 conf 를 다음과 같이 구성해보았다.
- ./conf.d : 설정의 목적에 맞는 아이들이 들어갈 것이다.
- ./default.d : 웹 서비스 명세에 기본적으로 있어야 하는 아이들이 들어갈 것이다.
- ./site-available : 웹 서비스별 명세가 들어갈 것이다.
일단, site-avaliable 에 들어갈 웹 서비스 명세를 작성해보자.
# ./site-available/service.conf
server {
listen 80 default_server;
server_name _;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
include /etc/nginx/default.d/*.conf;
}
include 를 통해 default.d 에 있는 기본적인 아이들을 포함 시킬 것이다. 서버에서 작동할 것이기 때문에 경로들 또한 로컬 경로가 아닌 서버 시점에서 바라보는 경로로 설정해 주도록 한다.
다음으로는 default.d 에 php 확장자가 들어가면 인식할 수 있도록 만들어주는 블록을 적을 것이다.
# ./default.d/php.conf
index index.php index.htm index.html;
location ~ \.(php|phar)(/.*)?$ {
fastcgi_split_path_info ^(.+\.(?:php|phar))(/.*)$;
fastcgi_intercept_errors on;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php-fpm;
}
추가적으로 index 페이지는 index.php index.html index.html 인 아이들만 되도록 명세를 해주고, location 블록을 통해서 php와 phar 파일을 따로 처리하도록 한다. 여기서 주목해야 될 곳은 fastcgi_pass 부분으로, 보통 여기에다가는 127.0.0.1:9000 형식으로 넣어주는데 나 같은 경우에는 upstream 을 정의해놓고 해당 upstream 으로 던져주도록 만들었다. 이 방식은 AWS EC2 에서 nginx 를 설치하는데 이렇게 되어있어서 방법을 익혀놓았다. upstream 은 미리 설정을 정의하는 것이기 때문에 conf.d 에 입력을 시켜놓았다.
# ./conf.d/php-fpm.conf
upstream php-fpm {
server unix:/var/run/php-fpm/www.sock;
}
upstream 이름은 php-fpm 이기 때문에 위에 fastcgi_pass 도 php-fpm 으로 맞춰놓았다. 그리고 server 의 값은 127.0.0.1:9000 이 아닌 unix:/var/run/php-fpm/www.sock 을 적어놓았다. php-fpm 을 사용하게 된다면 127.0.0.1:9000 보다는 해당 방식이 훨씬 처리하는 속도가 빠르다고 하여 변경을 했는데 실제로 그 둘의 차이가 어떻게 되는 지는 눈으로 확인 해보진 못했다. 여튼 unix 방식을 사용하는 것을 대부분 추천하고 있기 때문에 이렇게 사용해 보도록 한다.
이제 이 모든 것들을 Nginx 에서 실행할 수 있도록 nginx.conf 에 작성을 해주어야 한다.
# nginx.conf
daemon off;
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/site-available/*.conf;
}
http 블록을 확인해보면 맨 마지막 줄에 include 두 줄을 작성하며 Nginx 설정을 끝을 내도록 한다.
2. PHP-FPM 필수 설정 파일
Nginx 만 되었다고 해서 PHP 가 동작하진 않는다. 로컬에서 작업하고 붙여 넣어 준 Nginx 와는 다르게 PHP-FPM 은 작동하는데에 몇가지 설정만 변경해주면 되기 때문에 따로 로컬에 파일을 작성하지 않고 스크립트로면 문자를 변경하여 처리하도록 작성했다.
각 필요 설정 파일들은 이미 Dockerfile 을 통해서 옮기고, 이름바꾸고 했을 것이다. 하지만 설정 파일 내부의 데이터들은 바꾸지 못했는데, 해당 작업을 Dockerfile 마지막에 넣어준 run-script.sh 파일을 통하여 실행할 것이다.
#!/bin/sh
set -eux
mkdir /var/run/php-fpm
sed -i 's/listen = 127.0.0.1:9000/listen = \/var\/run\/php-fpm\/www.sock/g' /usr/local/php/etc/php-fpm.d/www.conf
sed -i 's/;listen.owner/listen.owner/g' /usr/local/php/etc/php-fpm.d/www.conf
sed -i 's/;listen.group/listen.group/g' /usr/local/php/etc/php-fpm.d/www.conf
sed -i 's/;listen.mode/listen.mode/g' /usr/local/php/etc/php-fpm.d/www.conf
rc-service php-fpm start
nginx -t
nginx
Alpine 리눅스에서는 /bin/bash 가 아닌 /bin/sh 를 사용하여 스크립트를 짜는 것 같다.
set -eux 를 먼저 호출하였는데, e와 u 는 어떤 차이가 있는 지 확인은 못했지만 x 를 추가 하게 되면, 이미지를 컨테이너로 실행했을 때, 어떤 커맨드를 실행했는 지 눈으로 확인할 수 있다. 그래서 디버깅 용도로 꽤나 유용한 플래그라고 할 수 있다.
mkdir 를 통해서 /var/run/php-fpm 에 폴더를 생성해주었는데, Nginx upstream 설정할 때 /var/run/php-fpm/www.sock 파일을 바라보도록 설정을 해서, 없는 폴더이기 때문에 생성을 미리 해주어야 한다. www.sock 파일은 PHP-FPM 이 실행되면 자동으로 생성된다. (폴더가 없으면 에러가 발생한다.)
그 다음 sed -i 로 시작하는 4줄의 커맨드들이 있는데, 이 부분이 설정 파일 내에서 변경할 사항들을 적어놓은 곳이다. 바꾸는 파일은 전부 www.conf 파일 내부인데, sed 명령어 하나를 통하여 여러군데를 고치는 방법을 몰라 4부분에 걸쳐서 각 줄마다 고쳐보았다.
먼저 첫번째 줄, listen = 127.0.0.1:9000 의 내용을 listen=/var/run/php-fpm/www.sock 으로 변경을 했다.
2~4번째 줄, listen 앞에 있는 세미콜론을 삭제하여 주석이 아닌 상태로 변경하였다. 이 작업을 하지 않으면 php 주소를 입력했을 때 파일이 다운로드 되는 현상을 확인할 수 있었다.
수정까지 완료된 다음에 openrc 패키지에 있는 rc-service 를 통해서 php-fpm 을 실행시켰으며, 추가적으로 Nginx 의 설정에 문제가 있는지 확인하기 위해 nginx -t 를 하고 nginx 를 돌렸다.
비로소 이미지를 만들 준비는 모두 끝났다. 이제 컴파일 같은 작업을 하여 이미지를 생성해보자.
3. 이미지 생성
지금까지 Dockerfile 에 명세가 잘 되어있다면, 이미지를 만드는데 큰 문제는 없을 것이다. 그럼 바로 터미널로 이동하여 커맨드를 입력해보도록 하자. 터미널을 이용하여 Dockerfile 이 있는 작업폴더로 이동한 다음 다음의 커맨드로 실행을 한다.
docker build . --no-cache -t [IMAGE_NAME]
폴더 내에 Dockerfile 이 있다면 자동으로 감지하여 이미지를 생성해준다. 이미지 이름은 -t 옵션에 작성해주면 된다. 중간에 --no-cache 의 경우에는 실패하거나 뭐 해서 이미지를 다시 생성하는 경우에 기존에 물고 있던 데이터들을 다시 사용할 수 있기 때문에, Dockerfile 을 수정한 후 변경된 옵션들이 적용되지 않을 수 있어서 지정을 해주도록 한다.
Dockerfile 명세중에 시간이 제일 많이 잡아 먹는 부분이 단연 PHP 를 컴파일 할 때인데, 대략 600s 이상이었으니 10분 정도 잡아먹는 것 같다. 모든 작업이 끝나면 이미지를 컨테이너로 실행하는 부분만 남았다.
4. 실행
여기까지 되었으면 이미지 생성은 완료 되었고, GUI 에서도 이미지 항목에 만들어진 것을 볼 수 있다. 이제 해당 이미지를 컨테이너로 실행시켜 보도록 하자.
터미널에서 다음과 같이 입력을 한다.
docker run -d -p [PORT]:80 \
--volume $(pwd)/html:/usr/share/nginx/html \
--name [CONTAINER_NAME] \
[IMAGE_NAME]
[PORT] 는 외부에서 컨테이너로 접속할 때 어떤 포트로 접속할 지를 정해주는 것이다. 만약 -p 2357:80 이라고하면 http://localhost:2357 로 브라우저에서 접근을 할 수 있게 된다. 컨테이너 내부에서는 80번 포트를 통해 접근하는 것으로 알고 있게 된다.
--volume 은 로컬 폴더를 이미지 내의 폴더에 마운트 시키는 것인데, 형식은 --volume [로컬 경로]:[이미지 내 경로] 가 된다. Dockerfile 에 /usr/share/nginx/html 로 VOLUME 을 통해 지정을 했기 때문에 이 값을 [이미지 내 경로]에 작성 해주고, [로컬 경로] 는 절대주소를 작성해주면 된다. $(pwd) 를 통해서 현재 위치의 폴더값을 가져와서 집어넣었다.
--name 은 컨테이너의 이름을 정해주면 된다
마지막으로 어떤 이미지를 사용할 것인지 입력하고서 엔터를 치면 컨테이너가 실행이 될 것이다.
작업 폴더의 html 폴더에 index.php 를 만들어주고 phpinfo() 를 실행시켜 테스트 페이지가 잘 작동되는 지 확인해보도록 하자.
잘 나오면 성공!!
[Docker] Nginx + PHP-FPM 이미지를 만들어보자 (1편) (0) | 2022.06.27 |
---|---|
[Linux] PHP Composer 다른 방식으로 설치하기 (무설치) (0) | 2022.03.14 |
[Linux] Nginx 소스 컴파일 (베껴)설치하기 (0) | 2022.03.10 |
[Linux] 자주 쓰는 커맨드 모음 (0) | 2022.03.08 |
[Windows] PDFium 와 boost::gil 을 함께 사용하기 (0) | 2022.02.04 |