Using Cloud Storage

You can use Cloud Storage to store and serve files, such as movies or images or other static content.

This document describes how to use the Google Cloud Client Library to store and retrieve data using Cloud Storage in an App Engine app.

Prerequisites and setup

Follow the instructions in "Hello, World!" for Go on App Engine to set up your environment and project, and to understand how Go apps are structured in App Engine. Write down and save your project ID, because you will need it to run the sample application described in this document.

Make sure you create a Cloud Storage bucket for your application by invoking the following command:

gsutil mb gs://[your-bucket-name]

And make it publically readable so it can serve files:

gsutil defacl set public-read gs://[your-bucket-name]

Clone the repository

Download the sample:

go get -u -d github.com/GoogleCloudPlatform/golang-samples/appengine_flexible/storage
cd $GOPATH/src/github.com/GoogleCloudPlatform/golang-samples/appengine_flexible/storage

Edit project configuration and install dependencies

In app.yaml, set GCLOUD_STORAGE_BUCKET. This value is the name of the Cloud Storage bucket you created previously.

runtime: go
env: flex

automatic_scaling:
  min_num_instances: 1

#[START env_variables]
env_variables:
  GCLOUD_STORAGE_BUCKET: your-bucket-name
#[END env_variables]

Application code

The sample application presents a web page prompting the user to supply a file to be stored in Cloud Storage. When the user selects a file and clicks submit, the upload handler writes the file to the Cloud Storage bucket using Cloud Storage NewWriter function.

Notice that to retrieve this file from Cloud Storage, you will need to specify the bucket name and the filename. You should store these values in your app for future use.

// Copyright 2015 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

// Sample storage demonstrates use of the cloud.google.com/go/storage package from App Engine flexible environment.
package main

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"os"

	"cloud.google.com/go/storage"

	"google.golang.org/appengine"

	"golang.org/x/net/context"
)

var (
	storageClient *storage.Client

	// Set this in app.yaml when running in production.
	bucket = os.Getenv("GCLOUD_STORAGE_BUCKET")
)

func main() {
	ctx := context.Background()

	var err error
	storageClient, err = storage.NewClient(ctx)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", formHandler)
	http.HandleFunc("/upload", uploadHandler)

	appengine.Main()
}

func uploadHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "", http.StatusMethodNotAllowed)
		return
	}

	ctx := appengine.NewContext(r)

	f, fh, err := r.FormFile("file")
	if err != nil {
		msg := fmt.Sprintf("Could not get file: %v", err)
		http.Error(w, msg, http.StatusBadRequest)
		return
	}
	defer f.Close()

	sw := storageClient.Bucket(bucket).Object(fh.Filename).NewWriter(ctx)
	if _, err := io.Copy(sw, f); err != nil {
		msg := fmt.Sprintf("Could not write file: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	if err := sw.Close(); err != nil {
		msg := fmt.Sprintf("Could not put file: %v", err)
		http.Error(w, msg, http.StatusInternalServerError)
		return
	}

	u, _ := url.Parse("/" + bucket + "/" + sw.Attrs().Name)

	fmt.Fprintf(w, "Successful! URL: https://storage.googleapis.com%s", u.EscapedPath())
}

func formHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, formHTML)
}

const formHTML = `<!DOCTYPE html>
<html>
  <head>
    <title>Storage</title>
    <meta charset="utf-8">
  </head>
  <body>
    <form method="POST" action="/upload" enctype="multipart/form-data">
      <input type="file" name="file">
      <input type="submit">
    </form>
  </body>
</html>`

For more information

For complete information on Cloud Storage, see the Cloud Storage documentation.

Send feedback about...

App Engine flexible environment for Go