[Ubuntu] 서버에서 Laravel 파일 권한 설정 완벽 가이드

2025. 4. 21. 21:06·실무 | 성장/프로젝트 사례

1. 개요

Linux 파일 시스템은 각 파일 및 디렉토리에 소유자(owner), 그룹(group), 그리고 권한(permission) 비트가 할당되어 있습니다. 잘못된 권한 설정은 ‘Permission denied’ 오류, 로그 기록 실패, 웹서버 정상 작동 중단 등을 초래할 수 있습니다. Laravel의 경우 특히 storage 및 bootstrap/cache 디렉토리에 웹서버가 쓰기 가능해야 하며, 그렇지 않으면 애플리케이션이 실행되지 않습니다


2. 사용자 및 그룹 계층

서버에는 대개 다음과 같은 계정이 사용됩니다.

  • root: 시스템 전체 권한을 가진 관리자 계정입니다. 배포 스크립트나 초기 설정 시에만 사용하고, 애플리케이션 실행에는 절대 사용을 금합니다.
  • 프로젝트 사용자: 개발자가 SSH로 접속하여 코드를 배포·관리하는 계정이며, 가령 ubuntu 또는 deployer 등이 일반적입니다.
  • 웹서버 사용자: Nginx/Apache가 동작하는 계정으로, 우분투에서는 주로 www-data를 사용합니다. 이 계정이 storage, bootstrap/cache 디렉토리를 쓰기 위해 소유자 또는 그룹에 포함되어야 합니다.
  • 데이터 사용자: 로그·백업·미디어 파일 전용으로 별도 그룹을 설정할 수도 있으며, 이 경우 setfacl을 통해 세분화된 권한 제어가 가능합니다.

운영 계정들이 혼재할 때 편리함과 보안을 모두 고려하여, 프로젝트 사용자와 웹서버 사용자를 같은 그룹에 추가하거나 ACL(Access Control List)을 적용하는 방식을 선택할 수 있습니다.


3. 디렉토리별 권한 설정

3-1. 프로젝트 루트 권한

Laravel 프로젝트 루트(예: /var/www/myapp)는 읽기 권한만 웹서버에 허용하고, 쓰기는 금지해야 보안이 강화됩니다. 디렉토리 권한은 보통 755, 파일 권한은 644로 설정합니다.

sudo chown -R $USER:www-data /var/www/myapp  
sudo find /var/www/myapp -type d -exec chmod 755 {} \;  
sudo find /var/www/myapp -type f -exec chmod 644 {} \;

이렇게 하면 프로젝트 사용자가 쓰기 권한을 유지하면서, 웹서버는 필요한 읽기 권한만 가지게 됩니다.

3-2. app, config, public, vendor 디렉토리

이들 디렉토리는 실행 시 애플리케이션 코드를 읽기만 하면 되고, 동적으로 파일을 생성·수정하지 않으므로 755(디렉토리)·644(파일)이 적합합니다. 특히 public 디렉토리는 웹 루트로 설정되므로, 외부로 노출되지 않도록 소스 코드가 저장된 상위 디렉토리는 웹서버 문서 루트로 직접 연결하지 않습니다.

3-3. storage 및 bootstrap/cache 디렉토리

이 두 디렉토리는 Laravel이 캐시·세션·로그 등을 기록하기 위해 반드시 웹서버에 쓰기 권한을 부여해야 합니다. 안전한 설정 방법은 다음과 같습니다.

sudo chgrp -R www-data /var/www/myapp/storage /var/www/myapp/bootstrap/cache  
sudo chmod -R ug+rwx /var/www/myapp/storage /var/www/myapp/bootstrap/cache

위 명령으로 웹서버 사용자가 속한 그룹에 읽기·쓰기·실행 권한을 부여하여, Laravel이 정상적으로 파일을 생성·수정할 수 있게 됩니다.

추가로, 새로운 파일이 생성될 때도 동일한 그룹 권한을 상속하도록 setgid 비트를 설정할 수 있습니다:

sudo find /var/www/myapp/storage /var/www/myapp/bootstrap/cache -type d -exec chmod g+s {} \;

이렇게 하면 디렉토리에 생성되는 모든 파일이 www-data 그룹 권한을 자동으로 물려받습니다.

3-4. 로그(storage/logs) 디렉토리

로그 파일은 storage/logs 아래에 저장되므로, 위와 동일한 그룹 설정으로 커버됩니다. 간혹 특정 로그 파일만 권한 오류가 발생한다면, 해당 파일을 명시적으로 소유자 변경 및 권한 부여를 수행합니다.

sudo chown www-data:www-data /var/www/myapp/storage/logs/laravel.log  
sudo chmod 664 /var/www/myapp/storage/logs/laravel.log

