정적 웹사이트 호스팅

이 가이드는 소유한 도메인의 정적 웹사이트를 호스팅하기 위해 Cloud Storage 버킷을 구성하는 방법을 설명합니다. 정적 웹페이지에는 HTML, CSS, 자바스크립트와 같은 클라이언트 측 기술이 포함될 수 있습니다. 반면, PHP 등의 서버 측 스크립트를 비롯한 동적 콘텐츠는 포함될 수 없습니다.

Cloud Storage는 자체적으로 HTTPS 커스텀 도메인을 지원하지 않으므로 이 가이드에서는 Cloud Storage를 HTTP(S) 부하 분산과 함께 사용하여 HTTPS를 통해 커스텀 도메인에서 콘텐츠를 제공합니다. HTTPS를 통해 커스텀 도메인에서 콘텐츠를 제공하는 다른 방법은 관련 문제 해결 주제를 참조하세요. Cloud Storage를 사용하여 부하 분산기가 필요 없는 HTTP를 통해 커스텀 도메인 콘텐츠를 제공할 수도 있습니다.

동적 웹사이트의 정적 애셋을 호스팅하는 방법을 비롯하여 정적 웹페이지에 대한 예시와 도움말은 정적 웹사이트 페이지를 참조하세요.

목표

이 가이드에서는 다음을 수행하는 방법을 보여줍니다.

  • 버킷을 만듭니다.
  • 사이트의 파일을 업로드하고 공유합니다.
  • 부하 분산기와 SSL 인증서를 설정합니다.
  • 부하 분산기를 버킷에 연결합니다.
  • A 레코드를 사용하여 도메인이 부하 분산기를 가리키도록 합니다.
  • 웹사이트를 테스트합니다.

비용

이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

  • Cloud Storage
  • Cloud Load Balancing

정적 웹사이트 호스팅 시 발생할 수 있는 요금에 대한 자세한 내용은 요금 모니터링 팁을 참조하세요. Cloud Storage 비용에 대한 자세한 내용은 가격 책정 페이지를 참조하세요.

시작하기 전에

  1. Google 계정으로 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기 페이지로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. 자신이 소유하거나 관리하는 도메인이 있어야 합니다. 기존 도메인이 없는 경우, Google Domains와 같은 다양한 서비스를 이용하여 새 도메인을 등록할 수 있습니다.

    이 가이드는 example.com 도메인을 사용합니다.

  5. 사용할 도메인을 소유 또는 관리하고 있는지 확인합니다. www.example.com과 같은 하위 도메인이 아니라 example.com과 같은 최상위 도메인을 확인해야 합니다.

    참고: 버킷에 연결된 도메인을 소유하고 있는 경우, 이전에 이 단계를 이미 수행했을 수 있습니다. Google Domains를 통해 도메인을 구입한 경우, 자동으로 확인이 수행됩니다.

  6. 제공할 웹사이트 파일이 있어야 합니다. 이 가이드는 최소한 색인 페이지(index.html)와 404 페이지(404.html)가 있는 경우에 가장 효과적입니다.
  7. 프로젝트 소유자 또는 편집자 역할이나 ID 및 액세스 관리 역할(스토리지 객체 관리자네트워크 관리자)이 있어야 합니다.

버킷 만들기

www.example.com이라는 버킷을 만들려면 다음 안내를 따르세요.

Console

  1. Google Cloud Console에서 Cloud Storage 브라우저를 엽니다.
    Cloud Storage 브라우저 열기
  2. 버킷 생성을 클릭하여 버킷 생성 양식을 엽니다.

  3. 각 단계를 완료하려면 버킷 정보를 입력하고 계속을 클릭합니다.

    • 버킷의 이름을 설정합니다. 도메인 이름과 동일하게 만들면 이후 단계가 쉬워집니다(예: www.example.com).

    • 버킷의 위치 유형위치를 선택합니다(예: 리전us-east1).

    • 스토리지 클래스표준 스토리지를 선택합니다.

    • 액세스 제어균일을 선택합니다.

  4. 만들기를 클릭합니다.

성공하면 버킷 세부정보 페이지가 열리고 '이 버킷에 실시간 객체가 없습니다.'라는 텍스트가 표시됩니다.

Cloud Storage 브라우저에서 실패한 작업에 대한 자세한 오류 정보를 가져오는 방법은 문제해결을 참조하세요.

gsutil

gsutil mb 명령어를 사용합니다.

gsutil mb -b on gs://www.example.com

성공하면 명령어가 다음을 반환합니다.

Creating gs://www.example.com/...

코드 샘플

C++

