정적 웹사이트 호스팅


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

Cloud Storage는 자체적으로 HTTPS 커스텀 도메인을 지원하지 않으므로 이 튜토리얼에서는 Cloud Storage를 외부 애플리케이션 부하 분산기와 함께 사용하여 HTTPS를 통해 커스텀 도메인에서 콘텐츠를 제공합니다. HTTPS를 통해 커스텀 도메인에서 콘텐츠를 제공하는 다른 방법은 HTTPS 제공 문제 해결을 참조하세요. Cloud Storage를 사용하여 부하 분산기가 필요 없는 HTTP를 통해 커스텀 도메인 콘텐츠를 제공할 수도 있습니다.

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

목표

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

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

비용

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

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

시작하기 전에

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 프로젝트에 Compute Engine API를 사용 설정합니다.
  7. 스토리지 관리자컴퓨팅 네트워크 관리자라는 Identity and Access Management 역할이 있습니다.
  8. 자신이 소유하거나 관리하는 도메인이 있어야 합니다. 기존 도메인이 없는 경우 Cloud Domains와 같은 다양한 서비스를 사용하여 새 도메인을 등록할 수 있습니다.

    이 튜토리얼은 example.com 도메인을 사용합니다.

  9. 제공할 웹사이트 파일이 있어야 합니다. 이 튜토리얼은 최소 색인 페이지(index.html)와 404 페이지(404.html)가 있는 경우에 가장 효과적입니다.
  10. 제공하려는 파일을 저장할 Cloud Storage 버킷이 있어야 합니다. 현재 버킷이 없는 경우 버킷을 만듭니다.
  11. (선택사항) Cloud Storage 버킷이 도메인과 동일한 이름을 사용하도록 하려면 사용할 도메인을 소유 또는 관리하고 있는지 확인해야 합니다. www.example.com과 같은 하위 도메인이 아니라 example.com과 같은 최상위 도메인을 확인해야 합니다. Cloud Domains를 통해 도메인을 구매한 경우 자동으로 확인이 수행됩니다.

사이트 파일 업로드

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

콘솔

  1. Google Cloud 콘솔에서 Cloud Storage 버킷 페이지로 이동합니다.

    버킷으로 이동

  2. 버킷 목록에서 앞서 만든 버킷의 이름을 클릭합니다.

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

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

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

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

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

명령줄

gcloud storage cp 명령어를 사용하여 파일을 버킷으로 복사합니다. 예를 들어 index.html 파일을 현재 위치 Desktop에서 my-static-assets 버킷으로 복사하려면 다음 명령어를 실행합니다.

gcloud storage cp Desktop/index.html gs://my-static-assets

성공하면 응답은 다음 예시와 같습니다.

Completed files 1/1 | 164.3kiB/164.3kiB

클라이언트 라이브러리

C++

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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::move(metadata).status();

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

C#

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using Google.Cloud.Storage.V1;
using System;
using System.IO;

public class UploadFileSample
{
    public void UploadFile(
        string bucketName = "your-unique-bucket-name",
        string localPath = "my-local-path/my-file-name",
        string objectName = "my-file-name")
    {
        var storage = StorageClient.Create();
        using var fileStream = File.OpenRead(localPath);
        storage.UploadObject(bucketName, objectName, null, fileStream);
        Console.WriteLine($"Uploaded {objectName}.");
    }
}

Go

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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: %w", err)
	}
	defer client.Close()

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

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

	o := client.Bucket(bucket).Object(object)

	// Optional: set a generation-match precondition to avoid potential race
	// conditions and data corruptions. The request to upload is aborted if the
	// object's generation number does not match your precondition.
	// For an object that does not yet exist, set the DoesNotExist precondition.
	o = o.If(storage.Conditions{DoesNotExist: true})
	// If the live object already exists in your bucket, set instead a
	// generation-match precondition using the live object's generation number.
	// attrs, err := o.Attrs(ctx)
	// if err != nil {
	// 	return fmt.Errorf("object.Attrs: %w", err)
	// }
	// o = o.If(storage.Conditions{GenerationMatch: attrs.Generation})

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

Java

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

