...++
=

엊그제에 밤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가 특정 파일을 포인팅해 주지 않으면, 그 요청의 응답은 영원히 403404, 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 테이블이 자동으로 만들어지게 되는데, 없으면... 걍 하나 만들면 됨.


후기

  1. 쓸데없이 길어졌네요. 제가 읽고 싶었던 문서를 제가 쓰다 보니 그렇게 되었던듯
  2. 아무튼 .htaccess는 웬만하면 건드리는 것이 아닙니다. 혹시 RewriteBase, RewriteCond, RewriteRule 같은것 붙잡고 씨름하고 계시다면 머리를 비우고 새로 다시 처음부터 생각해 보시길.
  3. 도움이 되려나 모르겠네요.


Posted by 엽토군
:

카테고리

분류 전체보기 (799)
0 주니어 PHP 개발자 (6)
1 내 (326)
2 다른 이들의 (252)
3 늘어놓은 (37)
4 생각을 놓은 (71)
5 외치는 (76)
9 도저히 분류못함 (30)

최근에 올라온 글

최근에 달린 댓글

달력

«   2024/03   »
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