Skip to main content

7 posts tagged with "nginx"

View All Tags

pm2 앱에서 git hook시에 nginx 502 gateway timeout 오류

· One min read

원인​

git pull을 hook으로 실행하는데 계속 nginx 502 gateway timeout 오류가 발생해 pm2 logs 앱 또는 nginx log를 계속 추적해도 별다른 에러 로그가 없었다. (exec: Internal Server error 라고만 적혀있었다.)

삽질 끝에 watch 속성을 사용하고 있는게 문제였다.

해결​

ecosystem.config.js
module.exports = {
apps: [
{
name: "server",
script: "server.js",
env_production: {
NODE_ENV: "production",
},
watch: true,
ignore_watch: ["node_modules", ".git", "yarn.lock", "package-lock.json"],
exec_mode: "cluster",
instances: "max",
},
],
};

ignore_watch 속성에 .git 폴더와 다른 폴더들이 제대로 예외처리 되었는지 확인해보자.

nginx에 letsencrypt 인증서로 https 가장 빨리 적용하기

· One min read

centos7 기준

nginx 설치​

$ vi /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1

$ yum makecache
$ yum install -y nginx

$ vi /etc/nginx/conf.d/default.conf
## server_name에 도메인 연결

## 문법 체크
$ nginx -t

## nginx 시작
$ systemctl enable nginx
$ systemctl start nginx

certbot 설치​

$ yum install -y epel-release
$ yum install -y certbot-nginx

## 인증
$ certbot --nginx -d my.domain.com

ssl nginx 설정​

기존 포스트 nginx 연동 탭 참조

renew 설정​

$ crontab -e

1 0 1 * * certbot renew --nginx

$ systemctl restart crond

systemctl restart nginx 하면 완료

Docker로 LEMP Stack 구축하기

· One min read

이 포스트 전에 웹서버 세팅을 하나씩 설치해서 띄워보는 걸 권장하고 Docker, SSH Login, LetsEncrypt, sed 명령어의 사용법을 알고 있어야 한다. 구성할 서버 스택은 다음과 같다.

  • Docker
  • Docker-compose
  • Host 에 사용될 Linux (Centos7)
  • Alpain Linux
  • Nginx ^1.13
  • MariaDB ^10.2
  • PHP ^7.1
  • Laravel =5.4
  • LetsEncrypt
  • HTTP2
  • Redis

Docker 설치​

이전 포스트를 참조하자.

Container 쇼핑​

Docker Hub에서 마음에 드는 Container 를 사용해도 되지만, 생각처럼 돌아가는 Container 는 다음과 같았다.

왜 Laradock을 안 썼죠?

  1. Laradock 에서 caddy 를 사용하지 않고 nginx 와 certbot 만을 이용해 http2 환경을 구성하는 예제가 없었다.
  2. 그래도 시도해봤으나 certbot 인증시에 DocumentRoot 를 잡지 못하는 현상을 삽질로 매꿀 시간이 없었다.
  3. Git repo 를 Clone 받아서 Docker-compose 로 Container 를 구동하기 때문에 추후 ECS 에 적용할 수가 없는 구조였다.
  4. 직접 구축해보고 싶었다.

세팅​

nginx-php-fpm​

Laravel 용 및 튜닝을 위해 Docker hub 의 이미지 대신 Git repo 의 이미지를 Clone 해서 세팅을 해보자.

내용 추가 중..

CentOS7 LEMP Stack 설치하기 (HTTP2, PHP7.1, Maria, Letsencrypt)

· 6 min read

LEMP​

Linux, Nginx, MariaDB, PHP

Why LEMP instead of LNMP? We go with LEMP due to the pronunciation for Nginx: Engine-X (en-juhn-ecks). Think of how in English, the article an is used instead of a for hour even though it begins with a consonant. The importance is the sound of the first letter rather than its written representation. Besides, LEMP is actually pronounceable and doesn’t sound like reciting the alphabet.

PHP​

repo 를 등록하고 설치하는 방법이 있지만 php71 등의 이름으로 설정해야되서 번거롭다. yum 명령어의 --enablerepo 옵션을 사용해 php71 repository 를 가져오자.

## php repo를 가져오기
$ yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm

$ vi /etc/yum.repos.d/remi-php71.repo