다음 샘플은 개별 객체를 업로드합니다.


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.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();

    // Optional: set a generation-match precondition to avoid potential race
    // conditions and data corruptions. The request returns a 412 error if the
    // preconditions are not met.
    Storage.BlobWriteOption precondition;
    if (storage.get(bucketName, objectName) == null) {
      // For a target object that does not yet exist, set the DoesNotExist precondition.
      // This will cause the request to fail if the object is created before the request runs.
      precondition = Storage.BlobWriteOption.doesNotExist();
    } else {
      // If the destination already exists in your bucket, instead set a generation-match
      // precondition. This will cause the request to fail if the existing object's generation
      // changes before the request runs.
      precondition =
          Storage.BlobWriteOption.generationMatch(
              storage.get(bucketName, objectName).getGeneration());
    }
    storage.createFrom(blobInfo, Paths.get(filePath), precondition);

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

다음 샘플은 객체 여러 개를 동시에 업로드합니다.

import com.google.cloud.storage.transfermanager.ParallelUploadConfig;
import com.google.cloud.storage.transfermanager.TransferManager;
import com.google.cloud.storage.transfermanager.TransferManagerConfig;
import com.google.cloud.storage.transfermanager.UploadResult;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;

class UploadMany {

  public static void uploadManyFiles(String bucketName, List<Path> files) throws IOException {
    TransferManager transferManager = TransferManagerConfig.newBuilder().build().getService();
    ParallelUploadConfig parallelUploadConfig =
        ParallelUploadConfig.newBuilder().setBucketName(bucketName).build();
    List<UploadResult> results =
        transferManager.uploadFiles(files, parallelUploadConfig).getUploadResults();
    for (UploadResult result : results) {
      System.out.println(
          "Upload for "
              + result.getInput().getName()
              + " completed with status "
              + result.getStatus());
    }
  }
}

다음 샘플에서는 공통 프리픽스가 있는 모든 객체를 동시에 업로드합니다.

import com.google.cloud.storage.transfermanager.ParallelUploadConfig;
import com.google.cloud.storage.transfermanager.TransferManager;
import com.google.cloud.storage.transfermanager.TransferManagerConfig;
import com.google.cloud.storage.transfermanager.UploadResult;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

class UploadDirectory {

  public static void uploadDirectoryContents(String bucketName, Path sourceDirectory)
      throws IOException {
    TransferManager transferManager = TransferManagerConfig.newBuilder().build().getService();
    ParallelUploadConfig parallelUploadConfig =
        ParallelUploadConfig.newBuilder().setBucketName(bucketName).build();

    // Create a list to store the file paths
    List<Path> filePaths = new ArrayList<>();
    // Get all files in the directory
    // try-with-resource to ensure pathStream is closed
    try (Stream<Path> pathStream = Files.walk(sourceDirectory)) {
      pathStream.filter(Files::isRegularFile).forEach(filePaths::add);
    }
    List<UploadResult> results =
        transferManager.uploadFiles(filePaths, parallelUploadConfig).getUploadResults();
    for (UploadResult result : results) {
      System.out.println(
          "Upload for "
              + result.getInput().getName()
              + " completed with status "
              + result.getStatus());
    }
  }
}

Node.js

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

다음 샘플은 개별 객체를 업로드합니다.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The path to your file to upload
// const filePath = 'path/to/your/file';

// The new ID for your GCS file
// const destFileName = 'your-new-file-name';

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

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

async function uploadFile() {
  const options = {
    destination: destFileName,
    // Optional:
    // Set a generation-match precondition to avoid potential race conditions
    // and data corruptions. The request to upload is aborted if the object's
    // generation number does not match your precondition. For a destination
    // object that does not yet exist, set the ifGenerationMatch precondition to 0
    // If the destination object already exists in your bucket, set instead a
    // generation-match precondition using its generation number.
    preconditionOpts: {ifGenerationMatch: generationMatchPrecondition},
  };

  await storage.bucket(bucketName).upload(filePath, options);
  console.log(`${filePath} uploaded to ${bucketName}`);
}

uploadFile().catch(console.error);

다음 샘플은 객체 여러 개를 동시에 업로드합니다.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The ID of the first GCS file to download
// const firstFilePath = 'your-first-file-name';

// The ID of the second GCS file to download
// const secondFilePath = 'your-second-file-name';

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

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

// Creates a transfer manager client
const transferManager = new TransferManager(storage.bucket(bucketName));

async function uploadManyFilesWithTransferManager() {
  // Uploads the files
  await transferManager.uploadManyFiles([firstFilePath, secondFilePath]);

  for (const filePath of [firstFilePath, secondFilePath]) {
    console.log(`${filePath} uploaded to ${bucketName}.`);
  }
}

uploadManyFilesWithTransferManager().catch(console.error);

