엊그제에 밤2시까지 삽질해 성공한 기념으로 아주 간략하게 작성. 질문 받습니다.
여기서 말하는 "닷홈"이란 한국식 LAMP 스택의 shared hosting이라고 보시면 됨.
사전 준비사항
- 이 글은 모든 작업을 윈도우에서 한다고 가정한다. 리눅스/맥 쓰시는 분들은 훨씬 쉽게 할 수 있는 작업이니 필요한 명령줄은 알아서 연구하시길.
- 최소한의 php 상식
- php, composer (라라벨 인스톨러는 쓰지 않는다.)
- Git 관리툴 (FTP로 수동배포하는 과정에서 버전을 관리하기 위한 용도. 잘 모르면 소스트리 쓰자.)
- FTP 클라이언트 (닷홈에 수동배포하려는 용도. 잘 모르면 파일질라 쓰자.)
- PHP 5.6.4 이상이 돌아가는 닷홈 계정 (닷홈에서 PHP 7.0을 굴리려면 무제한 호스팅을 받아야 한다. 여기서 도메인 구매하는 댓가로 FREE 티어를 쓸수있게 해놓았으니 참고하시길... 제길 이런글 쓴다고 레퍼럴 받는것도 아닌데)
tl;dr
이하의 서술은 닷홈 호스팅의 두 가지 문제를 극복하는 과정을 안내한다. composer와 artisan을 못 쓰는 문제, 요청 실행 담당 파일이 마음대로 지목되지 않는 문제. 이 두 가지가 별문제가 아니라고 생각된다면 더 읽지 않아도 됨.
로컬에서는 php artisan make:migration create_foo_table 같은 콘솔도 쓸 수 있고 composer install foo 같은 것도 얼마든지 실행할 수 있지만 닷홈의 대부분 호스팅 상품은 공식적으로 SSH 접속이나 컴포저 실행, 쉘스크립트 실행 등을 할 수 없다. 요즘처럼 모든 것이 패키징 체계로 되어 있는 웹앱 개발 환경에서 이는 치명적인 제약이다.
게다가 로컬의 라라벨과 프로덕션인 닷홈은 웹 요청 수행 방식이 다르다. 라라벨은 루트폴더의 server.php를 실행하는데, 닷홈은 별도의 .htaccess 설정이 없는 한은 걍 아무 생각 없이 각 계정에 대하여 /host/home숫자/계정명/html 디렉토리의 index.htm(l)이나 index.php만을 열고 보기 때문이다. 어떤 요청에 대해서 .htaccess가 특정 파일을 포인팅해 주지 않으면, 그 요청의 응답은 영원히 403, 404, 500 또는 310(Too many redirects)뿐일 것이다.
여기에 사소한 몇 가지 요점을 짚고 가려고 한다. 예컨대 라라벨 버전 문제인데, PHP 7.1이 아닌 PHP 7.0의 서버라면 라라벨 버전은 5.5까지만 쓸 수 있다. 이제부터 조금씩 살펴보자.
1. 상쾌하게 새 앱으로 시작하기 (단, 버전에 맞춰서)
1-1. 라라벨을 올리고 싶은 닷홈 호스팅의 PHP 버전을 알아내고, 이 버전을 지원하는 최신 라라벨 버전이 뭔지 각 버전별 설치 문서에 가서 확인해 본다. 대리클릭을 해드리자면 PHP가 7.0일 땐 5.5까지, PHP가 5.6.4 이상일 땐 5.4까지.
1-2. 앱을 설치할 디렉토리로 가서 커맨드를 열고 라라벨 설치 명령을 실행한다. 예컨대 설치할 수 있는 라라벨 최고 버전이 5.5버전대라면 이렇게 입력한다. (자동으로 현시점 최신 버전인 5.5.28을 깔아준다.)
> composer create-project laravel/laravel 앱이름 "5.5.*" --prefer-dist
1-3. 컴포저 특유의 무반응이 잠시 이어지다가 한바탕 폭풍 설치가 끝나면 Git 관리툴을 열고 이 폴더를 기존 존재하는 저장소로서 생성해 커밋&푸시하고 버전 관리를 시작한다.
소스트리 기준으로 설명하자면: New Tab > Create > 지금 만든 폴더 선택 > 저장소 이름이나 나머지는 뭐 알아서 > 생성 > Yes > 작업공간 > 모두 스테이지에 올리기 > 커밋 > Push.
1-4. 설치된 디렉토리로 이동해 php artisan serve를 실행해본다. 별문제가 없어야 한다.
1-5. /public 폴더에 assets라는 이름으로 빈 폴더를 하나 만들고 거기에 css 폴더와 js 폴더를 때려넣어 둔다. 3번 스텝에서 해야 할 작업을 미리 해놓는 것.
2. 최초 버전 unzip 배치
이짓을 하는 이유는 /vendor 디렉토리에 너무 많은 폴더와 파일이 들어 있기 때문이다. 이걸 전부 FTP로 올리는 것은 바보짓이며, 번번이 이렇게 할 수도 없는 노릇이다. composer가 바로 이 문제를 해결한 툴이지만, 우리는 닷홈 서버를 빌려 쓰고 있어 컴포저를 쓸 수 없으니 일단 갓 구워진 라라벨 정도로만 올려보자. AWS 엘라스틱 빈스톡에서 영감을 얻음.
2-1. 라라벨이 설치된(=server.php 파일이 있는) 폴더의 내용 전체를 압축해 파일명.zip을 만들어둔다.
2-2. 다음 코드를 적당히 활용한 적당한이름.php 파일을 만들어둔다.
<? header("Content-Type: text/html; charset=UTF-8"); ?>
<a href="?unzip=true">Unzip 실행</a>
<?php
if ($_GET['unzip']) {
$zip = new ZipArchive;
if ($zip->open('파일명.zip') === TRUE) {
$zip->extractTo('./');
$zip->close();
echo '<br><br>배치 성공';
} else {
echo '<br><br>배치 실패';
}
} else {
phpinfo();
} ?>
대단히 스트레잇포워드한 코드인데 설명하자면 이렇다. 파일을 웹브라우저로 딱 보면 Unzip 실행이라 써진 링크 하나가 있고 그 밑에 이 서버의 php 정보가 줄줄이 달린다. 링크를 누르면 그 정보가 없어지고 배치가 성공했는지 실패했는지를 알려준다.
2-3. FTP 클라이언트로 닷홈 계정에 접속해 파일명.zip 압축파일과 적당한이름.php 파일을 같이 루트폴더에 올린다. (닷홈은 전형적으로 /html 폴더가 루트임)
2-4. http://닷홈계정주소/적당한이름.php 에 접속해본다. 설명한 대로 링크 하나와 php 설치정보가 떠야함.
2-5. 과감하게 Unzip 실행을 한다.
2-6. 배치 성공이라 떴는지, 그리고 실제로 FTP로 새로고침을 했을 때 로컬에 보이는 폴더와 파일들이 막 보이는지 확인한다.
2-7. 큰 산을 넘었다는 안도감을 가지도록 한다. (이후 필요할 경우 /vendor 폴더에 대해서만 이 꽁수를 써서 일괄 업로드할 수도 있을 것이다. extractTo() 함수는 덮어쓰기가 기본이므로 별문제 없을 것.)
3. public 폴더 바꿔치기
이 스텝은 왜 필요한가 하면 앞서 설명한 index.php를 루트에 띄워주기 위해 필요하다. 희한하게도 서양에서는 'public' 폴더가 닷홈 호스팅의 'html'에 해당한다고 한다. 요컨대 라라벨 앱 업로드 과정에서 그 public을 이 public으로 자연스럽게 덮어쓸 수 있으면 OK라는 것이다. 그래서 물정 모르는 서양 답변자들은 가끔 "퍼블릭폴더 위에 앱을 설치하면 그만인데 왜 우는소리를 해~" 같은 속터지는 소리를 한다. 하지만 닷홈은 그게 안 되니까 이짓을 하는 것. 결정적으로 도움이 된 것은 이 문서.
여기서는 라라벨을 닷홈 서버의 루트에 설치한다고 가정한다. 이 작업 자체는 닷홈 서버에서만 수행한다.
3-0. 잘 모르겠다면 다음 내용을 복사해 루트폴더에 .htaccess 파일로 저장하고 접속해 본다. 이것만 했는데 해결이 됐다면 (즉, 사이트가 뜬다면) 사실 이후의 3-x단계 및 4-x단계는 안 해도 된다. Thanks to 잘보고갑니다님
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
해결이 안 되면 다음 스텝으로 넘어간다.
3-1. 1-5를 아직 해놓지 않았다면 지금이라도 해놓고 닷홈서버에서도 동일하게 적용해 준다.
3-2. /public 폴더에 있는 '파일들'을 모두 복사해 그 위 폴더인 루트 폴더에 붙인다.
3-3. 라라벨 5.5 기준으로는 지금 붙여넣은 루트폴더의 index.php에 이런 라인들이 있을 것인데, 각각 알맞게 고친다.
require __DIR__.'/../vendor/autoload.php'; // 이렇게 생긴 라인은
require __DIR__.'/vendor/autoload.php'; // 이렇게 고칠것
$app = require_once __DIR__.'/../bootstrap/app.php'; // 이렇게 생긴 라인은
$app = require_once __DIR__.'/bootstrap/app.php'; // 이렇게 고칠것
한마디로, /public 폴더 기준으로 써져 있었던 로딩 파일들 주소를 루트폴더 기준으로 고친다.
3-4. 하나 더, 루트폴더에 있는 server.php를 고쳐준다.
# 고치기 전
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
return false;
}
require_once __DIR__.'/public/index.php';
# 고친 후
if ($uri !== '/' && file_exists(__DIR__.$uri)) {
return false;
}
require_once __DIR__.'/index.php';
3-5. http://닷홈계정주소/home 에 접속해 본다. 뷰 파일을 건드린 적이 없는데도 css와 js 파일이 로딩되지 않아 와장창 깨지고 있을 것이다. 이 부분을 4단계에서 해결한다.
4. 환경 구분해주기
이제 거의 모두 해결됐고, 3단계에서 해결되지 않은 퍼블릭 애셋 경로 문제만 남는다. php 소스들 자체는 로컬에서나 닷홈에서나 같아야 하는데, 로컬에서는 asset() 함수에 'assets/css/app.css' 경로를 넘겨줘야 되는 반면 닷홈에서는 'public/assets/css/app.css'를 넘겨줘야 된다. 어쩌면 좋냐고? htaccess 쓸줄 모른다고? 걱정마시라. 이런 건 env로 아주 간단하게 조치하면 된다.
4-1. 로컬의 루트에 있는 .env 파일을 편집기로 열고 다음 설정을 아무데나 추가한다.
ASSETS_DIR=assets
4-2. 소스코드 내 필요한 모든 곳에서 다음과 같은 찾아바꾸기를 실시한다. 4-1에서 저장한 변수를 불러오도록 하는 것.
// 바꾸기 전
{{ asset('assets/css/app.css') }}
// 바꾼 후
{{ asset(env('ASSETS_DIR').'/css/app.css') }}
4-3. 로컬의 .env 파일 내용 전체를 복사한 다음, 닷홈서버의 루트에 .env 파일을 새로 만들고, 그 파일의 내용을 방금 복사한 내용으로 덮어쓴 다음에, 이 부분을 고친다.
ASSETS_DIR=public/assets
4-4. 이것으로 우리는 마침내 로컬에서 돌아가는 여러분의 앱이 닷홈에서 그 모습 그대로 똑같이 돌아가는 것을 보게 되었다. 앞으로 애셋을 불러와야 할 일이 있을 때는 아묻따 env('ASSETS_DIR') 하나로 오케이.
5. 부록: 버전을 관리해서 필요한 파일만 추가 FTP 배치하기
아주 간단히 설명하고 지나간다.
5-1. 로컬에서 이 소스를 Git으로 관리한다.
5-2. 배포할 커밋 위치로 체크아웃한다.
5-3. 다음 명령어 실행하여 싹 zip으로 묶는다.
git archive --format=zip master -o ../foobar.zip
5-4. 2번 스텝에서 만들어 놓은 코드를 활용해 묶어놓은 zip을 루트에 싹 올려 덮어씌운다. 끝.
6. 부록: 아티즌 콘솔 써서 마이그레이션 하기
닷홈서버의 DB에 이미 잔존하는 테이블을 활용하는 거라면 걍 DB 덤프받아 로컬에 복붙해 시딩하고 php artisan make:model Foo 돌려 모델 만들고 그걸 배포하면 그만이지만, 없던 테이블을 만든다면 라라벨의 컨벤션에 맞게 정식으로 스키마를 만들어 마이그레이션하는 과정을 거쳐야 한다.
6-1. 일단 로컬에서 마이그레이션 직전까지 해놓는다. php artisan make:migration create_foo_table을 실행해 파일 자동 생성을 시키고, 생성된 파일의 up() 메소드와 down() 메소드를 적당히 매뉴얼 봐 가면서 채운다.
6-2. /routes/web.php 파일의 맨 끝에 아티즌 콘솔 명령을 실행하는 라인을 하나 넣는다.
Route::get('/artisan_console', function(){
Artisan::call('migrate');
});
6-3. 로컬에서 localhost:8000/artisan_console 에 접속해 up() 메소드가 계획대로 잘 돌아갔는지 확인하고, 확인되었으면 닷홈서버의 /database/migrations 디렉토리에 생성된 마이그레이션 파일을 올린 다음 /routes/web.php에 로컬과 같은 수정내역을 적용해, 마찬가지로 접속 실행한다. 닷홈DB에 migrations 테이블이 자동으로 만들어지게 되는데, 없으면... 걍 하나 만들면 됨.
후기
- 쓸데없이 길어졌네요. 제가 읽고 싶었던 문서를 제가 쓰다 보니 그렇게 되었던듯
- 아무튼 .htaccess는 웬만하면 건드리는 것이 아닙니다. 혹시 RewriteBase, RewriteCond, RewriteRule 같은것 붙잡고 씨름하고 계시다면 머리를 비우고 새로 다시 처음부터 생각해 보시길.
- 도움이 되려나 모르겠네요.
'1 내 > ㅎ 열외' 카테고리의 다른 글
세상에서 가장 무식하게 React 써보기 (0) | 2018.01.07 |
---|---|
3일만에 framework 7로 모바일 브로셔 만들기 (0) | 2015.12.24 |
새 블로그 스킨 작업중! (0) | 2015.03.05 |
fontclub, font.co.kr 미리보기 렌더러 스펙 (4) | 2014.01.31 |
⊥ED Conference (0) | 2013.05.19 |