본문 바로가기
개발 팁

클라우드 & 공유호스팅 기본 세팅 — AWS, Railway, Vercel, 카페24

by 루까(Luka) 2026. 3. 18.
반응형

왜 이 글을 쓰나

요즘 직접 서버에 접근하기 어려운 환경이 늘었다. 회사 방화벽, 공유 네트워크, 보안 정책 등 이유는 다양하다. 그래서 클라우드 서비스를 쓰는 게 현실적인 선택이 됐다.

문제는 서비스마다 세팅 방법이 다 다르다는 거다. AWS는 콘솔이 복잡하고, Railway는 GitHub 연동이 전부인 것 같은데 환경변수 위치를 못 찾겠고, Vercel은 Preview/Production 환경변수 차이를 모르면 배포가 이상하게 된다. 공유호스팅(카페24, 가비아)은 SSH도 안 되고 뭔가 답답하다.

각 서비스별로 처음 시작할 때 반드시 해야 할 것들, 그리고 실제로 삽질했던 지점들을 정리했다.


AWS EC2 기본 세팅

인스턴스 생성

프리티어 기준으로 t2.micro를 선택한다. AMI는 Ubuntu 22.04 LTS가 무난하다.

AMI: Ubuntu Server 22.04 LTS (HVM)
인스턴스 유형: t2.micro (프리티어)
스토리지: 8GB gp2 (기본값)

인스턴스 생성 시 키 페어를 새로 만들거나 기존 것을 사용한다. .pem 파일은 딱 한 번만 다운로드할 수 있다. 잃어버리면 해당 키로는 다시 접속 불가다.

# pem 파일 권한 설정 (이거 안 하면 SSH 연결 거부됨)
chmod 400 ~/keys/my-key.pem

# SSH 접속
ssh -i ~/keys/my-key.pem ubuntu@{퍼블릭IP}

보안 그룹 설정

인바운드 규칙에 아무것도 없으면 외부에서 접근이 안 된다. 최소한 아래 세 가지는 열어야 한다.

유형 프로토콜 포트 소스
SSH TCP 22 내 IP (보안상 전체 개방 금지)
HTTP TCP 80 0.0.0.0/0
HTTPS TCP 443 0.0.0.0/0

SSH는 0.0.0.0/0으로 열면 브루트포스 공격이 들어온다. 반드시 내 IP로만 제한한다.

Elastic IP 연결

인스턴스를 재시작하면 퍼블릭 IP가 바뀐다. 고정 IP가 필요하면 Elastic IP를 할당하고 인스턴스에 연결한다.

EC2 콘솔 → 탄력적 IP → 탄력적 IP 주소 할당 → 주소 연결

주의: Elastic IP는 인스턴스에 연결된 상태면 무료, 연결 안 하고 방치하면 요금이 나온다.

S3 버킷 기본 설정 (정적 파일 호스팅)

이미지, CSS, JS 같은 정적 파일을 S3에 올려서 CDN처럼 쓰는 경우가 많다.

# AWS CLI로 파일 업로드
aws s3 cp ./dist s3://my-bucket-name --recursive

# 버킷 정책 (퍼블릭 읽기 허용)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-bucket-name/*"
        }
    ]
}

정적 웹사이트 호스팅을 켜면 http://{버킷명}.s3-website-{리전}.amazonaws.com 형태의 URL이 생긴다. CloudFront와 조합하면 HTTPS도 된다.


Railway

GitHub 연동 → 자동 배포

Railway는 GitHub 레포지토리를 연결하면 끝이다. 커밋 푸시할 때마다 자동으로 배포된다.

New Project → Deploy from GitHub repo → 레포 선택 → Deploy Now

빌드 커맨드와 시작 커맨드는 package.json을 보고 자동으로 감지한다. 못 찾으면 직접 지정한다.

Build Command: npm run build
Start Command: npm start

환경변수 설정

대시보드에서 서비스 선택 → Variables 탭으로 이동한다.

DATABASE_URL=postgresql://user:pass@host:5432/db
JWT_SECRET=your-secret-key
NODE_ENV=production

환경변수를 추가하면 자동으로 재배포가 트리거된다. .env 파일을 레포에 올릴 필요가 없다.

PostgreSQL/MySQL 서비스 추가

Project 대시보드 → New Service → Database → PostgreSQL

데이터베이스를 추가하면 DATABASE_URL 환경변수가 자동으로 앱 서비스에 주입된다. 별도로 복사해서 붙여넣지 않아도 된다.

커스텀 도메인 연결

서비스 선택 → Settings → Domains → Custom Domain 입력

도메인 등록 후 안내해주는 CNAME 레코드를 DNS에 등록하면 된다. HTTPS는 자동으로 발급된다.


Render

Web Service vs Static Site

구분 용도 특징
Web Service Node.js, Python, Go 등 서버 앱 슬립 모드 있음 (무료)
Static Site React, Vue 빌드 결과물 슬립 없음, 무료로 빠름
Background Worker 크론잡, 큐 처리 웹 요청 없이 실행

무료 플랜 주의사항 (슬립 모드)