다음 샘플에서는 공통 프리픽스가 있는 모든 객체를 동시에 업로드합니다.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The local directory to upload
// const directoryName = 'your-directory';

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

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

// Creates a transfer manager client
const transferManager = new TransferManager(storage.bucket(bucketName));

async function uploadDirectoryWithTransferManager() {
  // Uploads the directory
  await transferManager.uploadManyFiles(directoryName);

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

uploadDirectoryWithTransferManager().catch(console.error);

PHP

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Storage\StorageClient;

/**
 * Upload a file.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $objectName The name of your Cloud Storage object.
 *        (e.g. 'my-object')
 * @param string $source The path to the file to upload.
 *        (e.g. '/path/to/your/file')
 */
function upload_object(string $bucketName, string $objectName, string $source): void
{
    $storage = new StorageClient();
    if (!$file = fopen($source, 'r')) {
        throw new \InvalidArgumentException('Unable to open file for reading');
    }
    $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 참고 문서를 확인하세요.

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

다음 샘플은 개별 객체를 업로드합니다.

from google.cloud import storage


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

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

    # Optional: set a generation-match precondition to avoid potential race conditions
    # and data corruptions. The request to upload is aborted if the object's
    # generation number does not match your precondition. For a destination
    # object that does not yet exist, set the if_generation_match precondition to 0.
    # If the destination object already exists in your bucket, set instead a
    # generation-match precondition using its generation number.
    generation_match_precondition = 0

    blob.upload_from_filename(source_file_name, if_generation_match=generation_match_precondition)

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

다음 샘플은 객체 여러 개를 동시에 업로드합니다.

def upload_many_blobs_with_transfer_manager(
    bucket_name, filenames, source_directory="", workers=8
):
    """Upload every file in a list to a bucket, concurrently in a process pool.

    Each blob name is derived from the filename, not including the
    `source_directory` parameter. For complete control of the blob name for each
    file (and other aspects of individual blob metadata), use
    transfer_manager.upload_many() instead.
    """

    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"

    # A list (or other iterable) of filenames to upload.
    # filenames = ["file_1.txt", "file_2.txt"]

    # The directory on your computer that is the root of all of the files in the
    # list of filenames. This string is prepended (with os.path.join()) to each
    # filename to get the full path to the file. Relative paths and absolute
    # paths are both accepted. This string is not included in the name of the
    # uploaded blob; it is only used to find the source files. An empty string
    # means "the current working directory". Note that this parameter allows
    # directory traversal (e.g. "/", "../") and is not intended for unsanitized
    # end user input.
    # source_directory=""

    # The maximum number of processes to use for the operation. The performance
    # impact of this value depends on the use case, but smaller files usually
    # benefit from a higher number of processes. Each additional process occupies
    # some CPU and memory resources until finished. Threads can be used instead
    # of processes by passing `worker_type=transfer_manager.THREAD`.
    # workers=8

    from google.cloud.storage import Client, transfer_manager

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

    results = transfer_manager.upload_many_from_filenames(
        bucket, filenames, source_directory=source_directory, max_workers=workers
    )

    for name, result in zip(filenames, results):
        # The results list is either `None` or an exception for each filename in
        # the input list, in order.

        if isinstance(result, Exception):
            print("Failed to upload {} due to exception: {}".format(name, result))
        else:
            print("Uploaded {} to {}.".format(name, bucket.name))

다음 샘플에서는 공통 프리픽스가 있는 모든 객체를 동시에 업로드합니다.

def upload_directory_with_transfer_manager(bucket_name, source_directory, workers=8):
    """Upload every file in a directory, including all files in subdirectories.

    Each blob name is derived from the filename, not including the `directory`
    parameter itself. For complete control of the blob name for each file (and
    other aspects of individual blob metadata), use
    transfer_manager.upload_many() instead.
    """

    # The ID of your GCS bucket
    # bucket_name = "your-bucket-name"

    # The directory on your computer to upload. Files in the directory and its
    # subdirectories will be uploaded. An empty string means "the current
    # working directory".
    # source_directory=""

    # The maximum number of processes to use for the operation. The performance
    # impact of this value depends on the use case, but smaller files usually
    # benefit from a higher number of processes. Each additional process occupies
    # some CPU and memory resources until finished. Threads can be used instead
    # of processes by passing `worker_type=transfer_manager.THREAD`.
    # workers=8

    from pathlib import Path

    from google.cloud.storage import Client, transfer_manager

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

    # Generate a list of paths (in string form) relative to the `directory`.
    # This can be done in a single list comprehension, but is expanded into
    # multiple lines here for clarity.

    # First, recursively get all files in `directory` as Path objects.
    directory_as_path_obj = Path(source_directory)
    paths = directory_as_path_obj.rglob("*")

    # Filter so the list only includes files, not directories themselves.
    file_paths = [path for path in paths if path.is_file()]

    # These paths are relative to the current working directory. Next, make them
    # relative to `directory`
    relative_paths = [path.relative_to(source_directory) for path in file_paths]

    # Finally, convert them all to strings.
    string_paths = [str(path) for path in relative_paths]

    print("Found {} files.".format(len(string_paths)))

    # Start the upload.
    results = transfer_manager.upload_many_from_filenames(
        bucket, string_paths, source_directory=source_directory, max_workers=workers
    )

    for name, result in zip(string_paths, results):
        # The results list is either `None` or an exception for each filename in
        # the input list, in order.

        if isinstance(result, Exception):
            print("Failed to upload {} due to exception: {}".format(name, result))
        else:
            print("Uploaded {} to {}.".format(name, bucket.name))

Ruby

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

def upload_file bucket_name:, local_file_path:, file_name: nil
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  # The path to your file to upload
  # local_file_path = "/local/path/to/file.txt"

  # The ID of your GCS object
  # file_name = "your-file-name"

  require "google/cloud/storage"

  storage = Google::Cloud::Storage.new
  bucket  = storage.bucket bucket_name, skip_lookup: true

  file = bucket.create_file local_file_path, file_name

  puts "Uploaded #{local_file_path} as #{file.name} in bucket #{bucket_name}"
end

Terraform

# Upload a simple index.html page to the bucket
resource "google_storage_bucket_object" "indexpage" {
  name         = "index.html"
  content      = "<html><body>Hello World!</body></html>"
  content_type = "text/html"
  bucket       = google_storage_bucket.static_website.id
}

# Upload a simple 404 / error page to the bucket
resource "google_storage_bucket_object" "errorpage" {
  name         = "404.html"
  content      = "<html><body>404!</body></html>"
  content_type = "text/html"
  bucket       = google_storage_bucket.static_website.id
}

REST API

JSON API

  1. Authorization 헤더에 대한 액세스 토큰을 생성하려면 gcloud CLI가 설치 및 초기화되어 있어야 합니다.

    또는 OAuth 2.0 Playground를 사용하여 액세스 토큰을 만들고 Authorization 헤더에 포함할 수 있습니다.

  2. cURL을 사용하여 POST 객체 요청으로 JSON API를 호출합니다. index.html 파일을 my-static-assets라는 버킷에 업로드한 경우:

    curl -X POST --data-binary @index.html \
      -H "Content-Type: text/html" \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      "https://storage.googleapis.com/upload/storage/v1/b/my-static-assets/o?uploadType=media&name=index.html"

XML API

  1. Authorization 헤더에 대한 액세스 토큰을 생성하려면 gcloud CLI가 설치 및 초기화되어 있어야 합니다.

    또는 OAuth 2.0 Playground를 사용하여 액세스 토큰을 만들고 Authorization 헤더에 포함할 수 있습니다.

  2. cURL을 사용하여 PUT 객체 요청으로 XML API를 호출합니다. index.html 파일을 my-static-assets라는 버킷에 업로드한 경우:

    curl -X PUT --data-binary @index.html \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: text/html" \
      "https://storage.googleapis.com/my-static-assets/index.html"

파일 공유

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

콘솔

  1. Google Cloud 콘솔에서 Cloud Storage 버킷 페이지로 이동합니다.

    버킷으로 이동

  2. 버킷 목록에서 공개하려는 버킷의 이름을 클릭합니다.

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

  4. 공개 액세스 창에 공개 아님이 표시되면 공개 액세스 방지 삭제 버튼을 클릭하고 대화상자가 나타나면 확인을 클릭합니다.

  5. 액세스 권한 부여 버튼을 클릭합니다.

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

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

  7. 역할 선택 드롭다운에서 Cloud Storage 하위 메뉴를 선택하고 스토리지 객체 뷰어 옵션을 클릭합니다.

  8. 저장을 클릭합니다.

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

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

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

명령줄

buckets add-iam-policy-binding 명령어를 사용합니다.

gcloud storage buckets add-iam-policy-binding  gs://my-static-assets --member=allUsers --role=roles/storage.objectViewer

클라이언트 라이브러리

C++

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

namespace gcs = ::google::cloud::storage;
using ::google::cloud::StatusOr;
[](gcs::Client client, std::string const& bucket_name) {
  auto current_policy = client.GetNativeBucketIamPolicy(
      bucket_name, gcs::RequestedPolicyVersion(3));
  if (!current_policy) throw std::move(current_policy).status();

  current_policy->set_version(3);
  current_policy->bindings().emplace_back(
      gcs::NativeIamBinding("roles/storage.objectViewer", {"allUsers"}));

  auto updated =
      client.SetNativeBucketIamPolicy(bucket_name, *current_policy);
  if (!updated) throw std::move(updated).status();

  std::cout << "Policy successfully updated: " << *updated << "\n";
}

C#

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;
using System.Collections.Generic;

public class MakeBucketPublicSample
{
    public void MakeBucketPublic(string bucketName = "your-unique-bucket-name")
    {
        var storage = StorageClient.Create();

        Policy policy = storage.GetBucketIamPolicy(bucketName);

        policy.Bindings.Add(new Policy.BindingsData
        {
            Role = "roles/storage.objectViewer",
            Members = new List<string> { "allUsers" }
        });

        storage.SetBucketIamPolicy(bucketName, policy);
        Console.WriteLine(bucketName + " is now public ");
    }
}

Go

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

import (
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/iam"
	"cloud.google.com/go/iam/apiv1/iampb"
	"cloud.google.com/go/storage"
)

// setBucketPublicIAM makes all objects in a bucket publicly readable.
func setBucketPublicIAM(w io.Writer, bucketName string) error {
	// bucketName := "bucket-name"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

	policy, err := client.Bucket(bucketName).IAM().V3().Policy(ctx)
	if err != nil {
		return fmt.Errorf("Bucket(%q).IAM().V3().Policy: %w", bucketName, err)
	}
	role := "roles/storage.objectViewer"
	policy.Bindings = append(policy.Bindings, &iampb.Binding{
		Role:    role,
		Members: []string{iam.AllUsers},
	})
	if err := client.Bucket(bucketName).IAM().V3().SetPolicy(ctx, policy); err != nil {
		return fmt.Errorf("Bucket(%q).IAM().SetPolicy: %w", bucketName, err)
	}
	fmt.Fprintf(w, "Bucket %v is now publicly readable\n", bucketName)
	return nil
}

Java

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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");
  }
}

