# πŸ—‚οΈ 정적 μ‚¬μ΄νŠΈ μ„œλΉ„μŠ€ 파일 μ„œλΉ„μŠ€λŠ” Pingclairκ°€ ν•˜λŠ” 일의 λ‚˜λ¨Έμ§€ μ ˆλ°˜μž…λ‹ˆλ‹€. 이 νŽ˜μ΄μ§€λŠ” `root`와 `file_server`μ—μ„œ μ‹œμž‘ν•΄ μ••μΆ•, μΊμ‹œ 헀더, λΆ€λΆ„ μš”μ²­, 단일 νŽ˜μ΄μ§€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ— ν•„μš”ν•œ ν΄λ°±κΉŒμ§€ μŒ“μ•„ 올리고, 각 λ‹¨κ³„μ—μ„œ μ„œλ²„κ°€ μ‹€μ œλ‘œ 무엇을 λ‹΅ν•˜λŠ”μ§€ 보여 μ€λ‹ˆλ‹€. ## 🧾 μ‹œμž‘ν•˜κΈ° 전에 - Pingclairκ°€ μ„€μΉ˜λ˜μ–΄ μ‹€ν–‰ 쀑이어야 ν•©λ‹ˆλ‹€([μ„€μΉ˜](/ko/start/install/)). μ‹€ν—˜ν•˜λŠ” λ™μ•ˆμ—λŠ” μ„œλΉ„μŠ€λ₯Ό 멈μΆ₯λ‹ˆλ‹€: `sudo pc service stop`. - μ„œλΉ„μŠ€ν•  디렉터리. μ˜ˆμ œλŠ” `/srv/site`λ₯Ό μ”λ‹ˆλ‹€. ## πŸ“ 디렉터리 μ„œλΉ„μŠ€ ```caddyfile http://:8080 { root * /srv/site file_server } ``` ```bash sudo cp Pingclairfile /etc/Pingclair/Pingclairfile sudo pingclair validate /etc/Pingclair/Pingclairfile sudo systemctl restart pingclair curl -i http://localhost:8080/ ``` ```text HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Last-Modified: Tue, 22 Sep 2026 04:37:54 GMT ETag: "5e-6ab20622" Accept-Ranges: bytes ``` `root *`λŠ” λͺ¨λ“  μš”μ²­μ— μ‚¬μ΄νŠΈ 루트λ₯Ό μ§€μ •ν•˜κ³  `file_server`κ°€ κ·Έκ³³μ—μ„œ μ„œλΉ„μŠ€ν•©λ‹ˆλ‹€. μ—†λŠ” κ²½λ‘œλŠ” `404`λ₯Ό λ‹΅ν•©λ‹ˆλ‹€. ## πŸ—œοΈ μ••μΆ• ```caddyfile http://:8080 { root * /srv/site encode zstd gzip file_server } ``` μΈμˆ˜λŠ” μ„ ν˜Έ μˆœμ„œμž…λ‹ˆλ‹€. 같은 36 KB ν…μŠ€νŠΈ νŒŒμΌμ„ μ„Έ κ°€μ§€ `Accept-Encoding`으둜 μš”μ²­ν•œ, 이 κ΅¬μ„±μ—μ„œμ˜ μΈ‘μ •κ°’: ```text zstd 200 65 bytes content-encoding: zstd gzip 200 301 bytes content-encoding: gzip identity 200 36000 bytes (no content-encoding) ``` BrotliλŠ” ν”„λ‘μ‹œ 응닡에 κ΅¬ν˜„λ˜μ–΄ μžˆμ§€ μ•Šκ³ , μš”μ²­ν•˜λ©΄ μ‘°μš©ν•œ ν•˜ν–₯이 μ•„λ‹ˆλΌ 컴파일 였λ₯˜κ°€ λ©λ‹ˆλ‹€. ```text Error: ❌ Configuration Error: Compile error: Unsupported feature: `encode br`: Brotli is not implemented for proxied responses; use `encode zstd gzip` ``` λ©”μ‹œμ§€κ°€ λŒ€μ•ˆμ„ μ•Œλ € μ€λ‹ˆλ‹€. μ„œλ²„κ°€ 지킬 수 μ—†λŠ” 것을 μš”κ΅¬ν•˜λŠ” 섀정은 μ•„μ˜ˆ μ‹€ν–‰λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. ## ⏳ μΊμ‹œ 헀더 `file_server`λŠ” 이미 쑰건뢀 μš”μ²­μ— μ‘λ‹΅ν•©λ‹ˆλ‹€. μœ„μ˜ `ETag`와 `Last-Modified`κ°€ ν΄λΌμ΄μ–ΈνŠΈκ°€ `If-None-Match`λ‚˜ `If-Modified-Since`둜 되돌렀 λ³΄λ‚΄λŠ” κ°’μž…λ‹ˆλ‹€. 보관 기간은 당신이 μ •ν•  일이고, 그것이 참인 κ²½λ‘œμ— λ‘‘λ‹ˆλ‹€. ```caddyfile http://:8080 { root * /srv/site encode zstd gzip header Cache-Control "public, max-age=60" @assets path /assets/* header @assets Cache-Control "public, max-age=31536000, immutable" file_server } ``` μΈ‘μ •: νŽ˜μ΄μ§€μ—λŠ” `Cache-Control: public, max-age=60`, `/assets/*`μ—λŠ” `public, max-age=31536000, immutable`. immutable은 파일 이름이 λ‚΄μš©κ³Ό ν•¨κ»˜ λ°”λ€” λ•Œλ§Œ μ •μ§ν•©λ‹ˆλ‹€. κ·Έλž˜μ„œ λΉŒλ“œ 도ꡬ가 이름에 ν•΄μ‹œλ₯Ό λΆ™μž…λ‹ˆλ‹€. λΆ€λΆ„ μš”μ²­μ—λŠ” 섀정이 ν•„μš” μ—†μŠ΅λ‹ˆλ‹€. μ•ž 10λ°”μ΄νŠΈλ₯Ό μš”μ²­ν•œ ν΄λΌμ΄μ–ΈνŠΈλŠ” 그것을 λ°›μŠ΅λ‹ˆλ‹€. ```text HTTP/1.1 206 Partial Content Content-Length: 10 Content-Range: bytes 0-9/36000 ``` ## 🧭 단일 νŽ˜μ΄μ§€ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λΈŒλΌμš°μ €μ—μ„œ λΌμš°νŒ…ν•˜λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ€ μ•Œ 수 μ—†λŠ” λͺ¨λ“  κ²½λ‘œμ—μ„œ μ§„μž… λ¬Έμ„œλ₯Ό λŒλ €μ€˜μ•Ό ν•˜κ³ , μ‹€μ œ νŒŒμΌμ€ 계속 μ„œλΉ„μŠ€λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€. ```caddyfile http://:8080 { root * /srv/site try_files {path} /index.html file_server } ``` μΈ‘μ •: `/assets/big.txt`λŠ” 자기 λ‚΄μš©μœΌλ‘œ μ—¬μ „νžˆ `200`, `/some/spa/route`λŠ” `index.html`둜 `200`을 λ‹΅ν•©λ‹ˆλ‹€. `try_files` 쀄이 μ—†μœΌλ©΄ 두 λ²ˆμ§ΈλŠ” `404`μž…λ‹ˆλ‹€. ## πŸ—‚οΈ 디렉터리 λͺ©λ‘ `file_server browse`λŠ” index 파일이 μ—†λŠ” λ””λ ‰ν„°λ¦¬μ˜ λͺ©λ‘μ„ κ·Έλ¦½λ‹ˆλ‹€. ```caddyfile http://:8080 { root * /srv/site file_server browse } ``` λͺ©λ‘μ€ ν•­λͺ© 이름을 λ‚˜μ—΄ν•˜λ―€λ‘œ `/assets/`λŠ” `Index of` 제λͺ© μ•„λž˜ `big.txt`λ₯Ό 보여 μ€λ‹ˆλ‹€. κ·Έλ ‡κ²Œ 읽히게 ν•˜λ €λŠ” 디렉터리가 μ•„λ‹ˆλΌλ©΄ `browse`λŠ” 뢙이지 μ•ŠμŠ΅λ‹ˆλ‹€. ## πŸ”’ 파일 숨기기 ⚠️ 점으둜 μ‹œμž‘ν•˜λŠ” νŒŒμΌλ„ λ‹€λ₯Έ 파일과 λ˜‘κ°™μ΄ μ„œλΉ„μŠ€λ©λ‹ˆλ‹€. μœ„ κ΅¬μ„±μ—μ„œ `.hidden`은 `200`을 λ‹΅ν–ˆμŠ΅λ‹ˆλ‹€. `.git`, `.env`, νŽΈμ§‘κΈ° 백업이 인터넷에 λ‚˜κ°€λŠ” κ²½λ‘œκ°€ μ΄κ²ƒμž…λ‹ˆλ‹€. λ§‰μœΌλ €λ©΄ 파일 μ„œλ²„κ°€ λ™μž‘ν•˜κΈ° 전에 μ‘λ‹΅ν•©λ‹ˆλ‹€. ```caddyfile http://:8080 { root * /srv/site @hidden path /.* respond @hidden "Not found" 404 file_server } ``` μΈ‘μ •: `/.hidden`은 `404`, `/`와 `/assets/big.txt`λŠ” μ—¬μ „νžˆ `200`. `403`이 μ•„λ‹ˆλΌ `404`인 것은 μ˜λ„μ μž…λ‹ˆλ‹€. `403`은 파일이 μžˆλ‹€λŠ” 사싀을 확인해 μ€λ‹ˆλ‹€. ## ⚠️ 잘 λ˜μ§€ μ•Šμ„ λ•Œ - **`Unsupported feature: 'encode br'`.** BrotliλŠ” 이름을 λŒ€λ©° κ±°λΆ€λ©λ‹ˆλ‹€. `encode zstd gzip`을 μ“°μ‹­μ‹œμ˜€. - **`Unknown directive 'file_server: …'`.** κ·Έ μ˜΅μ…˜μ€ μ—†κ³ , `validate`λŠ” λ¬΄μ‹œν•˜μ§€ μ•Šκ³  κ±°λΆ€ν•œ 철자λ₯Ό μ•Œλ € μ€λ‹ˆλ‹€. - **νŽ˜μ΄μ§€ λŒ€μ‹  디렉터리 λͺ©λ‘.** κ·Έ 디렉터리에 `index.html`이 μ—†μŠ΅λ‹ˆλ‹€. μ˜λ„ν•œ κ²°κ³Όμ΄κ±°λ‚˜ νŒŒμΌμ„ 빠뜨린 κ²ƒμž…λ‹ˆλ‹€. - **μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ²˜λ¦¬ν•˜λŠ” κ²½λ‘œμ—μ„œ `404`.** 단일 νŽ˜μ΄μ§€ 폴백이 μ—†μŠ΅λ‹ˆλ‹€: `try_files {path} /index.html`. - **재적용 후에도 μƒˆ νŽ˜μ΄μ§€κ°€ μ•ˆ λ³΄μž„.** 재적용이 μ μš©ν•˜λŠ” 것은 정책이지 μƒˆ λ¦¬μŠ€λ„ˆκ°€ μ•„λ‹™λ‹ˆλ‹€. νŒŒμΌμ€ μš”μ²­λ§ˆλ‹€ μ½νžˆλ―€λ‘œ 파일 μΆ”κ°€λŠ” μ¦‰μ‹œ 반영되고 λ¦¬μŠ€λ„ˆ 이동은 κ·Έλ ‡μ§€ μ•ŠμŠ΅λ‹ˆλ‹€([μ„œλΉ„μŠ€λ‘œ μ‹€ν–‰](/ko/start/service/#-재적용의-의미)). ## 🧭 λ‹€μŒ 단계 - [μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν”„λ‘μ‹œν•˜κΈ°](/ko/guides/reverse-proxy/): μ„œλ²„μ˜ λ‚˜λ¨Έμ§€ 절반. - [`file_server`](/ko/reference/directives/#file_server): μ§€μ‹œμ–΄ 레퍼런슀. - [`try_files`](/ko/reference/pingclairfile/): 폴백이 μ–΄λ–»κ²Œ μ»΄νŒŒμΌλ˜λŠ”μ§€.