[remi-php71]
name=Remi\'s PHP 7.1 RPM repository for Enterprise Linux 7 - $basearch
#baseurl=http://rpms.remirepo.net/enterprise/7/php71/$basearch/
mirrorlist=http://rpms.remirepo.net/enterprise/7/php71/mirror
## 이 값을 1로 바꿔준다.
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-remi

$ yum -y install php php-fpm php-devel php-curl php-mcrypt php-mysql php-xmlrpc php-mbstring php-zip 등등

$ systemctl start php-fpm
$ systemctl enable php-fpm

Maria​

예전 포스팅으로 대체한다. 설치방법은 똑같고 버전만 다르게 해주면 된다. 설치 후 서비스 실행만 systemctl 명령어로 해주자.

Xtrabackup​

이제 mysqldump 를 좀 놓아주고 Incremental Backup 을 해주자. 이게 왜 좋은지는 공홈이나 책이나 다른 블로그에 자세히 설명되어있다.

## xtrabackup 설치
$ yum -y install xtrabackup

## 증분백업을 위해 전체 백업이 한 번 필요하다.
## root가 아닌 유저일 경우 해당 DB를 백업하기 위해 PROCESS 등 여러 권한을 추가해야한다.
## (로그 메세지로 추가하라고 나온다.)
$ innobackupex --user='root' --password='암호' --databases='DB' --no-timestamp /백업위치

## 증분백업
$ innobackupex --user='root' --password='암호' --incremental --incremental-basedir='/백업위치/xtrabackup_checkpoints' --no-timestamp /증분백업위치

## 증분백업을 전체백업 위에 얹기
$ innobackupex --apply-log --redo-only --incremental-dir='/증분백업위치' /백업위치

## 증분백업 삭제
$ rm -rf /증분백업위치


## 복원
$ systemctl stop mariadb