Node.js

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

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

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

async function makeBucketPublic() {
  await storage.bucket(bucketName).makePublic();

  console.log(`Bucket ${bucketName} is now publicly readable`);
}

makeBucketPublic().catch(console.error);

PHP

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Storage\StorageClient;

/**
 * Update the specified bucket's IAM configuration to make it publicly accessible.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 */
function set_bucket_public_iam(string $bucketName): void
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);

    $policy = $bucket->iam()->policy(['requestedPolicyVersion' => 3]);
    $policy['version'] = 3;

    $role = 'roles/storage.objectViewer';
    $members = ['allUsers'];

    $policy['bindings'][] = [
        'role' => $role,
        'members' => $members
    ];

    $bucket->iam()->setPolicy($policy);

    printf('Bucket %s is now public', $bucketName);
}

Python

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

from typing import List

from google.cloud import storage


def set_bucket_public_iam(
    bucket_name: str = "your-bucket-name",
    members: List[str] = ["allUsers"],
):
    """Set a public IAM Policy to bucket"""
    # bucket_name = "your-bucket-name"

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

    policy = bucket.get_iam_policy(requested_policy_version=3)
    policy.bindings.append(
        {"role": "roles/storage.objectViewer", "members": members}
    )

    bucket.set_iam_policy(policy)

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

