아파치에서 inotify-tools을 사용한 WebP 이미지 적용 및 관리 방법

Updated on 2020-02-29 by

이미 우분투 서버의 크론탭 기능을 활용한 이미지 최적화 시스템 구축 방안에 대해 정리했고, 이를 기반으로 운영중입니다.

그런데 조금 더 자료를 검색하다보니 inotify-tools을 사용해 조금 더 효과적으로 Webp 이미지를 적용하고 관리할 수 있는 방법이 있어 소개해 봅니다.

이는 VPS업체인 디지탈오션(digitalocean) 튜터리얼에서 소개하는 방법인데요. 도움이 될 것 같아서 번역 겸해서 소개해 봅니다.

이 글에서는 우분투 16.04와 CentOS 7를 설치하고 웹서버로는 아파치를 사용자를 대상으로 설명하고 있습니다.

How To Create and Serve WebP Images to Speed Up Your Website

필요 조건

이 방법은 우분투 16.04와 CentOS 7에 아파치 사용자를 대상으로 설명된 것입니다. 저는 NGINX를 사용하므로 소개만 하기로 합니다.

  • 사용자는 non-root sudo user여야 함
  • 웹서버는 아파치
  • mod_rewrite가 설치 되어 있어야 함

1. cwebp 설치 및 이미지 폴더 준비

여기에서는 webp 이미지를 만들 수 있는 webp를 설치해 webp를 사용할 수 있게 만들고 webp이미지를 저장할 수 있는 폴더를 만드는 방법에 대해서 알아봅니다.

1.1. webp 설치

sudo apt-get update
sudo apt-get install webp Code language: PHP (php)

만약 CentOS 7 사용자라면 아래 명령어를 사용합니다

sudo yum install libwebp-toolsCode language: PHP (php)

1.2. 이미지 폴더 생성

webp라는 이미지 저장 폴더를 만듭니다. 이는 아파치 웹 루트( /var/www/html )에 만듭니다.

sudo mkdir /var/www/html/webpCode language: PHP (php)

이 폴더의 소유권을 변경합니다.

sudo chown sammy: /var/www/html/webpCode language: PHP (php)

새로 만든 이미지 폴더로 이동합니다.

cd /var/www/html/webpCode language: PHP (php)

이 단계에서 아파치 서버에서 mod_rewrite와 cwebp이 설치되어 있고 이미지 폴더가 만들어 졌다면 준비가 완료된 것입니다.

2. cwebp를 이용 이미지 압축

이용자들에게 webp 이미지를 보여주려면 webp 이미지가 만들어져야 합니다. 너무 당연한 소리..

이를 위한 일반적인 명령어는 아래와 같은 형식을 띱니다. 여기서 -o 옵션은 WebP 파일의 경로를 지정합니다.

cwebp image.jpg -o image.webpCode language: PHP (php)

3. JPEG와 PNG 이미지를 변환합니다.

이제 본격적으로 JPEG와 PNG 이미지를 변환을 위한 스크립트 파일 webp-convert.sh를 만들어 봅니다.

nano ~/webp-convert.shCode language: PHP (php)

여기에는 아래와 같은 내용으로 구성됩니다.

#!/bin/bash

# converting JPEG images
find $1 -type f -and \( -iname "*.jpg" -o -iname "*.jpeg" \) \
-exec bash -c '
webp_path=$(sed 's/\.[^.]*$/.webp/' <<< "$0");
if [ ! -f "$webp_path" ]; then 
  cwebp -quiet -q 90 "$0" -o "$webp_path";
fi;' {} \;

# converting PNG images
find $1 -type f -and -iname "*.png" \
-exec bash -c '
webp_path=$(sed 's/\.[^.]*$/.webp/' <<< "$0");
if [ ! -f "$webp_path" ]; then 
  cwebp -quiet -lossless "$0" -o "$webp_path";
fi;' {} \;
Save the fileCode language: PHP (php)
  • find : 지정된 디렉토리 내에서 파일을 검색합니다.
  • $1 :이 위치 매개 변수는 명령 행에서 가져온 이미지 디렉토리의 경로를 지정합니다.
  • -type f : 일반 파일 만 찾도록 합니다.
  • -iname : 지정된 패턴과 파일 이름을 일치시킵니다.
    -iname은 대소 문자를 구분하지 않으며, jpg 또는 .jpeg 파일 이름을 찾도록 합니다.
  • -o : find 명령을 사용하여 첫 번째 -iname 테스트(“*.jpg”) 또는 두 번째 테스트(iname “*.jpg”)와 일치하는 파일을 나열합니다.
  • () : -and 연산자와 함께이 테스트를 괄호로 묶으면 첫 번째 테스트 (예 : -type f)가 항상 실행됩니다.
  • bash: webp 이미지 파일을 만드는 스크립트를 실행합니다.
    이 스크립트는 -c 옵션 덕분에 문자열로 bash로 전달됩니다.
  • ‘commands’ : 이 자리 표시자는 webp 이미지를 만드는 스크립트입니다.
  • webp_path : 이 변수는 위치 매개변수 $0로 표시된 bash 명령에서 sed 및 일치하는 파일 이름을 사용하여 생성됩니다.
    여기서 문자열(<<))은 이 이름을 sed로 전달합니다.
  • if [ ! -f “$webp_path” ] : 이 테스트는 “$webp_path”라는 이름의 파일이 이미 존재하는지(!) 논리 비 연산자를 사용하여 확인합니다.
  • cwebp : webp 파일이 존재하지 않는 경우 -q 옵션(상태를 출력하지 않음)으로 webp 이미지 파일을 만듭니다.