자세한 내용은 Cloud Storage C++ API 참조 문서를 확인하세요.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name) {
  StatusOr<gcs::BucketMetadata> bucket_metadata =
      client.CreateBucket(bucket_name, gcs::BucketMetadata());

  if (!bucket_metadata) {
    throw std::runtime_error(bucket_metadata.status().message());
  }

  std::cout << "Bucket " << bucket_metadata->name() << " created."
            << "\nFull Metadata: " << *bucket_metadata << "\n";
}

C#

자세한 내용은 Cloud Storage C# API 참조 문서를 확인하세요.

public static Bucket StorageCreateBucket(string projectId, string bucketName)
{
    var storage = StorageClient.Create();
    var bucket = storage.CreateBucket(projectId, bucketName);
    Console.WriteLine($"Created {bucketName}.");
    return bucket;
}

Go

자세한 내용은 Cloud Storage Go API 참조 문서를 확인하세요.

import (
	"context"
	"fmt"
	"io"
	"time"

	"cloud.google.com/go/storage"
)

// createBucketClassLocation creates a new bucket in the project with Storage class and
// location.
func createBucketClassLocation(w io.Writer, projectID, bucketName string) error {
	// projectID := "my-project-id"
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	storageClassAndLocation := &storage.BucketAttrs{
		StorageClass: "COLDLINE",
		Location:     "asia",
	}
	bucket := client.Bucket(bucketName)
	if err := bucket.Create(ctx, projectID, storageClassAndLocation); err != nil {
		return fmt.Errorf("Bucket(%q).Create: %v", bucketName, err)
	}
	fmt.Fprintf(w, "Created bucket %v in %v with storage class %v\n", bucketName, storageClassAndLocation.Location, storageClassAndLocation.StorageClass)
	return nil
}

자바

자세한 내용은 Cloud Storage 자바 API 참조 문서를 확인하세요.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.BucketInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageClass;
import com.google.cloud.storage.StorageOptions;

public class CreateBucketWithStorageClassAndLocation {
  public static void createBucketWithStorageClassAndLocation(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID to give your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();

    // See the StorageClass documentation for other valid storage classes:
    // https://googleapis.dev/java/google-cloud-clients/latest/com/google/cloud/storage/StorageClass.html
    StorageClass storageClass = StorageClass.COLDLINE;

    // See this documentation for other valid locations:
    // http://g.co/cloud/storage/docs/bucket-locations#location-mr
    String location = "ASIA";

    Bucket bucket =
        storage.create(
            BucketInfo.newBuilder(bucketName)
                .setStorageClass(storageClass)
                .setLocation(location)
                .build());

    System.out.println(
        "Created bucket "
            + bucket.getName()
            + " in "
            + bucket.getLocation()
            + " with storage class "
            + bucket.getStorageClass());
  }
}

Node.js

자세한 내용은 Cloud Storage Node.js API 참조 문서를 확인하세요.

/**
 * TODO(developer): Uncomment the following line before running the sample.
 */
// const bucketName = 'Name of a bucket, e.g. my-bucket';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function createBucket() {
  // Creates a new bucket in the Asia region with the coldline default storage
  // class. Leave the second argument blank for default settings.
  //
  // For default values see: https://cloud.google.com/storage/docs/locations and
  // https://cloud.google.com/storage/docs/storage-classes

  const [bucket] = await storage.createBucket(bucketName, {
    location: 'ASIA',
    storageClass: 'COLDLINE',
  });

  console.log(`Bucket ${bucket.name} created.`);
}

createBucket().catch(console.error);

PHP

자세한 내용은 Cloud Storage PHP API 참조 문서를 확인하세요.

use Google\Cloud\Storage\StorageClient;

/**
 * Create a Cloud Storage Bucket.
 *
 * @param string $bucketName name of the bucket to create.
 * @param string $options options for the new bucket.
 *
 */
function create_bucket($bucketName, $options = [])
{
    $storage = new StorageClient();
    $bucket = $storage->createBucket($bucketName, $options);
    printf('Bucket created: %s' . PHP_EOL, $bucket->name());
}

Python

자세한 내용은 Cloud Storage Python API 참조 문서를 확인하세요.

from google.cloud import storage

def create_bucket_class_location(bucket_name):
    """Create a new bucket in specific location with storage class"""
    # bucket_name = "your-new-bucket-name"

    storage_client = storage.Client()

    bucket = storage_client.bucket(bucket_name)
    bucket.storage_class = "COLDLINE"
    new_bucket = storage_client.create_bucket(bucket, location="us")

    print(
        "Created bucket {} in {} with storage class {}".format(
            new_bucket.name, new_bucket.location, new_bucket.storage_class
        )
    )
    return new_bucket

Ruby

자세한 내용은 Cloud Storage Ruby API 참조 문서를 확인하세요.