Ruby

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

def set_bucket_public_iam bucket_name:
  # The ID of your GCS bucket
  # bucket_name = "your-unique-bucket-name"

  require "google/cloud/storage"

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

  bucket.policy do |p|
    p.add "roles/storage.objectViewer", "allUsers"
  end

  puts "Bucket #{bucket_name} is now publicly readable"
end

Terraform

# Make bucket public by granting allUsers storage.objectViewer access
resource "google_storage_bucket_iam_member" "public_rule" {
  bucket = google_storage_bucket.static_website.name
  role   = "roles/storage.objectViewer"
  member = "allUsers"
}

REST API

JSON API

  1. Authorization 헤더에 대한 액세스 토큰을 생성하려면 gcloud CLI가 설치 및 초기화되어 있어야 합니다.

    또는 OAuth 2.0 Playground를 사용하여 액세스 토큰을 만들고 Authorization 헤더에 포함할 수 있습니다.

  2. 다음 정보를 포함하는 JSON 파일을 만듭니다.

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

    curl -X PUT --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME/iam"

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

    • JSON_FILE_NAME은 2단계에서 만든 JSON 파일의 경로입니다.
    • BUCKET_NAME은 객체를 공개할 버킷의 이름입니다. 예를 들면 my-static-assets입니다.

