티스토리 뷰
반응형
Laravel/ PHP 사이트 기준 예시를 중심으로 하지만, 다른 스택에도 같은 흐름으로 적용하면 됩니다.
아래는 전체 흐름(요약) → 서버 준비 → GitHub(Secrets) 준비 → 실제 GitHub Actions 워크플로우(예제) → 보안/운영 팁 → 문제 해결 체크리스트 순서입니다.
1) 전체 흐름 요약
- 서버에 deploy 전용 사용자와 SSH 공개키 설정
- 로컬(또는 CI용)에서 SSH 개인키를 GitHub Actions Secrets에 등록
- .github/workflows/deploy.yml 파일을 만들어 main 브랜치에 푸시되면 실행되도록 설정
- Actions가 SSH로 서버에 접속 → 코드 동기화(rsync 또는 scp) → 원격에서 의존성 설치/마이그레이션/캐시/서비스 재시작 수행
2) 서버(우분투 계정) 준비 (권장)
아래 명령은 루트 권한으로 실행합니다(또는 sudo 앞에 붙이세요).
# 1) deploy 전용 사용자 생성 (비밀번호 로그인 비활성 권장) sudo adduser --disabled-password --gecos "" deploy # 2) 필요한 패키지 설치 sudo apt update sudo apt install -y openssh-server rsync git unzip # 3) 앱 디렉터리 만들기 및 소유권 설정 (예: /var/www/myapp) sudo mkdir -p /var/www/myapp sudo chown -R deploy:deploy /var/www/myapp
SSH 접속 보안
- 서버에 공개키를 추가할 때 deploy 사용자의 ~/.ssh/authorized_keys에 public key를 넣습니다.
- /etc/ssh/sshd_config 에서 PasswordAuthentication no 로 변경(단, 키로 로그인 가능한지 확인 후 재시작).
- 포트(22) 변경, 방화벽 설정(UFW 또는 cloud security group) 권장.
(선택) deploy에게 서비스 재시작 권한만 부여
sudoers로 제한된 명령만 허용하면 안전합니다:
# 예: /etc/sudoers.d/deploy deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart nginx, /bin/systemctl reload nginx, /bin/systemctl restart php*-fpm
3) SSH 키 생성 및 GitHub Secrets 등록
SSH 키 생성 (로컬 또는 CI 환경에서)
# 로컬에서 (파일명은 예시) ssh-keygen -t ed25519 -C "github-actions@yourproject" -f ./gh_deploy_key # 생성하면 gh_deploy_key (private) / gh_deploy_key.pub (public) 생성
- gh_deploy_key.pub의 내용을 서버 deploy 계정의 ~/.ssh/authorized_keys 에 추가.
-
# 서버에서 (deploy 계정으로) mkdir -p ~/.ssh && chmod 700 ~/.ssh echo "<PUBLIC_KEY_CONTENT>" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys chown -R deploy:deploy ~/.ssh
- gh_deploy_key(비밀키) 파일 내용을 GitHub 리포지토리 → Settings > Secrets and variables > Actions 에 새 Secret으로 등록
- 이름 예시: SSH_PRIVATE_KEY
- 추가로 아래도 Secrets로 등록:
- SERVER_HOST (예: 1.2.3.4 또는 example.com)
- SERVER_USER (예: deploy)
- SERVER_PORT (옵션, 기본 22)
- TARGET_DIR (예: /var/www/myapp)
- (필요 시) BRANCH (예: main)
4) GitHub Actions 워크플로우 예제
아래 파일을 ./github/workflows/deploy.yml 로 저장하세요. (Laravel 예시 — 필요 시 명령을 본인 스택에 맞게 수정)
name: CI/CD Deploy to Server on: push: branches: - main # main 브랜치로 merge/push 될 때 배포 jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v4 - name: Install rsync (ensure available) run: sudo apt-get update && sudo apt-get install -y rsync # SSH 키를 에이전트에 올리기 - name: Start ssh-agent and add key uses: webfactory/ssh-agent@v0.5.4 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - name: Add server to known_hosts run: | mkdir -p ~/.ssh ssh-keyscan -p ${{ secrets.SERVER_PORT || 22 }} ${{ secrets.SERVER_HOST }} >> ~/.ssh/known_hosts # (옵션) 빌드/테스트 단계 수행 (ex. npm build, phpunit 등) - name: Build (optional) run: | # 예: npm install && npm run build echo "빌드가 필요하면 여기에 추가하세요" # 파일 동기화 (rsync) - name: Sync files to server run: | rsync -avz --delete \ --exclude='.git' \ --exclude='node_modules' \ --exclude='vendor' \ --exclude='storage' \ ./ ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }}:${{ secrets.TARGET_DIR }} # 원격에서 의존성 설치, 마이그레이션, 캐시 등 실행 - name: Run remote deployment commands run: | ssh -p ${{ secrets.SERVER_PORT || 22 }} ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_HOST }} << 'EOF' set -e cd ${{ secrets.TARGET_DIR }} # 권한 설정 (옵션) chown -R deploy:www-data . # composer 설치(앱이 PHP/Laravel일 경우) if [ -f composer.json ]; then composer install --no-dev --optimize-autoloader --no-interaction fi # Laravel specific (필요하면) if [ -f artisan ]; then php artisan migrate --force php artisan config:cache php artisan route:cache php artisan view:cache fi # 서비스 재시작 (sudoers에서 허용된 명령만) sudo systemctl reload nginx || true sudo systemctl restart php8.1-fpm || true EOF
주의:
- rsync 명령의 --exclude 를 환경에 맞게 조정하세요. vendor를 제외했으므로 서버에서 composer install을 돌리도록 했습니다(더 안전).
- sudo 명령 사용 시 deploy 사용자에게 관련 시스템 서비스 재시작 명령을 NOPASSWD로 허용해야 합니다(앞서 설명).
- webfactory/ssh-agent는 private key를 ssh-agent에 등록해 SSH 연결을 가능하게 합니다.
5) 대체 방법 (짧게)
- Bare repository + post-receive hook (서버에서 Git으로 직접 pull 트리거): GitHub에서 webhook을 서버로 보내면 서버 hook에서 git --work-tree=/var/www/myapp --git-dir=/home/git/repo.git checkout -f 등으로 배포. (작업은 서버 측에서 모든 처리)
- Self-hosted runner: 서버에 GitHub Actions runner를 설치하면 액션을 서버에서 직접 실행(보안/네트워크 요구사항 고려). 장점: 네트워크 제한 내부망 배포에 유리.
- Container / Docker 방식: Actions에서 이미지를 빌드하고 레지스트리에 push → 서버에서 docker pull & restart로 배포(Blue/Green 또는 컨테이너 오케스트레이션 필요 시).
6) 보안 권장사항
- 배포용 SSH 키는 오직 배포용 계정에만 사용 (개인 계정 키와 분리).
- GitHub Secrets는 repo 권한이 있는 사람만 접근 가능. 정기적으로 키 회전.
- deploy 사용자는 가능한 최소 권한만 부여(특정 systemctl 명령만 허용).
- 서버에서 패스워드 인증 비활성화(키 기반만 허용).
- 방화벽(포트 제한), Fail2ban 등 적용.
7) 트러블슈팅 체크리스트
- Permission denied (publickey) → GitHub secret의 private key가 올바른지, 서버에 public key가 붙어있는지 확인.
- Host key verification failed → ssh-keyscan으로 known_hosts 추가 or 수동으로 등록.
- 파일 소유권 문제 → chown -R www-data:www-data 등으로 권한 조정.
- composer 가 없거나 메모리 부족 → 서버에 composer 설치 / swap 추가.
- rsync 동기화 실패 → 경로 권한, 포트 확인, 방화벽 확인.
반응형
'laravel' 카테고리의 다른 글
| 추천 알리고리즘 (0) | 2025.10.13 |
|---|---|
| Laravel Accessor 호출 방식 (0) | 2025.10.10 |
| Git 연결 세팅 (0) | 2025.10.10 |
| laravel 프로젝트 생성시 Base table or view not found (0) | 2025.10.08 |
| Storage 심볼릭 링크 설정 (0) | 2025.10.08 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- laravel
- 의정부 삼계탕
- 더서니
- 깃계정변경
- css
- ci/cd
- 라라벨프로젝트
- citykid
- 엔진엑스설정
- 신규생성
- 프로젝트생성
- 라라벨
- thesunny
- 깃생성
- nginx설정
- 라라벨설정
- 스크립트강좌
- github
- 홈마
- 홈마뜻
- 서니
- 깃연동
- 캐시테이블
- 깃허브자동배포
- php신규생성
- 메서드호출
- 깃자동배포
- 민락골
- Accessor
- 스크립트기초
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
글 보관함
반응형