# bucket_name   = "Name of Google Cloud Storage bucket to create"
# location      = "Location of where to create Cloud Storage bucket"
# storage_class = "Storage class of Cloud Storage bucket"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket  = storage.create_bucket bucket_name,
                                location:      location,
                                storage_class: storage_class

puts "Created bucket #{bucket.name} in #{location}" \
     " with #{storage_class} class"

REST API

JSON API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. 웹사이트 이름을 name 속성에 할당하는 .json 파일을 만듭니다.

    {
      "name": "www.example.com"
    }
  3. cURL을 사용하여 JSON API를 호출합니다. www.example.com의 경우는 다음과 같습니다.

    curl -X POST --data-binary @website-bucket-name.json \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b?project=my-static-website"

XML API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. cURL을 사용하여 웹사이트 이름으로 버킷을 만드는 XML API를 호출합니다. www.example.com의 경우는 다음과 같습니다.

    curl -X PUT \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      -H "x-goog-project-id: my-static-website" \
      "https://storage.googleapis.com/www.example.com"

사이트 파일 업로드

웹사이트가 제공할 파일을 버킷에 추가합니다.

Console

  1. Google Cloud Console에서 Cloud Storage 브라우저를 엽니다.
    Cloud Storage 브라우저 열기
  2. 버킷 목록에서 앞서 만든 버킷의 이름을 클릭합니다.

    객체 탭이 선택된 상태로 버킷 세부정보 페이지가 열립니다.

  3. 파일 업로드 버튼을 클릭합니다.

  4. 파일 대화상자에서 원하는 파일을 탐색하고 선택합니다.

업로드가 완료되면 버킷에 표시된 파일 정보와 함께 파일 이름이 표시됩니다.

Cloud Storage 브라우저에서 실패한 작업에 대한 자세한 오류 정보를 가져오는 방법은 문제해결을 참조하세요.

gsutil

gsutil cp 명령어를 사용하여 파일을 버킷으로 복사합니다. 예를 들어 현재 위치 Desktop에서 index.html 파일을 복사하려면 다음을 사용하세요.

gsutil cp Desktop/index.html gs://www.example.com

성공하면 명령어가 다음을 반환합니다.

Copying file://Desktop/index.html [Content-Type=text/html]...
Uploading   gs://www.example.com/index.html:       0 B/2.58 KiB
Uploading   gs://www.example.com/index.html:       2.58 KiB/2.58 KiB

코드 샘플

C++

자세한 내용은 Cloud Storage C++ API 참조 문서를 확인하세요.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& file_name,
   std::string const& bucket_name, std::string const& object_name) {
  // Note that the client library automatically computes a hash on the
  // client-side to verify data integrity during transmission.
  StatusOr<gcs::ObjectMetadata> metadata = client.UploadFile(
      file_name, bucket_name, object_name, gcs::IfGenerationMatch(0));
  if (!metadata) throw std::runtime_error(metadata.status().message());

  std::cout << "Uploaded " << file_name << " to object " << metadata->name()
            << " in bucket " << metadata->bucket()
            << "\nFull metadata: " << *metadata << "\n";
}

C#

자세한 내용은 Cloud Storage C# API 참조 문서를 확인하세요.

private void UploadFile(string bucketName, string localPath,
    string objectName = null)
{
    var storage = StorageClient.Create();
    using (var f = File.OpenRead(localPath))
    {
        objectName = objectName ?? Path.GetFileName(localPath);
        storage.UploadObject(bucketName, objectName, null, f);
        Console.WriteLine($"Uploaded {objectName}.");
    }
}

Go

자세한 내용은 Cloud Storage Go API 참조 문서를 확인하세요.

import (
	"context"
	"fmt"
	"io"
	"os"
	"time"

	"cloud.google.com/go/storage"
)

// uploadFile uploads an object.
func uploadFile(w io.Writer, bucket, object string) error {
	// bucket := "bucket-name"
	// object := "object-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	// Open local file.
	f, err := os.Open("notes.txt")
	if err != nil {
		return fmt.Errorf("os.Open: %v", err)
	}
	defer f.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*50)
	defer cancel()

	// Upload an object with storage.Writer.
	wc := client.Bucket(bucket).Object(object).NewWriter(ctx)
	if _, err = io.Copy(wc, f); err != nil {
		return fmt.Errorf("io.Copy: %v", err)
	}
	if err := wc.Close(); err != nil {
		return fmt.Errorf("Writer.Close: %v", err)
	}
	fmt.Fprintf(w, "Blob %v uploaded.\n", object)
	return nil
}

자바

자세한 내용은 Cloud Storage 자바 API 참조 문서를 확인하세요.

