목적
PHP + MySQL 웹 게시판(도커 패키지화 상태)을 각종 Google Cloud 서비스를 통해 배포
1. 주요 코드 점검 및 수정

본 코드들은 로컬 환경에서 작동하기에 문제없는 코드지만, 클라우드 환경에서는 문제 발생
이유는 각 환경에 차이점이 존재하기 때문
차이점
| Local 환경 |
| docker-compose.yml 사용 MySQL + PHP를 묶어서 관리 쉬운 데이터베이스 접근 |
| Cloud 환경 |
| 독립 단일 컨테이너 Cloud Run을 통해 실행 독립 단일 데이터베이스 Cloud SQL에서 인스턴스 제공 이 둘을 연결하기 위해 Cloud SQL Auth Proxy 연결 방식 사용 |
즉, 로컬 환경에 맞춰 제작된 코드를 클라우드 환경에 맞게 수정할 예정
| Cloud SQL Auth Proxy |
| 애플리케이션의 Cloud SQL 데이터베이스 접근을 돕는 도구 및 프록시 데이터베이스 접속 정보 제공 or 환경 변수 설정 방법 존재 gcloud의 IAM 권한 확인, 보안 경로 생성, Unix 소켓을 통한 데이터베이스 연결 과정 |
| Unix 소켓 |
| 같은 시스템 속 프로세스 간 통신 파일 프록시가 생성한 경로 속 해당 소켓을 통해서만 통신 가능 |
db.php
//수정 전
<?php
$host = 'db';
$user = 'scpuser';
$pw = 'scppass';
$dbname = 'scp';
$conn = new mysqli($host, $user, $pw, $dbname);
if ($conn->connect_error) {
die('MySQL 연결 실패' . $conn->connect_error);
}
?>
//수정 후
<?php
//Cloud Run에 입력 및 설정할 환경변수
//데이터베이스 연결 정보 호출 용도
//getenv() : 실행되는 서버의 환경 변수 값을 읽어오는 함수(PHP 내장 함수)
//getenv() 사용 이유 : Cloud Run은 컨테이너에 직접 접근할 수 없기때문 + 민감 정보들 하드코딩 방지
$db_socket = getenv('DB_SOCKET_PATH'); //Cloud Run -> Cloud SQL 접근 Unix 소켓 경로
$db_name = getenv('DB_NAME');
$db_user = getenv('DB_USER');
$db_password = getenv('DB_PASSWORD');
//Cloud SQL Auth Proxy를 통해 Unix 소켓 연결
//new mysqli() 인자값 : (첫 null - 호스트명 / Unix 소켓에는 호스트명 불필요, 두번째 null - 포트번호 / Unix 소켓을 사용하기에 포트 불필요)
$conn = new mysqli(null, $db_user, $db_password, $db_name, null, $db_socket);
if ($conn->connect_error) {
die("데이터베이스 연결 실패: " . $conn->connect_error);
}
?>
Dockerfile
FROM php:8.2-apache
RUN docker-php-ext-install mysqli
RUN mkdir -p /var/www/html/uploads && chmod 777 /var/www/html/uploads
COPY . /var/www/html/
RUN a2enmod rewrite
EXPOSE 80
FROM php:8.2-apache
#Composer 설치
#COPY : 파일 복사 명령어
# --from=composer : 해당 이름을 가진 이미지에서 파일을 가져오는 옵션
#lastest : 이미지 이름
#/usr/bin/composer : 이미지 내부의 composer 실행 위치 및 경로
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
RUN docker-php-ext-install mysqli
#zip 확장 모듈 설치
#RUN : Dockerfile 컨테이너 내부 셸 실행 명령어
#apt-get update : 패키지 목록 업데이트 명렁어
#apt-get install -y libzip-dev : libzip(개발 라이브러리)설치 명령어
#docker-php-ext-install zip : zip 확장 모듈 설치 및 라이브러리 모듈 빌드 활성화
RUN apt-get update && apt-get install -y libzip-dev \
&& docker-php-ext-install zip
#composer.json : 라이브러리 목록 및 버전 정의 파일
#composer.lock : composer 설치시 자동 생성되는 파일 / 모든 환경 호환 목적
COPY composer.json composer.lock ./
#composer install : 모든 패키지 설치 명령어
#--no-dev : 개발에만 쓰이는 등 불필요한 파일 제거 옵션
#--optimize-autoloader : Composer 오버로딩 최적화
RUN composer install --no-dev --optimize-autoloader
RUN mkdir -p /var/www/html/uploads && chmod 777 /var/www/html/uploads
COPY . /var/www/html/
RUN a2enmod rewrite
#CMD : 컨테이너 실행 명령어 정의
#apache2ctl : Apache 서버 제어 스크립트
#-D : Define / Apache 서버 특정 정의 전달 옵션
#FOREGROUND : Apache 프로세스 유지 및 컨테이너 실행 유지 모드
#-k start : Apache 서버 시작 명령어
#-c : Configuration / 명령 및 추가 설정 지정 옵션
#Listen ${PORT} : Apache 서버에서 외부 요청 수신 포트 번호 지정
#${PORT} 사용 이유 : Cloud Run에서 사용할 포트 번호를 환경 변수를 통해 동적으로 할당하기 위해
CMD ["apache2ctl", "-D", "FOREGROUND", "-k", "start", "-c", "Listen ${PORT}"]
Composer
라이브러리 및 패키지 관리자
2. 필요 API 활성화