이 스트립트 실행 가능하도록 권한을 변경합니다.

chmod a+x ~/webp-convert.shCode language: PHP (php)

이 스크립트 파일은 이미지 폴더에서 실행합니다.

./webp-convert.sh /var/www/html/webpCode language: PHP (php)

4. 이미지 폴더 변경 사항을 모니터링 하기

이 단계에서는 notify-tools을 이용해서 이미지 폴더에서 어떤 변경 사항이 발생하는지 모니터링하고 이에 따른 액션읗 취합니다.

4.1. inotify-tools 설치하기

우분투 18.04를 위한 inotify-tools 바이너리 패키지가 있기 때문에 apt-get 명령어로 inotify-tools를 설치할 수 있습니다.

sudo apt-get update -y
sudo apt-get install -y inotify-tools
Code language: PHP (php)

참고로 CentOS 7을 이용한다면 다음 명령어를 이용해서 설치할 수 있습니다.

sudo yum install epel-release
sudo yum install inotify-tools
Code language: PHP (php)

4.2. inotify-tools 이용한 모니터링 스크립트 작성

inotifywait -q -m -r --format '%e %w%f' -e close_write -e moved_from -e moved_to -e delete $1 Code language: PHP (php)
  • inotifywait: 이 명령어는 특정 폴더의 변경 내용을 모니터링 합니다.
  • -q: 이 옵션은 inotifywait작동 시 불필요한 소리와 메세지를 내지말도록 합니다.
  • -m: 이 옵션은 inotifywait를 계속 실행하고, 어느 한 이벤트가 끝나도 종료하지 않습니다.
  • -r: 이 옵션은 지정된 폴더와 하위 폴더 모니터링을 반복적으로 실행합니다.
  • --format: 이 옵션은 inotifywait에게 이벤트 이름과 파일 경로를 이용하여 변경 사항을 모니터링하도록 합니다.
  • –format ‘%w%f’ : /complete/path/file.name과 같은 형식으로 파일을 인쇄(print out)
  • 모니터링하는 이벤트는 close_write(파일을 만들고 디스크에 기록을 완료할 때 발생), moved_from 및 moved_to (파일 이동 시) 및 delete (파일 삭제 시)입니다.
  • $1: 변경된 파일 경로를 가지고 있는 위치 매개 변수
| grep -i -E '\.(jpe?g|png)$' --line-bufferedCode language: PHP (php)
  • grep : 이 명령어를 사용해 변경된 파일이 JPEG나 PNG 파일인지 확인합니다.
  • -i : 이 옵션은 grep에게 대문자, 소문자를 무시하도록 합니다.
  • -E : 이 옵션은 grep이 확장 정규 표현식을 사용하도록 합니다.
  • –line-buffered : 이는 grep에게 일치하는 행을 while 루프에 전달하도록 지시합니다.
| while read operation path: do
  # commands
done;Code language: PHP (php)
  • 여기서는 read 명령으로 while 루프를 만듭
  • read는 inotifywait가 감지 한 이벤트를 처리하여 $ operation이라는 변수에 처리하고 파일 경로는 $ path라는 변수에 지정합니다.

while 루프가 이벤트를 확인하면, 그 결과에 따라 다음 명령을 수행합니다.

  • 새로운 이미지 파일을 생겼거나 대상 폴더로 이동해온 경우 이 이미지에 대한 WebP 파일을 만듭니다.
  • 관련 이미지 파일이 삭제되거나 대상 폴더에서 다른 곳으로 이동한 경우 WebP 파일을 삭제합니다.

루프 내부에는 세가지 주요 섹션이 있습니다. webp_path라고 불리우는 변수는 해당 이미지의 WebP에 대한 경로 정보를 가지고 있습니다.

webp_path="$(sed 's/\.[^.]*$/.webp/' <<< "$path")";Code language: PHP (php)
if [ $operation = "MOVED_FROM" ] || [ $operation = "DELETE" ]; then
  # commands to be executed if the file is moved or deleted
elif [ $operation = "CLOSE_WRITE,CLOSE" ] || [ $operation = "MOVED_TO" ]; then
  # commands to be executed if a new file is created
fi;Code language: PHP (php)
  • 만약 파일이 다른 곳으로 옴겨졌거나 지워졌으면 WebP 파일을 지웁니다.
if [ -f "$webp_path" ]; then
  $(rm -f "$webp_path");