import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class UploadObject {
  public static void uploadObject(
      String projectId, String bucketName, String objectName, String filePath) throws IOException {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    // The ID of your GCS object
    // String objectName = "your-object-name";

    // The path to your file to upload
    // String filePath = "path/to/your/file"

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    BlobId blobId = BlobId.of(bucketName, objectName);
    BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
    storage.create(blobInfo, Files.readAllBytes(Paths.get(filePath)));

    System.out.println(
        "File " + filePath + " uploaded to bucket " + bucketName + " as " + objectName);
  }
}

Node.js

자세한 내용은 Cloud Storage Node.js API 참조 문서를 확인하세요.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const bucketName = 'Name of a bucket, e.g. my-bucket';
// const filename = 'Local file to upload, e.g. ./local/path/to/file.txt';

// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');

// Creates a client
const storage = new Storage();

async function uploadFile() {
  // Uploads a local file to the bucket
  await storage.bucket(bucketName).upload(filename, {
    // Support for HTTP requests made with `Accept-Encoding: gzip`
    gzip: true,
    // By setting the option `destination`, you can change the name of the
    // object you are uploading to a bucket.
    metadata: {
      // Enable long-lived HTTP caching headers
      // Use only if the contents of the file will never change
      // (If the contents will change, use cacheControl: 'no-cache')
      cacheControl: 'public, max-age=31536000',
    },
  });

  console.log(`${filename} uploaded to ${bucketName}.`);
}

uploadFile().catch(console.error);

PHP

자세한 내용은 Cloud Storage PHP API 참조 문서를 확인하세요.

use Google\Cloud\Storage\StorageClient;

/**
 * Upload a file.
 *
 * @param string $bucketName the name of your Google Cloud bucket.
 * @param string $objectName the name of the object.
 * @param string $source the path to the file to upload.
 *
 * @return Psr\Http\Message\StreamInterface
 */
function upload_object($bucketName, $objectName, $source)
{
    $storage = new StorageClient();
    $file = fopen($source, 'r');
    $bucket = $storage->bucket($bucketName);
    $object = $bucket->upload($file, [
        'name' => $objectName
    ]);
    printf('Uploaded %s to gs://%s/%s' . PHP_EOL, basename($source), $bucketName, $objectName);
}

Python

자세한 내용은 Cloud Storage Python API 참조 문서를 확인하세요.

Blob.upload_from_file(), Blob.upload_from_filename() 또는 Blob.upload_from_string() 메서드를 사용하여 객체를 업로드합니다.
from google.cloud import storage

def upload_blob(bucket_name, source_file_name, destination_blob_name):
    """Uploads a file to the bucket."""
    # bucket_name = "your-bucket-name"
    # source_file_name = "local/path/to/file"
    # destination_blob_name = "storage-object-name"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(destination_blob_name)

    blob.upload_from_filename(source_file_name)

    print(
        "File {} uploaded to {}.".format(
            source_file_name, destination_blob_name
        )
    )

Ruby

자세한 내용은 Cloud Storage Ruby API 참조 문서를 확인하세요.

# bucket_name       = "Your Google Cloud Storage bucket name"
# local_file_path   = "Path to local file to upload"
# storage_file_path = "Path to store the file in Google Cloud Storage"

require "google/cloud/storage"

storage = Google::Cloud::Storage.new
bucket  = storage.bucket bucket_name

file = bucket.create_file local_file_path, storage_file_path

puts "Uploaded #{file.name}"

REST API

JSON API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. cURL을 사용하여 POST 객체 요청으로 JSON API를 호출합니다. www.example.com 색인 페이지의 경우 다음과 같습니다.

    curl -X POST --data-binary @index.html \
      -H "Content-Type: text/html" \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      "https://storage.googleapis.com/upload/storage/v1/b/www.example.com/o?uploadType=media&name=index.html"

XML API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. cURL을 사용하여 PUT 객체 요청으로 XML API를 호출합니다. www.example.com 색인 페이지의 경우 다음과 같습니다.

    curl -X PUT --data-binary @index.html \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      -H "Content-Type: text/html" \
      "https://storage.googleapis.com/www.example.com/index.html"

파일 공유

공개 인터넷의 모든 사용자가 버킷의 모든 객체를 읽을 수 있도록 하려면 다음 단계를 따르세요.

Console

  1. Google Cloud Console에서 Cloud Storage 브라우저를 엽니다.
    Cloud Storage 브라우저 열기
  2. 버킷 목록에서 공개하려는 버킷의 이름을 클릭합니다.

  3. 페이지 상단의 권한 탭을 선택합니다.

  4. 구성원 추가 버튼을 클릭합니다.

    구성원 추가 대화상자가 나타납니다.

  5. 새 구성원 필드에 allUsers를 입력합니다.

  6. 역할 선택 드롭다운에서 Cloud Storage 하위 메뉴를 선택하고 Storage Object Viewer 옵션을 클릭합니다.

  7. 저장을 클릭합니다.

  8. 공개 액세스 허용을 클릭합니다.