Google Cloud는 감사하게 무료 체험판 3개월 이용 가능

각 주요 API들이 활성화되어 있는지 확인 필요
활성화되어있지 않다면,
"+ API 및 서비스 사용 설정" → "API 및 서비스 검색" 직접 활성화

Docker 이미지 기반 컨테이너 배포 및 관리가 목적인 API
이를 활성화해야 GCP가 Cloud Run 서비스 생성, 수정, 삭제 등 모든 작업 수행 가능

Cloud SQL 인스턴스 관리가 목적인 API
이를 활성화해야 Cloud SQL 인스턴스 생성, Cloud Run 서비스와의 연결 및 고급설정 가능

Docker 이미지나 패키지 저장 및 관리가 목적인 API
이를 활성화해야 로컬에서 빌드한 이미지를 GCP 저장소에 업로드 가능
만약 비활성화 시 Cloud Run에서 저장소 속 이미지를 가져오는 것은 불가능
3. 인스턴스 + 데이터베이스 생성
인스턴스
클라우드 환경에서 실행되는 하나의 독립적인 데이터베이스 서버를 의미
해당 서버는 GCP에서 관리해 주므로, 따로 운영체제 관리나 보안 패치가 불필요
인스턴스 생성 이유
웹 애플리케이션이 데이터를 저장하고 읽을 수 있는 데이터베이스 서버 생성 목적
로컬 MySQL을 더 이상 사용하지 않기 때문 + 클라우드에서 안전하게 실행되기 때문
그냥 성능, 안정성, 네트워크 속도면에서 Better than anything

"+ 인스턴스 만들기" -> "MySQL 선택" -> Cloud SQL 버전 선택(Enterprise plus / Enterprise)

리전
GCP은 전 세계 여러 곳에 분산되어 있는 데이터 센터 보유
즉, 서버실이 위치하고 있는 지역을 의미
가까운 지역의 센터가 최적화된 성능 제공
애플리케이션(Cloud Run)과 데이터베이스(Cloud SQL)가 서로 통신하기 때문
만약 동일한 리전을 고르지 않아, 멀리 떨어져 있으면 네트워크 지연, 추가 비용 발생

SQL 페이지 왼쪽메뉴 "데이터베이스" -> "+데이터베이스 만들기"


4. 계정 권한 확인

주 구성원 목록 중 "Default account" 에게 역할 추가

Cloud Run 서비스가 GCP 속 다른 서비스에 접근 및 조작을 허용하기 위해 권한 부여를 하는 것이 당연
Cloud SQL Client
Cloud SQL 인스턴스에 연결이나, 데이터를 읽고 쓸 수 있는 권한 제공
Cloud Run 컨테이너가 해당 인스턴스에 접속하여 데이터를 저장 및 조회해야 하기 때문
Cloud SQL Auth Proxy를 통해 이루어지는 핵심 권한
권한 상실 시 db.php로부터 연결 실패 발생
환경 및 Storage 객체 관리자
Cloud Composer 환경 및 Cloud Storage 객체 관리 권한
버킷 업로드 및 관리

5. 버킷 설정 및 테이블 연결

Cloud Storage 왼쪽메뉴 "버킷" -> "+만들기"
스토리지
저장소
GCP에서는 저장 서비스는 전부 스토리지라고 통칭 (ex. Cloud Filestore, Cloud SQL 등)
버킷
스토리지 내에 있는 데이터를 담은 최상위 컨테이너
즉, 가장 먼저 만들어져야 하는 폴더를 의미
모든 파일은 반드시 버킷에 저장
파일 관리 / 권한 설정 / 데이터 수명 주기 관리



Cloud SQL에 데이터베이스.sql 파일을 직접 업로드하는 기능은 없는 것으로 인지
Cloud Storage를 경유하는 방식 채택
애초에 로컬환경에서 제작된 sql파일을 직접 연결하는 것보다
안전하고, 빠르고,
외부 접속을 계속 열지 않기에 보안적이고,
대용량 파일 처리도 효율적이고,
... etc