Web Service 무료 플랜은 15분간 트래픽이 없으면 슬립 상태가 된다. 다음 요청이 들어오면 콜드 스타트로 30~60초 걸린다. 토이 프로젝트 데모용이면 상관없지만, 실제 서비스에서는 유료 플랜을 써야 한다.

슬립 방지 꼼수로 UptimeRobot 같은 무료 모니터링 서비스로 15분마다 헬스체크 요청을 보내는 방법이 있다. Render 정책상 권장하지는 않는다.

환경변수 설정

서비스 선택 → Environment → Environment Variables

Secret Files 기능도 있다. .env 파일 내용을 그대로 붙여넣으면 파일로 마운트해준다.

자동 배포 설정

GitHub 연동 후 기본적으로 main 브랜치 푸시 시 자동 배포된다. 특정 브랜치만 배포하거나 자동 배포를 끄려면 Settings → Build & Deploy에서 조정한다.


Vercel

Next.js/React 배포 최적화 설정

Next.js 프로젝트는 Vercel이 공식 호스팅 플랫폼이라 설정이 거의 없다. 레포 연결하면 자동으로 최적화 빌드가 된다.

vercel.json으로 추가 설정을 할 수 있다:

{
    "buildCommand": "npm run build",
    "outputDirectory": "dist",
    "rewrites": [
        { "source": "/(.*)", "destination": "/index.html" }
    ],
    "headers": [
        {
            "source": "/api/(.*)",
            "headers": [
                { "key": "Cache-Control", "value": "no-store" }
            ]
        }
    ]
}

SPA(Single Page App)라면 rewrites로 모든 경로를 index.html로 보내는 설정이 필요하다.

환경변수 — Preview vs Production 분리

Vercel의 환경변수는 세 가지 환경을 따로 관리한다.

환경 설명
Production main 브랜치 배포
Preview 다른 브랜치 / PR 배포
Development vercel dev 로컬 개발
Project Settings → Environment Variables
→ 환경변수명, 값 입력 후 적용 환경 체크

Preview에 다른 API 키나 DB URL을 써야 할 때 여기서 분리한다. 이걸 모르면 Preview 배포가 Production DB를 그대로 바라보게 된다.

커스텀 도메인 + HTTPS 자동

Project Settings → Domains → Add Domain

도메인을 추가하면 DNS 설정 안내가 나온다. A 레코드 또는 CNAME을 등록하면 HTTPS 인증서가 자동으로 발급된다.

Edge Functions 기초

Vercel Edge Functions는 CDN 엣지에서 실행되는 서버리스 함수다. 응답 속도가 기존 서버리스보다 빠르다.

// /api/hello.js (Edge Runtime)
export const config = {
    runtime: 'edge',
};

export default async function handler(request) {
    return new Response(JSON.stringify({ message: 'Hello from edge!' }), {
        headers: { 'Content-Type': 'application/json' },
    });
}

단, Edge Runtime에서는 Node.js 내장 모듈(fs, path 등)을 쓸 수 없다. Web API 기반으로만 작성해야 한다.


공유호스팅 (카페24 / 가비아)

FTP 접속 설정 (FileZilla)

공유호스팅은 SSH 대신 FTP로 파일을 올린다. FileZilla 기준:

호스트: ftp.도메인.com (카페24 호스팅 관리자에서 확인)
사용자명: FTP 계정 ID
비밀번호: FTP 비밀번호
포트: 21

파일은 보통 public_html 또는 www 폴더에 올린다. 폴더 구조:

public_html/
├── index.php
├── .htaccess
└── assets/
    ├── css/
    └── js/

DB 생성 및 phpMyAdmin 접속

카페24 호스팅 관리자 → MySQL 관리 → DB 추가

생성한 DB 정보로 phpMyAdmin에 접속한다:

https://db.호스팅사.com/phpmyadmin
계정: 생성한 DB 계정

PHP에서 DB 연결할 때 호스트는 localhost가 아니라 호스팅사에서 제공하는 내부 DB 호스트를 써야 한다.

$host = 'dbXXX.cafe24.com';  // 카페24 DB 호스트
$db   = 'my_database';
$user = 'my_user';
$pass = 'my_password';

$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8mb4", $user, $pass);

.htaccess 활용

Apache 기반 공유호스팅에서 URL 처리, 리다이렉트, 보안 설정은 .htaccess로 한다.

# www 리다이렉트
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# HTTPS 강제
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

# SPA 라우팅 (React, Vue 등)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.html [L]

# 디렉토리 목록 숨기기
Options -Indexes

# 특정 파일 접근 차단
<Files .env>
    Order allow,deny
    Deny from all
</Files>

PHP 버전 변경 방법

카페24 기준:

호스팅 관리자 → 나의 서비스 관리 → 호스팅 → PHP 버전 변경

또는 .htaccess로 직접 지정할 수 있다:

AddHandler application/x-httpd-php82 .php

버전을 바꾸고 나서 기존 코드가 동작하지 않으면 phpinfo()로 현재 설정을 확인한다.

<?php phpinfo(); ?>