XML API

XML API에서는 버킷의 모든 객체를 공개적으로 읽을 수 있게 설정할 수 없습니다. 대신 Google Cloud 콘솔 또는 gcloud storage를 사용하거나 개별 객체에 ACL을 설정합니다. 개별 객체별로 ACL을 설정하려면 버킷의 액세스 제어 모드를 세분화로 전환해야 합니다.

원하는 경우 버킷의 일부를 공개적으로 액세스 가능하게 설정할 수도 있습니다.

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

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

색인 페이지 서픽스와 특수 페이지라고 하는 커스텀 오류 페이지를 할당할 수 있습니다. 이 중 원하는 한 가지를 할당할 수 있지만 색인 페이지 서픽스를 할당하지 않고 해당 색인 페이지를 업로드하지 않으면 최상위 사이트에 액세스하는 사용자에게 버킷의 공개 객체 목록이 포함된 XML 문서 트리가 제공됩니다.

특수 페이지 동작에 대한 자세한 내용은 특수 페이지를 참조하세요.

콘솔

  1. Google Cloud 콘솔에서 Cloud Storage 버킷 페이지로 이동합니다.

    버킷으로 이동

  2. 버킷 목록에서 앞서 만든 버킷을 찾습니다.

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

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

  5. 저장을 클릭합니다.

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

명령줄

buckets update 명령어를 --web-main-page-suffix--web-error-page 플래그와 함께 사용합니다.

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

gcloud storage buckets update gs://my-static-assets --web-main-page-suffix=index.html --web-error-page=404.html

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

Updating gs://www.example.com/...
  Completed 1

클라이언트 라이브러리

C++

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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::move(original).status();
  StatusOr<gcs::BucketMetadata> patched = client.PatchBucket(
      bucket_name,
      gcs::BucketMetadataPatchBuilder().SetWebsite(
          gcs::BucketWebsite{main_page_suffix, not_found_page}),
      gcs::IfMetagenerationMatch(original->metageneration()));
  if (!patched) throw std::move(patched).status();

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

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

C#

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.


using Google.Apis.Storage.v1.Data;
using Google.Cloud.Storage.V1;
using System;

public class BucketWebsiteConfigurationSample
{
    public Bucket BucketWebsiteConfiguration(
        string bucketName = "your-bucket-name",
        string mainPageSuffix = "index.html",
        string notFoundPage = "404.html")
    {
        var storage = StorageClient.Create();
        var bucket = storage.GetBucket(bucketName);

        if (bucket.Website == null)
        {
            bucket.Website = new Bucket.WebsiteData();
        }
        bucket.Website.MainPageSuffix = mainPageSuffix;
        bucket.Website.NotFoundPage = notFoundPage;

        bucket = storage.UpdateBucket(bucket);
        Console.WriteLine($"Static website bucket {bucketName} is set up to use {mainPageSuffix} as the index page and {notFoundPage} as the 404 not found page.");
        return bucket;
    }
}

Go

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

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

// setBucketWebsiteInfo sets website configuration on a bucket.
func setBucketWebsiteInfo(w io.Writer, bucketName, indexPage, notFoundPage string) error {
	// bucketName := "www.example.com"
	// indexPage := "index.html"
	// notFoundPage := "404.html"
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %w", err)
	}
	defer client.Close()

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

	bucket := client.Bucket(bucketName)
	bucketAttrsToUpdate := storage.BucketAttrsToUpdate{
		Website: &storage.BucketWebsite{
			MainPageSuffix: indexPage,
			NotFoundPage:   notFoundPage,
		},
	}
	if _, err := bucket.Update(ctx, bucketAttrsToUpdate); err != nil {
		return fmt.Errorf("Bucket(%q).Update: %w", bucketName, err)
	}
	fmt.Fprintf(w, "Static website bucket %v is set up to use %v as the index page and %v as the 404 page\n", bucketName, indexPage, notFoundPage)
	return nil
}