Storage에 버킷이 문제없이 생성되고, 파일 업로드도 기깔나게 되었다면 문제없이 파일 선택 가능
이외에 파일 형식, 대상 위치 확인
6. 레지스트리 생성 및 Docker 이미지 빌드/푸시

레지스트리
컨테이너 이미지 저장 및 관리 서비스 전체를 의미
쉽게 로컬에서 만든 Docker 이미지를 옮길 저장소라고 생각
결국 Cloud Run을 위해 필요
version tag를 통해 특정 버전별 이미지 배포 가능
이미지 보안 용이


gcloud CLI 설치 | Google Cloud SDK Documentation
이 페이지는 Cloud Translation API를 통해 번역되었습니다. 의견 보내기 gcloud CLI 설치 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 이 페이지에는 Google Cloud CLI
cloud.google.com
Google Cloud CLI
Google Cloud Platform을 제어하는 명령 도구 모음
GCP, Artifact Registry 인증 및 연결
서비스 관리
Docker Desktop: The #1 Containerization Tool for Developers | Docker
Docker Desktop is collaborative containerization software for developers. Get started and download Docker Desktop today on Mac, Windows, or Linux.
www.docker.com
Docker Desktop
Docker 컨테이너를 로컬환경에서 제작/실행하도록 하는 애플리케이션
최종 배포될 컨테이너 이미지를 만드는(docker build) 역할
Artifact Registry 등 저장소에 업로드(docker push) 역할
로컬에서 오류 검증 및 테스트
로컬환경 + GCP 연결 및 초기 설정
gcloud init




gcloud + Docker 연결 설정
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
<asia-northeast3> : 사용자의 리전
gcloud auth : 인증 관련 명령어
configure-docker : docker 명령어의 인증 처리 방식 "설정"
docker.pkg.dev : 리전에 해당하는 이미지 저장소에 대한 인증 "설정"
Docker에서 GCP의 저장소로 이미지를 올리기 위한 별도의 과정
해당 명령어의 초기 결과값
Credential helper for asia-northeast3-docker.pkg.dev configured to use gcloud.
config.json 파일 업데이트 메세지
Docker가 Artifact Registry에 인증이 완료되었다는 의미

credHelpers : Docker 인증과 인증 도우미 사용 정의 "설정"
해당 로그는 이미 인증 도우미 설정과 함께 config.json파일이 있다는 의미
Docker 이미지 빌드 및 패키징 with Dockerfile
docker build -t my-php-app:latest .
<my-php-app> : Artifact Registry에서 확인 가능한 이미지의 고유 이름
docker build : Docker 이미지 빌드 지시 명령어
-t : 태그 지정 옵션
latest : 이미지 버전 태그
. : 현재 작업 중인 디렉터리를 의미
어떤 환경에서는 빌드하여 이미지 생성 및 문제 방지
Docker Desktop 미실행

Docker를 꼭 ON하고 진행할 것

[internal] load : Dockerfile을 읽고, 빌드하여 Docker 엔진으로 전송하는 과정
CACHED [stage-0 ~] : 실행 과정이 이미 이전에 성공하여 캐시에 저장되었다는 의미
잠깐만!! 빌드 이전에 composer.json 작성 필수

require : 필수 작성 및 의존성 목록 정의
google/cloud-storage : 사용 라이브러리 이름 및 피접근자
^1.30 : 라이브러리 버전 조건
빌드 이후

composer.lock
모든 라이브러리의 버전 및 해시값 기록
즉, 모두 같은 버전의 라이브러리 사용 가능
Cloud Run 환경은 라이브러리 버전이 중요
이미지 경로(Arifact Registry)로 태그 지정
docker tag my-php-app:latest asia-northeast3-docker.pkg.dev/round-device-468004-p1/scp/my-php-app:latest
<my-php-app> : Artifact Registry에서 확인 가능한 이미지의 고유 이름
<asia-northeast3> : 사용자의 리전
<round-device-468004-p1> : 사용자의 프로젝트 ID
scp : 사용자의 Artifact Registry명
docker tag : Docker 이미지의 태그 변경, 추가, 복사 등 실행 명령어
ex. docker tag [원본 이미지] / [새로운 (복사) 이미지]
원본 이미지를 복사하여 새로운 이미지로써 태그를 부여
이미지 Artifact Registry 푸시
docker push asia-northeast3-docker.pkg.dev/round-device-468004-p1/scp/my-php-app:latest
docker push : Docker 이미지를 Registry로 push 하는 명령어
ex. docker push [원본 도메인] / [새로운 위치]
클라우드 서비스는 로컬의 이미지를 직접 가져오지 못하기에 꼭꼭 필요한 절차


7. 배포

"+ 서비스 만들기"