## 데이터 폴더를 날려야한다. (만약을 대비해 백업)
$ rm -rf /var/lib/mysql/*
$ innobackupex --copy-back /백업위치

## 권한부여
$ chown -R mysql:mysql /var/lib/mysql
$ systemctl start mariadb

Nginx​

HTTP2 를 적용하기 위해서는 Nginx 1.9 버전과 Openssl 1.0.2 버전 이상이 필요한데, 기본 repository 에는 이 버전이 적용되어있지 않다. 따라서 검색해보면 컴파일 설치를 해야 된다는 글이 다수다. 모든 패키지는 패키지 매니져로 관리하는게 좋다고 생각하는 나로썬 그냥 넘어갈 수 없다. Nginx 최신 repository 를 관리해주는 나이스한 곳을 찾았다.

$ yum -y install yum-utils
$ yum-config-manager --add-repo https://brouken.com/brouken.repo

## 기존 nginx repo를 사용하지 않는다는 옵션
$ yum-config-manager --save --setopt=epel.exclude=nginx*;
$ yum -y install nginx

$ systemctl start nginx
$ systemctl enable nginx

## nginx 버전 확인
$ Nginx -V
nginx version: nginx/1.13.1
built with OpenSSL 1.0.2k 26 Jan 2017

setopt 가 오류가 날 경우​

ngixn.repo 를 만들어주고 연결하자.

$ vi /etc/yum.repos.d/nginx.repo

## vim /etc/yum.repos.d/nginx.repo

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1

## 저장하고 설치 시작

$ yum update
$ yum -y install nginx
$ systemctl start nginx
$ systemctl enable nginx

LetsEncrypt​

공짜 SSL 인 LetsEncrypt 의 이름이 certbot 으로 바뀌었다. 공홈을 참조해도 좋다. 인증을 받기위해 먼저 도메인을 따야한다.

$ yum -y install certbot

## 인증
$ certbot certonly --standalone -d example.com -d www.example.com

## 갱신 확인
$ certbot renew --dry-run

## 갱신하면서 nginx 재부팅
## 이 명령어를 적절히 cron에 넣어주자.
$ certbot renew --pre-hook="systemctl stop nginx" --post-hook="systemctl start nginx"

인증이 성공하면 /etc/letsencrypt/live/example.com/ 경로 아래에 키가 떨어질 것이다. 자세한 명령어 옵션은 Docs 참조.

nginx 연동​

ssl 을 적용하면서 HTTP2 도 붙혀보자. HTTP2 에서는 bundling 보다 파일을 쪼개서 보내는게 더 효율적이라고 한다. (non-blocking 이니까)

## HTTP
server {
listen 80;
server_name example.com www.example.com;

# certbot --webroot 인증을 받기위한 설정
#location ^~ /.well-known/acme-challenge/ {
# default_type "text/plain";
# root /var/www/letsencrypt;
#}

# 80 접속시 443으로 redirect
location / {
return 301 https://$server_name$request_uri;
}
}

## HTTPS
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
root /var/nginx/www/public;
index index.php index.html;

# 지저분한 보안 옵션은 추천옵션이니 넣어주자.
ssl on;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;

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

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

location ~ /\.ht {
deny all;
}

# 캐싱할 데이터가 있다면 추가
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc|woff)$ {
expires 1M;
add_header Cache-Control "public";
}

location ~* \.(?:css|js)$ {
expires 7d;
add_header Cache-Control "public";
}
}

해당 세팅은 Laravel5.4 용이다.

nginx.conf 에는 해당 옵션들도 추가해주자.

nginx.conf
# CPU 물리 코어에 따라 설정한다.
# 1코어에선 1로 나머지는 auto로 설정하면 된다.
# grep ^processor /proc/cpuinfo | wc -l 로 확인 가능
worker_processes 1;

events {
# 각 worker process에서 한 번에 처리할 수 있는 최대 연결 수
# ulimit -n의 값과 같게 설정하자.
worker_connections 1024;
# I/O event 노티 방식을 epoll로 사용. (poll보다 발전한 방식)
use epoll;
# worker가 한 번에 모든 연결을 수용할 수 있도록 설정
multi_accept on;
}

http {
# access_log 제거
access_log off;
server_tokens off;

# iframe 보안 이슈 DENY
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

# PHP 서버라는 header 제거
fastcgi_hide_header X-Powered-By;
# static file 제공 최적화
sendfile on;
# TCP multiple buffer를 individual packet으로 전송하게 변경
tcp_nopush on;
# TCP에서 TCP_CORK 옵션을 활성화
# MTU에서 IP 헤더의 40-60 Byte를 뺀값과 같다는데 뭐라는건지 모르겠다.
tcp_nodelay on;
# keep alive 설정
keepalive_timeout 65;
# keepalive_requests 100000;

# gzip 압축설정
gzip on;
gzip_min_length 1000;
gzip_types application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;
gzip_disable "MSIE [1-6]\.";
}

적용 후에 HTTP2 확인 확장프로그램 설치 후 이 프로그램에 파란불이 들어오면 성공이다.

파일 백업​

소스는 git 으로 관리가 되는데 static 파일은 주기적으로 백업이 필요하다.

file_backup.sh
NOW_DATE=`date`
BACKUP_DATE=`date +"%Y%m%d"`
FILE_DIR=백업할 폴더 경로
BACKUP_DIR=백업된 파일 경로

## gz 압축
tar zcvf ${BACKUP_DIR}/${BACKUP_DATE}.tar.gz ${FILE_DIR}

## 3일 이상된 백업파일은 제거
find ${BACKUP_DIR}/ -mtime +3 -exec rm -f {} \;
## find ${BACKUP_DIR}/ -mtime 3 -delete

여담​

다음부터 Ubuntu 쓸까 생각했는데, Nginx 최신 Repo 를 찾은게 컸다. 하지만 빨리 Docker 책 읽자. Nginx, Reverse Proxy, Redis, PHP, Jenkins 를 한 번에 해결해주겠지. 이제 DockerFile 이 잘 읽히긴 하는데, 언제쯤 갈아탈 수 있으려나

Nginx for Windows - 3. Virtual Host

· One min read

Nginx - 2. PHP 연동에서 이어집니다.

설정​

conf\nginx.conf 파일에서 쉽게 추가가 가능하다.

nginx.conf
http {
# 기존에 있던 default 설정
server {
...
}

# 이렇게 server 구문을 하나 더 추가한다.
server {
listen 8000;
# 서버 주소
server_name local.test.com;
index index.php;
# 서버 경로
root D:/workspace/testphp/;

location / {
try_files $uri /index.php$is_args$args;
}

# php 사용을 개별로 추가해야한다.
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9123;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
...
}

위 소스는 index.php를 라우터로 사용하기 위해 설정되었으므로, 17, 22, 23줄의 구문은 없어도 된다.

Host 파일 수정​

Apache Virtual Host 설정 문서의 Host 파일 수정 메뉴를 따라 진행하면 된다.

연동 확인​

nginx 서비스를 재시작하고 확인한다.

Nginx for Windows - 2. PHP 연동

· 2 min read

Nginx 설치에서 이어집니다.

Nginx를 설치했으니 PHP와 연동을 해보자.

설치​

이전 포스트로 대체한다. Apache버전은 상관이 없으니 x64 Thread Safe 버전으로 3번까지만 따라서 설치하면된다.

연동​

nginx 설정​

Nginx 폴더에서 conf/nginx.conf를 수정한다.

http {
...
server {
...
location / {
root html;

# index.php를 추가
index index.html index.htm index.php;
}
...
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
# 이 부분 주석을 모두 제거해준다.
location ~ \.php$ {
root html;

# nginx에서 9123포트를 추천한다.
fastcgi_pass 127.0.0.1:9123;
fastcgi_index index.php;

# SCIPRT를 $document_root 로 변경
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
...
}
}

php-cgi 설정​

nssm을 사용하는 방법과 배치 파일을 만드는 방법이 있는데 전자를 추천한다. bat 파일은 nginx restart를 할 때마다 따로 실행해줘야한다.

다른 포스팅에는 php-cgi 서비를 cmd에서 sc create 명령어를 사용하여 등록하는 부분이 있는데 windows10 환경에서 서비스가 1053 오류를 뱉으며 죽는다. 시간 낭비하지 말자.

nssm​

nginx에 지난 스텝에서 설치한 nssm을 사용한다. nginx\nssm\win64 폴더로 이동해 php 등록 커맨드를 입력한다.

./nssm.exe install php

php-cgi 경로를 선택한 뒤 아래 명령어를 Arguments 필드에 넣어준다.

## 경로를 알맞게 수정해주자.
D:\php7\php-cgi.exe -b 127.0.0.1:9123 -c D:\php7\php.ini

image from hexo

서비스를 실행한다. image from hexo

실행이 안되는 경우 arguments에 앞의 경로를 제거하고 -b 127.0.0.1:9123 -c D:\php7\php.ini 만 입력해준다.

bat​

배치 파일을 만들어 nginx가 실행 되기전만 php-cgi를 킬 수도 있다.

@ECHO OFF
ECHO Starting PHP CGI...
set PATH=D:\php7;%PATH%
D:\php7\php-cgi.exe -b 127.0.0.1:9123 -c D:\php7\php.ini

위 소스의 경로를 알맞게 수정한 뒤 start-php-cgi.bat으로 저장 후 실행한다.

확인​

**nginx\html\**에 index.php를 만든다.

index.php
<?php
phpinfo();

localhost:88/index.php로 접속한다. image from hexo

여담​

한 방에 설치하는 방법도 있지만 현재 버전까지는 C:\말고 D:\에 php를 설치한 사람에 대한 배려는 없다. (bat 파일을 건드려봐도 dll 안에 로깅하는 부분에서 오류 발생)

Nginx for Windows - 1. Setup

· One min read

Windows에서 Nginx로 로컬 웹서버를 돌려보자.

설치​

다운로드​

Nginx 홈페이지에서 Windows 버전을 다운로드 받는다. image from hexo

압축을 풀어 원하는 위치(D:\nginx)로 옮겨주자

설정​

apache, iis가 중복이 된다면 conf/nginx.conf 파일을 열어 포트 설정을 바꿔준다.

nginx.conf
http {
...
server {
listen 88; # 여기를 수정해주자.
server_name localhost;
...
}
...
}

실행​

nginx.exe를 더블 클릭한다.

서비스 등록​

실행은 되었지만 서비스를 등록해야 자동으로 실행되고 on/off를 관리하기가 쉽다. 다른 포스트에 있는 github의 2011년 엔진엑스 서비스 등록 소스는 찾아봐도 없길래 새로운 방법으로 등록한다.

nssm​

nssm에서 서비스 등록 프로그램을 다운받는다. image from hexo

압축을 풀어주고(D:\nginx\nssm-2.24) 자신의 windows bit에 맞는 폴더에서 nssm.exe를 커맨드로 실행하면 된다.

./nssm.exe install nginx

nginx 경로를 잡아주고 Install Service 버튼을 클릭한다. image from hexo

실행​

services.msc를 실행해 서비스 창을 열어 nginx를 실행한다. image from hexo

확인​

image from hexo

Nginx - 2. PHP 연동으로 이어집니다.