Java

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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");
  }
}

Node.js

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// The ID of your GCS bucket
// const bucketName = 'your-unique-bucket-name';

// The name of the main page
// const mainPageSuffix = 'http://example.com';

// The Name of a 404 page
// const notFoundPage = 'http://example.com/404.html';

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

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

async function addBucketWebsiteConfiguration() {
  await storage.bucket(bucketName).setMetadata({
    website: {
      mainPageSuffix,
      notFoundPage,
    },
  });

  console.log(
    `Static website bucket ${bucketName} is set up to use ${mainPageSuffix} as the index page and ${notFoundPage} as the 404 page`
  );
}

addBucketWebsiteConfiguration().catch(console.error);

PHP

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

use Google\Cloud\Storage\StorageClient;

/**
 * Update the given bucket's website configuration.
 *
 * @param string $bucketName The name of your Cloud Storage bucket.
 *        (e.g. 'my-bucket')
 * @param string $indexPageObject the name of an object in the bucket to use as
 *        (e.g. 'index.html')
 *     an index page for a static website bucket.
 * @param string $notFoundPageObject the name of an object in the bucket to use
 *        (e.g. '404.html')
 *     as the 404 Not Found page.
 */
function define_bucket_website_configuration(string $bucketName, string $indexPageObject, string $notFoundPageObject): void
{
    $storage = new StorageClient();
    $bucket = $storage->bucket($bucketName);

    $bucket->update([
        'website' => [
            'mainPageSuffix' => $indexPageObject,
            'notFoundPage' => $notFoundPageObject
        ]
    ]);

    printf(
        'Static website bucket %s is set up to use %s as the index page and %s as the 404 page.',
        $bucketName,
        $indexPageObject,
        $notFoundPageObject
    );
}

Python

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

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

Ruby

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

Cloud Storage에 인증하려면 애플리케이션 기본 사용자 인증 정보를 설정합니다. 자세한 내용은 로컬 개발 환경의 인증 설정을 참조하세요.

def define_bucket_website_configuration bucket_name:, main_page_suffix:, not_found_page:
  # The ID of your static website bucket
  # bucket_name = "www.example.com"

  # The index page for a static website bucket
  # main_page_suffix = "index.html"

  # The 404 page for a static website bucket
  # not_found_page = "404.html"

  require "google/cloud/storage"

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

  bucket.update do |b|
    b.website_main = main_page_suffix
    b.website_404 = not_found_page
  end

  puts "Static website bucket #{bucket_name} is set up to use #{main_page_suffix} as the index page and " \
       "#{not_found_page} as the 404 page"
end

REST API

JSON API

  1. Authorization 헤더에 대한 액세스 토큰을 생성하려면 gcloud CLI가 설치 및 초기화되어 있어야 합니다.

    또는 OAuth 2.0 Playground를 사용하여 액세스 토큰을 만들고 Authorization 헤더에 포함할 수 있습니다.

  2. website 객체에서 mainPageSuffixnotFoundPage 속성을 원하는 페이지로 설정하는 JSON 파일을 만듭니다.

    다음 샘플에서 mainPageSuffixindex.html로 설정되고 notFoundPage404.html로 설정됩니다.

    {
      "website":{
        "mainPageSuffix": "index.html",
        "notFoundPage": "404.html"
      }
    }
  3. cURL을 사용하여 PATCH 버킷 요청으로 JSON API를 호출합니다. my-static-assets 버킷의 경우:

    curl -X PATCH --data-binary @web-config.json \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/my-static-assets"

XML API

  1. Authorization 헤더에 대한 액세스 토큰을 생성하려면 gcloud CLI가 설치 및 초기화되어 있어야 합니다.

    또는 OAuth 2.0 Playground를 사용하여 액세스 토큰을 만들고 Authorization 헤더에 포함할 수 있습니다.

  2. WebsiteConfiguration 요소에서 MainPageSuffixNotFoundPage 요소를 원하는 페이지로 설정하는 XML 파일을 만듭니다.

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

    <WebsiteConfiguration>
      <MainPageSuffix>index.html</MainPageSuffix>
      <NotFoundPage>404.html</NotFoundPage>
    </WebsiteConfiguration>
  3. cURL을 사용하여 PUT 버킷 요청 및 websiteConfig 쿼리 문자열 매개변수로 XML API를 호출합니다. my-static-assets의 경우:

    curl -X PUT --data-binary @web-config.xml \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      https://storage.googleapis.com/my-static-assets?websiteConfig

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

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