파일 권한 664를 주면 소유자·그룹에 쓰기 권한, 기타에 읽기 권한만 허용되어 충분한 보안성을 유지합니다.


4. 예제: Ubuntu 서버 배포 스크립트

다음 예제는 /var/www/myapp 경로에 Laravel 프로젝트를 배포할 때 사용 가능한 Bash 스크립트입니다.

#!/bin/bash
APP_PATH=/var/www/myapp
WEB_USER=www-data
DEPLOY_USER=$(whoami)

# 1. 소유자 및 그룹 설정
sudo chown -R $DEPLOY_USER:$WEB_USER $APP_PATH

# 2. 파일/디렉토리 권한 설정
sudo find $APP_PATH -type f -exec chmod 644 {} \;
sudo find $APP_PATH -type d -exec chmod 755 {} \;

# 3. 캐시·로그 디렉토리 권한 강화
sudo chgrp -R $WEB_USER $APP_PATH/storage $APP_PATH/bootstrap/cache
sudo chmod -R ug+rwx $APP_PATH/storage $APP_PATH/bootstrap/cache
sudo find $APP_PATH/storage $APP_PATH/bootstrap/cache -type d -exec chmod g+s {} \;

# 4. 캐시 초기화
cd $APP_PATH
php artisan cache:clear
php artisan config:clear
php artisan view:clear
php artisan route:clear

echo "Deployment and permission setup completed."

이 스크립트를 사용하면 배포 후 권한 문제로 인한 장애 없이 즉시 애플리케이션을 실행할 수 있습니다.


5. 결론

Laravel 애플리케이션의 안정적인 운영을 위해, 권한 설정은 배포 프로세스의 핵심입니다. 루트 디렉토리는 제한된 읽기 권한만, 코드 디렉토리는 최소 권한(755/644)을 유지하며, storage·bootstrap/cache는 웹서버 그룹에 쓰기 권한을 부여하여 문제가 발생하지 않도록 해야 합니다. 필요 시 setfacl로 ACL을 적용하거나, 스크립트를 통해 일관된 배포 환경을 유지하는 방식을 적극 추천합니다.

'실무 | 성장 > 프로젝트 사례' 카테고리의 다른 글

[부하 테스트] 파견을 통한 부하테스트 진행 중 겪은 이슈  (0) 2025.02.08
'실무 | 성장/프로젝트 사례' 카테고리의 다른 글
  • [부하 테스트] 파견을 통한 부하테스트 진행 중 겪은 이슈
알쓸신개
알쓸신개
  • 알쓸신개
    알아두면 쓸모있는 신기한 개발지식
    알쓸신개
  • 전체
    오늘
    어제
    • 분류 전체보기 (55) N
      • 웹 기초 | 디자인 (2)
        • HTML (0)
        • CSS (0)
        • 반응형 (0)
        • 웹 지식 | 웹 표준 | 접근성 (2)
      • 프론트엔드 (6)
        • JavaScript (6)
        • DOM 조작 | AJAX (0)
        • TypeScript (0)
        • Vue.js | React | JSX (0)
        • Webpack | Vite | 웹 컴포넌트 (0)
      • 백엔드 (18)
        • PHP (4)
        • Laravel (9)
        • CodeIgniter (0)
        • JAVA (0)
        • Spring (0)
        • 디자인 패턴 (2)
        • 테스트 코드 작성 (1)
        • 보안 | 인증 (1)
      • 데이터베이스 (3)
        • SQL 기초 (1)
        • MariaDB | MySql (0)
        • 데이터베이스 설계 (0)
        • 쿼리 최적화(튜닝) (0)
      • 실무 | 성장 (7) N
        • 프로젝트 사례 (2)
        • 트러블슈팅 | 개발팁 (5) N
        • 커리어 관련 (0)
        • 코드 리뷰 | 스터디 (0)
        • 애자일 | 스크럼 | 작업 방법론 (0)
      • 개발 환경 | 도구 (16)
        • 버전관리 (Git) (1)
        • 개발 도구 (IDE, 에디터 등) (3)
        • 서버 | 인프라 | 배포 | 운영 (11)
        • Docker | 컨테이너 (0)
        • CI | CD (1)
        • 클라우드 환경 (AWS | GCP) (0)
      • 보안 (2)
        • 보안 | 인증 전반 (2)
        • CSRF | XSS 대응 (0)
        • SQL 인젝션 (0)
        • 암호화 | 해시 (0)
        • 보안 취약점 분석 (0)
      • AI & 머신러닝 (0)
        • AI 툴의 특성 (0)
  • 인기 글

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
알쓸신개
[Ubuntu] 서버에서 Laravel 파일 권한 설정 완벽 가이드
상단으로

티스토리툴바