버킷이 공개적으로 공유되면 공개 액세스 열에 각 객체의 링크 아이콘이 나타납니다. 이 아이콘을 클릭하여 객체의 URL을 가져올 수 있습니다.

Cloud Storage 브라우저에서 실패한 작업에 대한 자세한 오류 정보를 가져오는 방법은 문제해결을 참조하세요.

gsutil

gsutil iam ch 명령어를 사용합니다.

gsutil iam ch allUsers:objectViewer gs://www.example.com

코드 샘플

C++

자세한 내용은 Cloud Storage C++ API 참조 문서를 확인하세요.

namespace gcs = google::cloud::storage;
using google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name) {
  StatusOr<google::cloud::IamPolicy> current_policy =
      client.GetBucketIamPolicy(bucket_name);

  if (!current_policy) {
    throw std::runtime_error(current_policy.status().message());
  }

  current_policy->bindings.AddMember("roles/storage.objectViewer",
                                     "allUsers");

  // Update the policy. Note the use of `gcs::IfMatchEtag` to implement
  // optimistic concurrency control.
  StatusOr<google::cloud::IamPolicy> updated_policy =
      client.SetBucketIamPolicy(bucket_name, *current_policy,
                                gcs::IfMatchEtag(current_policy->etag));

  if (!updated_policy) {
    throw std::runtime_error(current_policy.status().message());
  }

  auto role = updated_policy->bindings.find("roles/storage.objectViewer");
  if (role == updated_policy->bindings.end()) {
    std::cout << "Cannot find 'roles/storage.objectViewer' in the updated"
              << " policy. This can happen if another application updates"
              << " the IAM policy at the same time. Please retry the"
              << " operation.\n";
    return;
  }
  auto member = role->second.find("allUsers");
  if (member == role->second.end()) {
    std::cout << "'allUsers' is not a member of the"
              << " 'roles/storage.objectViewer' role in the updated"
              << " policy. This can happen if another application updates"
              << " the IAM policy at the same time. Please retry the"
              << " operation.\n";
    return;
  }
  std::cout << "IamPolicy successfully updated for bucket " << bucket_name
            << '\n';
}

자바

자세한 내용은 Cloud Storage 자바 API 참조 문서를 확인하세요.

import com.google.cloud.Identity;
import com.google.cloud.Policy;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.StorageRoles;

public class MakeBucketPublic {
  public static void makeBucketPublic(String projectId, String bucketName) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your GCS bucket
    // String bucketName = "your-unique-bucket-name";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Policy originalPolicy = storage.getIamPolicy(bucketName);
    storage.setIamPolicy(
        bucketName,
        originalPolicy
            .toBuilder()
            .addIdentity(StorageRoles.objectViewer(), Identity.allUsers()) // All users can view
            .build());

    System.out.println("Bucket " + bucketName + " is now publicly readable");
  }
}

Python

자세한 내용은 Cloud Storage Python API 참조 문서를 확인하세요.

from google.cloud import storage

def set_bucket_public_iam(bucket_name, role, member):
    """Set a public IAM Policy to bucket"""
    # bucket_name = "your-bucket-name"
    # role = "IAM role, e.g. roles/storage.objectViewer"
    # member = "IAM identity, e.g. allUsers"

    storage_client = storage.Client()
    bucket = storage_client.bucket(bucket_name)

    policy = bucket.get_iam_policy(requested_policy_version=3)
    policy.bindings.append({"role": role, "members": {member}})

    bucket.set_iam_policy(policy)

    print("Bucket {} is now publicly readable".format(bucket.name))

REST API

JSON API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. 다음 정보를 포함하는 .json 파일을 만듭니다.

    {
      "bindings":[
        {
          "role": "roles/storage.objectViewer",
          "members":["allUsers"]
        }
      ]
    }
  3. cURL을 사용하여 PUT 버킷 요청으로 JSON API를 호출합니다.

    curl -X PUT --data-binary @JSON_FILE_NAME.json \
      -H "Authorization: Bearer OAUTH2_TOKEN" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/iam"

    각 항목의 의미는 다음과 같습니다.

    • JSON_FILE_NAME은 2단계에서 만든 파일의 이름입니다.
    • OAUTH2_TOKEN은 1단계에서 생성한 액세스 토큰입니다.
    • BUCKET_NAME은 객체를 공개할 버킷의 이름입니다. 예를 들면 my-bucket입니다.

XML API

XML API에서는 버킷의 모든 객체를 공개적으로 읽을 수 있게 설정할 수 없습니다. 대신 gsutil 또는 JSON API를 사용하거나 개별 객체에 ACL을 설정하세요.

