3단계: Laravel 프로젝트 배포
| ← 이전: 서버 환경 설정 | 메인으로 | 다음: 도메인/HTTPS 설정 → |
이제 드디어 Laravel 프로젝트를 서버에 배포할 차례예요! GitHub에서 코드를 가져와서 실제로 동작하도록 만들어봅시다.
이 단계에서 배울 내용
- GitHub 저장소 준비 및 접근 설정
- 서버로 프로젝트 클론하기
- Composer로 의존성 설치
- .env 파일 설정하기
- 데이터베이스 마이그레이션 실행
- Laravel 캐시 최적화
- 파일 권한 설정
- 프론트엔드 에셋 빌드
💡 예상 소요 시간: 30-40분 정도 걸려요.
3.1 GitHub 저장소 준비하기
GitHub에 프로젝트가 있나요?
아직 GitHub에 프로젝트를 올리지 않으셨다면, 먼저 올려주세요. 로컬에서 다음 명령어를 실행하세요:
# 로컬 프로젝트 디렉토리에서
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/jinyerp_demo_01.git
git push -u origin main
저장소 타입 확인
저장소가 공개(Public)인가요, 비공개(Private)인가요?
공개 저장소인 경우
- 추가 설정 불필요
- HTTPS로 바로 클론 가능
비공개 저장소인 경우
- Personal Access Token 또는 SSH 키 필요
- 아래 방법 중 하나 선택
3.2 서버에서 GitHub 접근 설정하기
방법 1: SSH 키 사용 (권장)
SSH 키를 사용하면 매번 비밀번호를 입력할 필요가 없어요.
1단계: SSH 키 생성
서버에서 다음 명령어 실행:
# SSH 키 생성
ssh-keygen -t rsa -b 4096 -C "deploy@example.com"
# Enter 키를 3번 누르세요 (기본 경로, 비밀번호 없음)
2단계: 공개 키 복사
# 공개 키 내용 출력
cat ~/.ssh/id_rsa.pub
출력된 내용을 전부 복사하세요 (ssh-rsa로 시작하는 긴 문자열)
3단계: GitHub에 SSH 키 등록
- GitHub 웹사이트 접속
- Settings → SSH and GPG keys 메뉴
- New SSH key 클릭
- Title: “Laravel Server” (알아보기 쉬운 이름)
- Key: 복사한 공개 키 붙여넣기
- Add SSH key 클릭
4단계: SSH 연결 테스트
# GitHub SSH 연결 테스트
ssh -T git@github.com
# 출력:
# Hi username! You've successfully authenticated...
방법 2: Personal Access Token (간단한 방법)
1단계: Token 생성
- GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
- Generate new token (classic) 클릭
- Note: “Laravel Deploy Server”
- Expiration: 90 days (또는 원하는 기간)
- Select scopes:
repo체크 - Generate token 클릭
- 생성된 토큰 복사 (다시 볼 수 없어요!)
2단계: Token 저장
# 토큰을 안전한 곳에 저장
echo "ghp_xxxxxxxxxxxxxxxxxxxx" > ~/.github_token
chmod 600 ~/.github_token
3.3 프로젝트 클론하기
웹 루트 디렉토리로 이동
# 웹 루트 디렉토리로 이동
cd /var/www
# 현재 디렉토리 확인
ls -la
GitHub에서 프로젝트 클론
SSH 방식 (권장)
# SSH로 클론 (비공개/공개 저장소 모두 가능)
sudo git clone git@github.com:your-username/jinyerp_demo_01.git
HTTPS 방식 (공개 저장소)
# HTTPS로 클론 (공개 저장소)
sudo git clone https://github.com/your-username/jinyerp_demo_01.git
HTTPS + Token 방식 (비공개 저장소)
# HTTPS + Token으로 클론 (비공개 저장소)
sudo git clone https://ghp_your_token@github.com/your-username/jinyerp_demo_01.git
💡 팁:
your-username과jinyerp_demo_01을 실제 저장소 정보로 바꿔주세요!
클론 완료 확인
# 클론된 디렉토리 확인
ls -la /var/www/
# 프로젝트 구조 확인
ls -la /var/www/jinyerp_demo_01
Laravel 프로젝트 파일들(app, config, routes 등)이 보이면 성공! 🎉
3.4 파일 소유권 및 권한 설정
웹서버 사용자로 소유권 변경
Nginx는 www-data 사용자로 실행되므로 소유권을 변경해야 해요:
# 전체 프로젝트 소유권을 www-data로 변경
sudo chown -R www-data:www-data /var/www/jinyerp_demo_01
기본 권한 설정
# 기본 파일 권한 설정
sudo chmod -R 755 /var/www/jinyerp_demo_01
Laravel 특수 디렉토리 권한
Laravel의 storage와 bootstrap/cache 디렉토리는 쓰기 권한이 필요해요:
# storage 디렉토리 쓰기 권한
sudo chmod -R 775 /var/www/jinyerp_demo_01/storage
# bootstrap/cache 디렉토리 쓰기 권한
sudo chmod -R 775 /var/www/jinyerp_demo_01/bootstrap/cache
3.5 Composer 의존성 설치
composer.json 파일 확인
# 프로젝트 디렉토리로 이동
cd /var/www/jinyerp_demo_01
# composer.json 파일 확인
cat composer.json
의존성 설치
# www-data 사용자로 Composer 의존성 설치
sudo -u www-data composer install --optimize-autoloader --no-dev
💡 옵션 설명:
--optimize-autoloader: 성능 최적화--no-dev: 개발용 패키지 제외 (프로덕션 환경)
1GB RAM 서버에서 메모리 부족 시
메모리가 부족하다는 에러가 나오면:
# 스크립트 실행 없이 설치
sudo -u www-data composer install --optimize-autoloader --no-dev --no-scripts
# 스크립트 따로 실행
sudo -u www-data composer run-script post-autoload-dump
설치 확인
# Composer 의존성 확인
sudo -u www-data composer check-platform-reqs
# vendor 디렉토리 확인
ls -la vendor/
# Laravel 명령어 테스트
sudo -u www-data php artisan --version
Laravel 버전이 출력되면 성공! 🎉
3.6 환경 설정 파일 구성
.env 파일 생성
# .env.example에서 .env 생성
sudo -u www-data cp .env.example .env
.env 파일 편집
# .env 파일 편집
sudo nano .env
다음 내용을 찾아서 수정해주세요:
# 애플리케이션 기본 설정
APP_NAME="Jiny ERP Demo"
APP_ENV=production
APP_DEBUG=false
APP_KEY=
APP_TIMEZONE=Asia/Seoul
APP_URL=http://your-server-ip
# 데이터베이스 설정
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=jinyerp_demo
DB_USERNAME=jinyerp
DB_PASSWORD=your_mysql_password_here
# 캐시 설정
CACHE_STORE=redis
SESSION_DRIVER=redis
SESSION_LIFETIME=120
QUEUE_CONNECTION=redis
# Redis 설정
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=your_redis_password_here
REDIS_PORT=6379
REDIS_DB=0
# 로그 설정
LOG_CHANNEL=stack
LOG_LEVEL=error
# 파일 시스템
FILESYSTEM_DISK=local
# 브로드캐스트
BROADCAST_DRIVER=log
🔒 중요:
DB_PASSWORD: MySQL 사용자 비밀번호 (2단계에서 설정한 것)REDIS_PASSWORD: Redis 비밀번호 (2단계에서 설정한 것)APP_URL: 현재는 IP 주소, 4단계에서 도메인으로 변경
저장하고 종료: Ctrl + X, Y, Enter
.env 파일 보안 설정
# .env 파일 권한 제한 (중요!)
sudo chmod 600 /var/www/jinyerp_demo_01/.env
sudo chown www-data:www-data /var/www/jinyerp_demo_01/.env
🔒 보안: .env 파일에는 중요한 정보가 들어있어서 읽기 권한을 제한해야 해요.
주요 Laravel 설정 파일 경로
나중에 필요할 때를 위해:
- 환경 설정:
/var/www/jinyerp_demo_01/.env - 설정 디렉토리:
/var/www/jinyerp_demo_01/config/ - 라우트 파일:
/var/www/jinyerp_demo_01/routes/web.php - 로그 디렉토리:
/var/www/jinyerp_demo_01/storage/logs/
3.7 Laravel 애플리케이션 초기화
애플리케이션 키 생성
Laravel의 암호화에 사용되는 고유한 키를 생성해요:
# 애플리케이션 키 생성
sudo -u www-data php artisan key:generate
# 출력:
# Application key set successfully.
생성된 키 확인
# .env 파일에서 APP_KEY 확인
grep APP_KEY /var/www/jinyerp_demo_01/.env
# 출력 예시:
# APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxx
3.8 데이터베이스 마이그레이션
데이터베이스 연결 테스트
# 마이그레이션 상태 확인 (연결 테스트)
sudo -u www-data php artisan migrate:status
에러 없이 마이그레이션 목록이 나오면 데이터베이스 연결 성공!
마이그레이션 실행
# 프로덕션 환경에서 마이그레이션 실행
sudo -u www-data php artisan migrate --force
💡
--force옵션: 프로덕션 환경에서는 확인 메시지 없이 실행하기 위해 필요해요.
시드 데이터 실행 (선택사항)
초기 데이터가 있다면:
# 모든 시더 실행
sudo -u www-data php artisan db:seed --force
# 또는 특정 시더만 실행
sudo -u www-data php artisan db:seed --class=UserSeeder --force
마이그레이션 확인
# 다시 상태 확인
sudo -u www-data php artisan migrate:status
# 데이터베이스 테이블 확인
mysql -u jinyerp -p jinyerp_demo -e "SHOW TABLES;"
3.9 Laravel 저장소 및 캐시 설정
Storage 심볼릭 링크 생성
업로드된 파일이 public에서 접근 가능하도록:
# storage를 public으로 링크
sudo -u www-data php artisan storage:link
# 출력:
# The [public/storage] link has been connected to [storage/app/public].
캐시 생성 (성능 향상)
Laravel의 설정 파일들을 캐싱하면 성능이 크게 향상돼요:
# 설정 캐시 생성
sudo -u www-data php artisan config:cache
# 라우트 캐시 생성
sudo -u www-data php artisan route:cache
# 뷰 캐시 생성
sudo -u www-data php artisan view:cache
# 이벤트 캐시 생성
sudo -u www-data php artisan event:cache
💡 언제 캐시를 재생성하나요? 설정 파일, 라우트, 뷰를 수정한 후에는 해당 캐시를 다시 생성해야 해요.
캐시 확인
# 캐시 파일 확인
ls -la bootstrap/cache/
config.php, routes-v7.php 등의 파일이 보이면 성공!
3.10 파일 권한 최종 설정
전체 소유권 재설정
# Laravel 전체 디렉토리 소유권
sudo chown -R www-data:www-data /var/www/jinyerp_demo_01
일반 파일 및 디렉토리 권한
# 일반 파일 권한 (644)
sudo find /var/www/jinyerp_demo_01 -type f -exec chmod 644 {} \;
# 디렉토리 권한 (755)
sudo find /var/www/jinyerp_demo_01 -type d -exec chmod 755 {} \;
쓰기 권한 필요한 디렉토리
# storage 디렉토리 (로그, 세션, 캐시)
sudo chmod -R 775 /var/www/jinyerp_demo_01/storage
# bootstrap/cache 디렉토리
sudo chmod -R 775 /var/www/jinyerp_demo_01/bootstrap/cache
artisan 실행 권한
# artisan 명령어 실행 권한
sudo chmod 755 /var/www/jinyerp_demo_01/artisan
권한 설정 확인
# 주요 디렉토리 권한 확인
ls -la /var/www/jinyerp_demo_01/ | grep -E "storage|bootstrap"
3.11 프론트엔드 빌드 (선택사항)
Laravel 프로젝트에 프론트엔드 에셋이 있다면 빌드해야 해요.
package.json 확인
# package.json 파일 확인
cat /var/www/jinyerp_demo_01/package.json
package.json이 없다면 이 단계를 건너뛰세요.
Node.js 의존성 설치
# 프로젝트 디렉토리로 이동
cd /var/www/jinyerp_demo_01
# Node.js 의존성 설치 (1GB RAM 환경)
sudo -u www-data env NODE_OPTIONS="--max-old-space-size=512" npm ci
💡
npm ci가 뭔가요?npm install보다 빠르고 클린한 설치 방법이에요. CI/CD 환경에 최적화되어 있습니다.
프론트엔드 빌드
# 프로덕션 빌드
sudo -u www-data npm run build
빌드가 완료될 때까지 기다려주세요 (3-5분 소요)
빌드 결과 확인
# 빌드된 파일 확인
ls -la public/build/
manifest.json과 assets 디렉토리가 있으면 성공!
3.12 Laravel 설정 검증
애플리케이션 상태 확인
# Laravel 버전 확인
sudo -u www-data php artisan --version
# 환경 정보 확인
sudo -u www-data php artisan env
# 라우트 목록 확인
sudo -u www-data php artisan route:list
데이터베이스 연결 테스트
# 마이그레이션 상태 재확인
sudo -u www-data php artisan migrate:status
# Tinker로 데이터베이스 테스트
sudo -u www-data php artisan tinker
Tinker가 실행되면:
// 데이터베이스 연결 테스트
DB::connection()->getPdo();
// 테이블 확인
DB::select('SHOW TABLES');
// 종료
exit
로그 확인
# Laravel 로그 디렉토리 확인
ls -la /var/www/jinyerp_demo_01/storage/logs/
# 현재 로그 확인 (실시간)
sudo tail -f /var/www/jinyerp_demo_01/storage/logs/laravel.log
Ctrl + C로 종료
✅ 3단계 완료 체크리스트
모든 단계를 완료하셨나요? 체크리스트로 확인해봅시다!
- GitHub 저장소 접근 설정 (SSH 키 또는 Token)
- 프로젝트 정상 클론
- 파일 소유권 www-data로 변경
- Composer 의존성 설치 완료
- .env 파일 생성 및 설정
- .env 파일 보안 권한 설정
- 애플리케이션 키 생성
- 데이터베이스 마이그레이션 완료
- Storage 심볼릭 링크 생성
- Laravel 캐시 설정 (config, route, view)
- 파일 권한 최종 설정
- 프론트엔드 빌드 (선택사항)
- 애플리케이션 상태 검증
최종 확인 명령어
# 모든 설정 한 번에 확인
echo "=== Laravel Version ===" && sudo -u www-data php artisan --version
echo "=== Database ===" && sudo -u www-data php artisan migrate:status
echo "=== Storage Link ===" && ls -la public/ | grep storage
echo "=== Permissions ===" && ls -la storage/ | head -3
echo "=== Cache ===" && ls -la bootstrap/cache/ | grep -E "config|routes"
문제 해결
문제 1: Composer install 실패 (메모리 부족)
Allowed memory size exhausted
해결 방법:
# 스왑 파일 생성 (아직 안 만들었다면)
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# 다시 설치
sudo -u www-data composer install --no-scripts
sudo -u www-data composer run-script post-autoload-dump
문제 2: 데이터베이스 연결 실패
SQLSTATE[HY000] [1045] Access denied
해결 방법:
# .env 파일 확인
cat .env | grep -E "DB_"
# MySQL 사용자 권한 재확인
mysql -u root -p -e "SHOW GRANTS FOR 'jinyerp'@'localhost';"
# 비밀번호가 틀렸다면 재설정
mysql -u root -p -e "ALTER USER 'jinyerp'@'localhost' IDENTIFIED BY 'new_password';"
문제 3: 권한 문제
failed to open stream: Permission denied
해결 방법:
# 소유권 재설정
sudo chown -R www-data:www-data /var/www/jinyerp_demo_01
# storage 권한 재설정
sudo chmod -R 775 /var/www/jinyerp_demo_01/storage
sudo chmod -R 775 /var/www/jinyerp_demo_01/bootstrap/cache
문제 4: 캐시 문제
Configuration cache file does not exist
해결 방법:
# 모든 캐시 삭제
sudo -u www-data php artisan cache:clear
sudo -u www-data php artisan config:clear
sudo -u www-data php artisan route:clear
sudo -u www-data php artisan view:clear
# 캐시 재생성
sudo -u www-data php artisan config:cache
sudo -u www-data php artisan route:cache
sudo -u www-data php artisan view:cache
문제 5: Storage 링크 에러
symlink(): File exists
해결 방법:
# 기존 링크 삭제
sudo rm /var/www/jinyerp_demo_01/public/storage
# 링크 재생성
sudo -u www-data php artisan storage:link
다음 단계
축하합니다! 3단계를 완료하셨어요! 🎉
Laravel 애플리케이션이 서버에 배포되었어요. 이제 도메인을 연결하고 HTTPS를 설정할 차례입니다!
| ← 이전: 서버 환경 설정 | 메인으로 | 다음: 도메인/HTTPS 설정 → |