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 |
---|