버킷의 개별 객체를 공개적으로 액세스 가능하게 설정하려면 버킷의 액세스 제어 모드를 세분화로 전환해야 합니다. 일반적으로 버킷의 모든 파일을 액세스 가능하게 설정하는 것이 더 쉽고 빠릅니다.

방문자가 비공개 파일이나 존재하지 않는 파일의 URL을 요청하면 http 403 응답 코드를 받습니다. http 404 응답 코드를 사용하는 오류 페이지를 추가하는 방법에 대한 자세한 내용은 다음 섹션을 참조하세요.

권장사항: 특수 페이지 할당

MainPageSuffix 속성으로 제어되는 색인 페이지 서픽스와 NotFoundPage 속성으로 제어되는 커스텀 오류 페이지를 할당할 수 있습니다. 이 중 원하는 한 가지를 할당할 수 있지만 색인 페이지가 없을 경우에는 사용자가 https://www.example.com과 같은 최상위 사이트에 액세스할 때 아무것도 제공되지 않습니다. MainPageSuffixNotFoundPage 속성에 대한 자세한 내용은 특수 페이지를 참조하세요.

다음 샘플에서 MainPageSuffixindex.html로 설정되고 NotFoundPage404.html로 설정됩니다.

Console

  1. Google Cloud Console에서 Cloud Storage 브라우저를 엽니다.
    Cloud Storage 브라우저 열기
  2. 버킷 목록에서 앞서 만든 버킷을 찾습니다.

  3. 버킷과 연관된 버킷 오버플로 메뉴()를 클릭하고 웹사이트 구성 수정을 선택합니다.

  4. 웹사이트 구성 대화상자에서 기본 페이지와 오류 페이지를 지정합니다.

  5. 저장을 클릭합니다.

Cloud Storage 브라우저에서 실패한 작업에 대한 자세한 오류 정보를 가져오는 방법은 문제해결을 참조하세요.

gsutil

gsutil web set 명령어를 사용하여 -m 플래그가 지정된 MainPageSuffix 속성과 -e 플래그가 지정된 NotFoundPage 속성을 설정합니다.

gsutil web set -m index.html -e 404.html gs://www.example.com

성공하면 명령어가 다음을 반환합니다.

Setting website config on gs://www.example.com/...

코드 샘플

C++

자세한 내용은 Cloud Storage C++ API 참조 문서를 확인하세요.

namespace gcs = google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name,
   std::string const& main_page_suffix, std::string const& not_found_page) {
  StatusOr<gcs::BucketMetadata> original =
      client.GetBucketMetadata(bucket_name);

  if (!original) throw std::runtime_error(original.status().message());
  StatusOr<gcs::BucketMetadata> patched_metadata = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetWebsite(
          gcs::BucketWebsite{main_page_suffix, not_found_page}),
      gcs::IfMetagenerationMatch(original->metageneration()));

  if (!patched_metadata) {
    throw std::runtime_error(patched_metadata.status().message());
  }

  if (!patched_metadata->has_website()) {
    std::cout << "Static website configuration is not set for bucket "
              << patched_metadata->name() << "\n";
    return;
  }

  std::cout << "Static website configuration successfully set for bucket "
            << patched_metadata->name() << "\nNew main page suffix is: "
            << patched_metadata->website().main_page_suffix
            << "\nNew not found page is: "
            << patched_metadata->website().not_found_page << "\n";
}

자바

자세한 내용은 Cloud Storage 자바 API 참조 문서를 확인하세요.

import com.google.cloud.storage.Bucket;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;

public class SetBucketWebsiteInfo {
  public static void setBucketWesbiteInfo(
      String projectId, String bucketName, String indexPage, String notFoundPage) {
    // The ID of your GCP project
    // String projectId = "your-project-id";

    // The ID of your static website bucket
    // String bucketName = "www.example.com";

    // The index page for a static website bucket
    // String indexPage = "index.html";

    // The 404 page for a static website bucket
    // String notFoundPage = "404.html";

    Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
    Bucket bucket = storage.get(bucketName);
    bucket.toBuilder().setIndexPage(indexPage).setNotFoundPage(notFoundPage).build().update();

    System.out.println(
        "Static website bucket "
            + bucketName
            + " is set up to use "
            + indexPage
            + " as the index page and "
            + notFoundPage
            + " as the 404 page");
  }
}

Python

자세한 내용은 Cloud Storage Python API 참조 문서를 확인하세요.

from google.cloud import storage

def define_bucket_website_configuration(bucket_name, main_page_suffix, not_found_page):
    """Configure website-related properties of bucket"""
    # bucket_name = "your-bucket-name"
    # main_page_suffix = "index.html"
    # not_found_page = "404.html"

    storage_client = storage.Client()

    bucket = storage_client.get_bucket(bucket_name)
    bucket.configure_website(main_page_suffix, not_found_page)
    bucket.patch()

    print(
        "Static website bucket {} is set up to use {} as the index page and {} as the 404 page".format(
            bucket.name, main_page_suffix, not_found_page
        )
    )
    return bucket