구성 시작

  1. Google Cloud 콘솔에서 부하 분산 페이지로 이동합니다.

    부하 분산으로 이동

  2. 부하 분산기 만들기를 클릭합니다.
  3. 부하 분산기 유형에서 애플리케이션 부하 분산기(HTTP/HTTPS)를 선택하고 다음을 클릭합니다.
  4. 공개 또는 내부에서 공개(외부)를 선택하고 다음을 클릭합니다.
  5. 전역 또는 단일 리전 배포전역 워크로드에 적합을 선택하고 다음을 클릭합니다.
  6. 부하 분산기 생성기본 애플리케이션 부하 분산기를 선택하고 다음을 클릭합니다.
  7. 구성을 클릭합니다.

부하 분산기의 구성 창이 나타납니다.

기본 구성

구성을 계속하기 전에 부하 분산기 이름(예: example-lb)을 입력합니다.

프런트엔드 구성

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

  1. 프런트엔드 구성을 클릭합니다.
  2. (선택사항) 프런트엔드 구성에 이름을 지정합니다.
  3. 프로토콜에서 HTTPS(HTTP/2 포함)를 선택합니다.
  4. IP 버전에서 IPv4를 선택합니다. IPv6을 선호하는 경우 자세한 내용은 IPv6 종료를 참조하세요.
  5. IP 주소 필드의 경우:

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

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

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

  9. (선택사항) Google Cloud에서 HTTP 트래픽을 리디렉션할 수 있도록 부분 HTTP 부하 분산기를 자동으로 설정하려면 HTTP에서 HTTPS로 리디렉션 사용 설정 옆에 있는 체크박스를 선택합니다.

  10. 완료를 클릭합니다.

백엔드 구성

  1. 백엔드 구성을 클릭합니다.
  2. 백엔드 서비스 및 백엔드 버킷 드롭다운에서 백엔드 버킷 만들기를 클릭합니다.
  3. 백엔드 버킷 이름(예: example-bucket)을 선택합니다. 선택한 이름은 앞에서 만든 버킷의 이름과 다를 수 있습니다.
  4. Cloud Storage 버킷 필드에 있는 찾아보기를 클릭합니다.
  5. 이전에 만든 my-static-assets 버킷을 선택하고 선택을 클릭합니다.
  6. (선택사항) Cloud CDN을 사용하려면 Cloud CDN 사용 설정 체크박스를 선택하고 원하는 대로 Cloud CDN을 구성합니다. Cloud CDN은 추가 비용이 발생할 수 있습니다.
  7. 만들기를 클릭합니다.

라우팅 규칙 구성

라우팅 규칙은 외부 애플리케이션 부하 분산기의 URL 맵 구성요소입니다. 이 튜토리얼에서는 부하 분산기 구성의 이 부분을 건너뛰어야 합니다. 이 구성은 방금 구성한 백엔드를 사용하도록 자동으로 설정되기 때문입니다.

구성 검토

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

콘솔

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

명령줄

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

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

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

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

웹사이트 테스트

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

삭제

튜토리얼을 완료한 후에는 만든 리소스를 삭제하여 할당량 사용을 중지하고 요금이 청구되지 않도록 할 수 있습니다. 다음 섹션은 이러한 리소스를 삭제하거나 사용 중지하는 방법을 설명합니다.

프로젝트 삭제

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

프로젝트를 삭제하는 방법은 다음과 같습니다.

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

부하 분산기 및 버킷 삭제

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

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

예약된 IP 주소 해제

튜토리얼에 사용된 예약된 IP 주소를 삭제하려면 다음 안내를 따르세요.

  1. Google Cloud Console에서 외부 IP 주소 페이지로 이동합니다.

    외부 IP 주소로 이동

  2. example-ip 옆의 체크박스를 선택합니다.

  3. 고정 주소 해제를 클릭합니다.

  4. 확인 창에서 삭제를 클릭합니다.

다음 단계

직접 사용해 보기

Google Cloud를 처음 사용하는 경우 계정을 만들어 실제 시나리오에서 Cloud Storage의 성능을 평가할 수 있습니다. 신규 고객에게는 워크로드를 실행, 테스트, 배포하는 데 사용할 수 있는 $300의 무료 크레딧이 제공됩니다.

Cloud Storage 무료로 사용해 보기