fi;
if [ $(grep -i '\.png$' <<< "$path") ]; then
  $(cwebp -quiet -lossless "$path" -o "$webp_path");
else
  $(cwebp -quiet -q 90 "$path" -o "$webp_path");
fi;Code language: PHP (php)

만약 이미지가 새로 만들어졌다면 아래 조건에 따라 압축이 이루어집니다.

  • 만약 PNG 이미지라면 무손실 압축을 실시
  • PNG 이미지가 아니라면 손실 압축을 실시

이미지 폴더를 모니터링하고 변화에 따른 후속 조치를 취하는 전체 스크립트는 아래와 같습니다. 이 스크립트를 watchers.sh에서 반영합니다.

nano watchers.shCode language: PHP (php)

아래 스크립트를 watchers.sh에 포합시킵니다.

#!/bin/bash
echo "Setting up watches.";

# watch for any created, moved, or deleted image files
inotifywait -q -m -r --format '%e %w%f' -e close_write -e moved_from -e moved_to -e delete $1 \
| grep -i -E '\.(jpe?g|png)$' --line-buffered \
| while read operation path; do
  webp_path="$(sed 's/\.[^.]*$/.webp/' <<< "$path")";
  if [ $operation = "MOVED_FROM" ] || [ $operation = "DELETE" ]; then # if the file is moved or deleted
    if [ -f "$webp_path" ]; then
      $(rm -f "$webp_path");
    fi;
  elif [ $operation = "CLOSE_WRITE,CLOSE" ] || [ $operation = "MOVED_TO" ]; then  # if new file is created
     if [ $(grep -i '\.png$' <<< "$path") ]; then
       $(cwebp -quiet -lossless "$path" -o "$webp_path");
     else
       $(cwebp -quiet -q 90 "$path" -o "$webp_path");
     fi;
  fi;
done;Code language: PHP (php)

watchers.sh 파일을 실행가능토록 권한을 변경합니다.

chmod a+x ~/webp-watchers.shCode language: PHP (php)

이 배치 파일은 아래와 같은 형식으로 사용합니다.

./webp-watchers.sh /var/www/html/webp > output.log 2>&1 &Code language: PHP (php)

5. HTML에서 WebP 이미지 사용

여기에서는 아파치에서 WebP 이미지 파일을 활용할 수 있도록 만드는 방법을 설명합니다.

먼저 /var/www/html/webp 폴더에 .htaccess 파일을 만듭니다. /var/www/html/webp/.htaccess

nano /var/www/html/webp/.htaccessCode language: PHP (php)

아래 내용이 반영됩니다.

<ifModule mod_rewrite.c>
  RewriteEngine On 
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_URI}  (?i)(.*)(\.jpe?g|\.png)$ 
  RewriteCond %{DOCUMENT_ROOT}%1.webp -f
  RewriteRule (?i)(.*)(\.jpe?g|\.png)$ %1\.webp [L,T=image/webp,R] 
</IfModule>

<IfModule mod_headers.c>
  Header append Vary Accept env=REDIRECT_accept
</IfModule>

AddType image/webp .webpCode language: PHP (php)

새롭게 뉴스레터를 시작했습니다.

1️⃣ 주식 등 투자 정보 : 기업 분석, IB 투자의견 등 투자 관련 내용
..... 테슬라 실적 및 IB들의의 테슬라 투자의견
2️⃣ 사례 및 트렌드 : 사례연구와 트렌드 관련 괜찮은 내용
.....유튜브와 경쟁대신 구독 전환한 비디오 플래폼 비메오 사례

서울에 생긴 Vultr 서버 100$ 프로모션

안녕하세요?
새로운 사이트 구축을 위한 신규 서버를 고민하신다면 , 서울 리젼이 생겨 더욱 빨라진 Vultr 서버를 Vultr 100$ 프로모션으로 이용해 보세요.

아래 프로모션 코드 링크를 통해 Vultr에서 서버 구축 후 1달 이상 사용 및 $25이상 결제 時 추가 100$을 주는 프로모션입니다.

Vultr는 서울에도 리젼이 있어 매우 빠르고, 아마존 웹 서비스(AWS)보다 성능이 높으며 가장 가성비가 뛰어납니다.

거기다 사용자 UI도 좋고, 15개까지 스냅샷을 무료로 제공하기 때문에 관리하기 좋습니다. 그리고 지금 100$ 프로모션처럼 가격적인 메리트도 있습니다.

우분투 20.04와 PHP 8 기반 워드프레스 설치 방법

가상 서버를 운영하고픈 勇者에게 전하는 가상 서버 운영 입문 노하우 – Vultr 가상서버호스팅(VPS)를 중심으로

워드프레스 최적화를 위한 18개월간의 고민, 그 노하우를 담다.

도쿄 리젼과 비교해 본 Vultr 서울 리젼 사용기

가성비가 뛰어난 Vultr 가상서버호스팅(클라우드호스팅,VPS) 사용기

Subscribe
Notify of
guest
0 Comments
Oldest
Newest
Inline Feedbacks
View all comments