REST API

JSON API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. website 객체에서 mainPageSuffixnotFoundPage 속성을 원하는 페이지로 설정하는 .json 파일을 만듭니다.

    {
      "website":{
        "mainPageSuffix": "index.html",
        "notFoundPage": "404.html"
      }
    }
  3. cURL을 사용하여 PATCH 버킷 요청으로 JSON API를 호출합니다. www.example.com의 경우는 다음과 같습니다.

    curl -X PATCH --data-binary @web-config.json \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/www.example.com"

XML API

  1. OAuth 2.0 Playground에서 승인 액세스 토큰을 가져옵니다. 자체 OAuth 사용자 인증 정보를 사용하도록 플레이그라운드를 구성합니다.
  2. WebsiteConfiguration 요소에서 MainPageSuffixNotFoundPage 요소를 원하는 페이지로 설정하는 .xml 파일을 만듭니다.

    <WebsiteConfiguration>
      <MainPageSuffix>index.html</MainPageSuffix>
      <NotFoundPage>404.html</NotFoundPage>
    </WebsiteConfiguration>
  3. cURL을 사용하여 PUT 버킷 요청 및 websiteConfig 쿼리 문자열 매개변수로 XML API를 호출합니다. www.example.com의 경우는 다음과 같습니다.

    curl -X PUT --data-binary @web-config.xml \
      -H "Authorization: Bearer ya29.AHES6ZRVmB7fkLtd1XTmq6mo0S1wqZZi3-Lh_s-6Uw7p8vtgSwg" \
      https://storage.googleapis.com/www.example.com?websiteConfig

부하 분산기 및 SSL 인증서 설정

Cloud Storage는 자체적으로 HTTPS 커스텀 도메인을 지원하지 않으므로 HTTPS를 통해 웹사이트를 제공하려면 HTTPS 부하 분산기에 연결된 SSL 인증서를 설정해야 합니다. 이 섹션에서는 부하 분산기의 백엔드에 버킷을 추가하는 방법과 부하 분산기의 프런트엔드에 새 Google 관리 SSL 인증서를 추가하는 방법을 보여줍니다.

  1. Google Cloud Console의 부하 분산 페이지로 이동합니다.
    부하 분산 페이지로 이동
  2. HTTP(S) 부하 분산에서 구성 시작을 클릭합니다.
  3. 인터넷에서 내 VM으로를 선택하고 계속을 클릭합니다.
  4. 부하 분산기에 example-lb와 같은 이름을 지정합니다.

백엔드 구성

  1. 백엔드 구성을 클릭합니다.
  2. 백엔드 서비스 및 백엔드 버킷 만들기 또는 선택 드롭다운에서 백엔드 버킷 하위 메뉴로 이동하고 백엔드 버킷 만들기 옵션을 클릭합니다.
  3. 백엔드 버킷의 이름(예: example-bucket)을 선택합니다.
  4. Cloud Storage 버킷에서 찾아보기를 클릭합니다.
  5. www.example.com 버킷을 선택하고 선택을 클릭합니다.
  6. 만들기를 클릭합니다.

호스트 규칙 및 경로 일치자 구성

호스트 규칙 및 경로 일치자는 외부 HTTP(S) 부하 분산기의 URL 맵 구성요소입니다.

  1. 호스트 및 경로 규칙을 클릭합니다.
  2. 모드는 이전에 만든 백엔드 버킷 example-bucket의 기본 단순 호스트 및 경로 규칙 그대로 둡니다.

프런트엔드 구성

이 섹션에서는 HTTPS 프로토콜을 구성하고 SSL 인증서를 만드는 방법을 보여줍니다. 기존 인증서를 선택하거나 자체 관리형 SSL 인증서를 업로드할 수도 있습니다.

  1. 프런트엔드 구성을 클릭합니다.
  2. 다음 필드의 값을 구성합니다.

  3. IP 주소 필드의 경우:

    1. 드롭다운에서 IP 주소 만들기를 클릭합니다.
    2. 새 고정 IP 주소 예약 팝업에서 IP 주소의 이름example-ip를 입력합니다.
    3. 예약을 클릭합니다.
  4. 포트에서 443을 선택합니다.

  5. 인증서 필드에서 새 인증서 만들기를 선택합니다. 인증서 생성 양식이 패널에 나타납니다. 다음과 같이 구성합니다.

    • 이름: example-ssl
    • 생성 모드: Google 관리 인증서 만들기
    • 도메인: www.example.com. 루트 도메인 example.com과 같은 추가 도메인을 통해 콘텐츠를 제공하려면 Enter를 눌러 추가 행에 추가합니다. 각 인증서의 도메인 한도는 100개입니다.
  6. 만들기를 클릭합니다.

  7. 완료를 클릭합니다.