확인 후 파일은 반드시 삭제한다. 서버 정보가 외부에 노출되면 보안 위협이 된다.

직접 SSH 접근 안 될 때 대처법

공유호스팅은 기본적으로 SSH가 막혀 있다. 대안:

  1. 웹 기반 파일 매니저: 호스팅 관리자에서 제공하는 웹 파일 매니저를 쓴다.
  2. PHP Shell 스크립트: exec() 함수로 서버 커맨드를 실행하는 PHP 파일을 올린다. 보안상 테스트 후 즉시 삭제해야 한다.
  3. FTP + 자동화: Git 훅이나 CI/CD에서 lftp로 자동 업로드한다.
# lftp를 이용한 자동 FTP 배포
lftp -u $FTP_USER,$FTP_PASS $FTP_HOST <<EOF
mirror -R ./dist /public_html
EOF

카페24의 경우 SSH 접근이 필요하면 별도의 SSH 상품을 신청해야 한다.


서비스별 비교

기능 비교

서비스 무료 플랜 DB 지원 커스텀 도메인 SSH 접근 슬립 모드
AWS EC2 t2.micro (12개월) 별도 RDS O (직접 설정) O 없음
Railway $5 크레딧/월 PostgreSQL, MySQL, Redis O (자동 HTTPS) X (웹 콘솔) 없음
Render 무료 (제한) PostgreSQL O (자동 HTTPS) X O (무료)
Vercel 무료 (충분) X (외부 연동) O (자동 HTTPS) X 없음
카페24 유료 (저렴) MySQL O X (별도 신청) 없음

용도별 추천

용도 추천 서비스 이유
토이 프로젝트 (프론트) Vercel 무료, 빠름, 설정 최소
토이 프로젝트 (풀스택) Railway DB 포함, GitHub 연동 간단
소규모 서비스 (Node.js) Railway / Render 유료 슬립 없이 안정적
소규모 서비스 (PHP) 카페24 PHP 환경 기본 제공
프로덕션 (제어 필요) AWS EC2 완전한 서버 제어권
정적 파일 CDN AWS S3 + CloudFront 가격 저렴, 안정적

삽질 기록

EC2 .pem 파일 날린 케이스

키 페어 .pem 파일을 실수로 삭제했다. SSH 접근이 완전히 막혔다. 해결책이 없을 것 같지만 방법이 있긴 하다. EC2 인스턴스를 중단하고, EBS 볼륨을 분리해서 다른 인스턴스에 마운트한 뒤 ~/.ssh/authorized_keys에 새 공개키를 직접 추가하는 방법이다. 절차가 복잡하고 실수하면 데이터를 잃는다. 애초에 .pem 파일은 외장 드라이브나 비밀번호 관리자에 백업해 두는 게 맞다.

Railway 환경변수 안 넣어서 배포 실패

로컬에서 .env 파일로 잘 돌아가던 앱이 Railway에서 계속 죽었다. 로그를 보니 DATABASE_URL is not defined 에러였다. .env 파일은 .gitignore에 들어있어서 레포에 없고, Railway Variables 탭에도 넣지 않은 거였다. 배포 전에 Variables 탭에서 환경변수 목록을 .env와 대조하는 습관이 필요하다.

Vercel Preview 환경변수 빠뜨린 케이스

Production 배포는 정상인데 PR마다 만들어지는 Preview URL에서 API 호출이 실패했다. 환경변수를 Production 환경에만 체크해두고 Preview에는 빠뜨린 거였다. Vercel 환경변수 설정 화면에서 체크박스가 Production / Preview / Development 세 개로 나눠져 있는데, 처음엔 이 차이를 몰랐다. 보통은 셋 다 체크해두는 게 안전하다.

카페24 .htaccess 적용 안 되는 문제

.htaccess를 올렸는데 적용이 안 됐다. 확인해 보니 두 가지 이유였다. 첫째, FTP로 파일을 올릴 때 .으로 시작하는 숨김 파일이 전송되지 않도록 설정되어 있었다. FileZilla의 서버 → 숨김 파일 강제 표시 옵션을 켜야 한다. 둘째, 카페24 호스팅 설정에서 mod_rewrite 모듈이 기본으로 비활성화된 플랜이 있다. 호스팅 관리자에서 .htaccess 사용 여부를 활성화하는 메뉴가 따로 있다.


마무리

클라우드 서비스는 많고, 각각의 세팅 방법이 다르다. 하지만 결국 공통적인 흐름이 있다. 배포 소스 연결 → 환경변수 주입 → 도메인 연결 → HTTPS 설정. 이 네 단계를 어디서 어떻게 하는지가 다를 뿐이다.

처음 세팅할 때 막히는 지점 대부분은 문서를 읽으면 해결된다. 단, 환경변수 누락과 보안 그룹 설정은 로그를 잘 읽지 않으면 원인을 찾기 어렵다. 뭔가 안 되면 로그부터 확인하는 습관을 들이는 게 가장 빠른 길이다.


다루는 서비스: AWS EC2, S3, Railway, Render, Vercel, 카페24

반응형