구성 검토

  1. 검토 및 완료를 클릭합니다.
  2. 백엔드 구성, 호스트 및 경로 규칙, 프런트엔드 구성을 검토합니다.
  3. 만들기를 클릭합니다.

부하 분산기가 생성될 때까지 몇 분 정도 기다려야 할 수 있습니다.

부하 분산기에 도메인 연결

부하 분산기를 만든 후 부하 분산기의 이름 example-lb를 클릭합니다. 부하 분산기에 연결된 IP 주소(예: 30.90.80.100)를 확인합니다. 도메인이 부하 분산기를 가리키도록 하려면 도메인 등록 서비스를 사용하여 A 레코드를 만듭니다. SSL 인증서에 여러 도메인을 추가했다면 모두 부하 분산기의 IP 주소를 가리키는 A 레코드를 도메인마다 추가해야 합니다. 예를 들어 www.example.comexample.comA 레코드를 만들려면 다음 안내를 따르세요.

NAME                  TYPE     DATA
www                   A        30.90.80.100
@                     A        30.90.80.100

Google Domains를 사용하는 경우 자세한 내용은 A 또는 CNAME 레코드 만들기를 참조하세요.

Google Cloud에서 인증서를 프로비저닝하고 부하 분산기를 통해 사이트를 사용할 수 있게 되려면 최대 60~90분이 걸릴 수 있습니다. 인증서 상태를 모니터링하려면 다음 단계를 따르세요.

Console

  1. Google Cloud Console의 부하 분산 페이지로 이동합니다.
    부하 분산 페이지로 이동
  2. 부하 분산기의 이름 example-lb를 클릭합니다.
  3. 부하 분산기에 연결된 SSL 인증서의 이름 example-ssl을 클릭합니다.
  4. 상태도메인 상태 행에 인증서 상태가 표시됩니다. 인증서가 웹사이트에 유효하려면 두 가지 모두 활성 상태여야 합니다.

gcloud

  1. 인증서 상태를 확인하려면 다음 명령어를 실행하세요.

    gcloud beta compute ssl-certificates describe certificate-name \
      --global \
      --format="get(name,managed.status)"
    
  2. 도메인 상태를 확인하려면 다음 명령어를 실행하세요.

    gcloud beta compute ssl-certificates describe certificate-name \
      --global \
      --format="get(managed.domainStatus)"
    

인증서 상태에 대한 자세한 내용은 SSL 인증서 문제해결을 참조하세요.

웹사이트 테스트

SSL 인증서가 활성화되면 https://www.example.com/test.html로 이동하여 콘텐츠가 버킷에서 제공되는지 확인합니다. 여기서 test.htmlwww.example.com이라는 버킷에 저장된 객체입니다. MainPageSuffix 속성을 설정하면 https://www.example.comindex.html로 이동합니다.

삭제

정적 웹사이트 호스팅 가이드를 완료했으면 Google Cloud에서 만든 리소스가 할당량을 소모하여 이후에 요금이 청구되지 않도록 이 리소스를 삭제할 수 있습니다. 다음 섹션에서는 리소스를 삭제하거나 사용 중지하는 방법을 설명합니다.

프로젝트 삭제

비용이 청구되지 않도록 하는 가장 쉬운 방법은 가이드에서 만든 프로젝트를 삭제하는 것입니다.

프로젝트를 삭제하려면 다음 안내를 따르세요.

  1. Cloud Console에서 리소스 관리 페이지로 이동합니다.

    리소스 관리 페이지로 이동

  2. 프로젝트 목록에서 삭제할 프로젝트를 선택하고 삭제 를 클릭합니다.
  3. 대화상자에서 프로젝트 ID를 입력한 다음 종료를 클릭하여 프로젝트를 삭제합니다.

부하 분산기 및 버킷 삭제

전체 프로젝트를 삭제하지 않으려면 가이드를 위해 만든 부하 분산기와 버킷을 삭제합니다.

  1. Google Cloud Console의 부하 분산 페이지로 이동합니다.
    부하 분산 페이지로 이동
  2. example-lb 옆의 체크박스를 선택합니다.
  3. 삭제를 클릭합니다.
  4. (선택사항) www.example.com 버킷 또는 example-ssl SSL 인증서와 같이 부하 분산기와 함께 삭제할 리소스 옆의 체크박스를 선택합니다.
  5. 부하 분산기 삭제 또는 부하 분산기 및 선택한 리소스 삭제를 클릭합니다.

다음 단계