Como disponibilizar arquivos estáticos

Muitas vezes, os aplicativos precisam disponibilizar arquivos estáticos, como JavaScript, imagens e CSS, além de manipular solicitações dinâmicas. Os aplicativos no ambiente flexível podem exibir arquivos estáticos de uma opção do Google Cloud, como o Cloud Storage, exibi-los diretamente ou usar uma rede de fornecimento de conteúdo (CDN) de terceiros.

Como exibir arquivos do Cloud Storage

O Cloud Storage pode hospedar recursos estáticos de aplicativos dinâmicos da Web. Estes são os benefícios de usar o Cloud Storage em vez de disponibilizar diretamente no aplicativo:

  • O Cloud Storage funciona basicamente como uma rede de fornecimento de conteúdo. Por padrão, qualquer objeto publicamente legível é armazenado em cache na rede global do Cloud Storage. Por isso, não é preciso fazer nenhuma configuração especial.
  • A carga do aplicativo é reduzida ao descarregar os recursos estáticos em disponibilização no Cloud Storage. Dependendo de quantos você tiver e da frequência de acesso, isso reduz bastante o custo de execução do aplicativo.
  • As tarifas de largura de banda para acessar conteúdo costumam ser menores com o Cloud Storage.

É possível fazer upload dos recursos para o Cloud Storage usando a ferramenta de linha de comando gsutil ou a API Cloud Storage.

A biblioteca de cliente do Google Cloud fornece um cliente idiomático ao Cloud Storage para armazenar e recuperar dados com o Cloud Storage em um aplicativo do App Engine.

Exemplo de exibição em um bucket do Cloud Storage

Este exemplo simples cria um bucket do Cloud Storage e faz upload de recursos estáticos usando a Google Cloud CLI:

  1. Crie um bucket. É comum dar o nome do ID do projeto ao bucket, mas isso não é obrigatório. O nome dele precisa ser exclusivo.

    gsutil mb gs://<your-bucket-name>
    
  2. Configure a ACL para conceder acesso de leitura aos itens no bucket.

    gsutil defacl set public-read gs://<your-bucket-name>
    
  3. Faça o upload dos itens para o bucket. Geralmente, o comando rsync é o jeito mais rápido e fácil de fazer upload e atualizar recursos. Também é possível usar o cp.

    gsutil -m rsync -r ./static gs://<your-bucket-name>/static
    

Agora é possível acessar os recursos estáticos via https://storage.googleapis.com/<your-bucket-name>/static/....

Para saber mais sobre como usar o Cloud Storage para disponibilizar recursos estáticos, incluindo a disponibilização a partir de um nome de domínio personalizado, consulte Como hospedar um site estático.

Como exibir arquivos de outros serviços do Google Cloud

Você também tem a opção de usar o Cloud CDN ou outros serviços de armazenamento do Google Cloud.

Como exibir arquivos diretamente do aplicativo

Normalmente, a exibição de arquivos do aplicativo é simples. No entanto, lembre-se destas desvantagens:

  • É possível que as solicitações de arquivos estáticos utilizem recursos aplicados em solicitações dinâmicas.
  • Dependendo da sua configuração, a disponibilização de arquivos do seu aplicativo pode resultar em um aumento na latência de resposta. Isso também poderá acontecer quando novas instâncias forem criadas para processar o carregamento.

Exemplo de exibição de arquivos estáticos com o aplicativo

Go

O exemplo a seguir demonstra como exibir arquivos estáticos com o app para o ambiente de execução do Go versão 1.15 e anterior e a versão 1.18 e posterior. É necessário atualizar seu app.yaml para usar a nova versão. Consulte Ambiente de execução do Go para mais informações sobre o uso dos novos ambientes de execução.

É possível usar o http.FileServer ou http.ServeFile padrão para exibir arquivos diretamente do app.

v1.18 e posterior


// Package static demonstrates a static file handler for App Engine flexible environment.
package main

import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
)

func main() {
	// Serve static files from "static" directory.
	http.Handle("/static/", http.FileServer(http.Dir(".")))

	http.HandleFunc("/", homepageHandler)
	appengine.Main()
}

const homepage = `<!doctype html>
<html>
<head>
  <title>Static Files</title>
  <link rel="stylesheet" type="text/css" href="/static/main.css">
</head>
<body>
  <p>This is a static file serving example.</p>
</body>
</html>`

func homepageHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, homepage)
}

v1.15 e anteriores


// Package static demonstrates a static file handler for App Engine flexible environment.
package main

import (
	"fmt"
	"net/http"

	"google.golang.org/appengine"
)

func main() {
	// Serve static files from "static" directory.
	http.Handle("/static/", http.FileServer(http.Dir(".")))

	http.HandleFunc("/", homepageHandler)
	appengine.Main()
}

const homepage = `<!doctype html>
<html>
<head>
  <title>Static Files</title>
  <link rel="stylesheet" type="text/css" href="/static/main.css">
</head>
<body>
  <p>This is a static file serving example.</p>
</body>
</html>`

func homepageHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, homepage)
}

Java

O exemplo a seguir demonstra como exibir arquivos estáticos com o aplicativo para o ambiente de execução Java 8 e 11/17. É necessário atualizar seu app.yaml para usar a nova versão. Consulte Ambiente de execução do Java para mais informações sobre como usar os novos ambientes de execução.

O contêiner de servlet do ambiente de execução do Java usará o descritor de implantação, que é o arquivo web.xml, para mapear URLs para servlets, incluindo recursos estáticos. Se você não especificar um web.xml, é usado um padrão que mapeia tudo para o servlet padrão.

Neste exemplo, ./src/main/webapp/index.html refere-se a uma folha de estilos disponibilizada por /stylesheets/styles.css.

versão 11/17

<!doctype html>
<html>
<head>
<title>Static Files</title>
<link rel="stylesheet" type="text/css" href="/stylesheets/styles.css">
</head>
<body>
  <p>This is a static file serving example.</p>
</body>
</html>

versão 8

<!doctype html>
<html>
<head>
<title>Static Files</title>
<link rel="stylesheet" type="text/css" href="/stylesheets/styles.css">
</head>
<body>
  <p>This is a static file serving example.</p>
</body>
</html>

O arquivo styles.css está localizado em ./src/main/webapp/stylesheets/styles.css.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #CCCCFF;
}

É possível configurar explicitamente como os arquivos estáticos são processados no arquivo web.xml. Por exemplo, se você quiser mapear solicitações para todos os arquivos que têm a extensão .jpg:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>

Se estiver usando uma biblioteca da Web, como Play (em inglês), você precisará consultar a documentação do framework sobre ativos estáticos.

Node.js

O exemplo a seguir demonstra como exibir arquivos estáticos com o aplicativo para o ambiente de execução do Node.js versão 16 e anteriores e a versão 18 e posteriores. É necessário atualizar seu app.yaml para usar a nova versão. Consulte Ambiente de execução do Node.js para mais informações sobre como usar os novos ambientes de execução.

A maioria dos frameworks da Web é compatível com a exibição de arquivos estáticos. Nesta amostra, o aplicativo usa o middleware express.static para exibir arquivos do diretório ./public para o URL /static.

'use strict';

const express = require('express');
const app = express();

app.set('view engine', 'pug');

// Use the built-in express middleware for serving static files from './public'
app.use('/static', express.static('public'));

app.get('/', (req, res) => {
  res.render('index');
});

// Start the server
const PORT = parseInt(process.env.PORT) || 8080;
app.listen(PORT, () => {
  console.log(`App listening on port ${PORT}`);
  console.log('Press Ctrl+C to quit.');
});

A visualização se refere a /static/main.css.

doctype html
html(lang="en")
  head
    title Static Files
    meta(charset='utf-8')
    link(rel="stylesheet", href="/static/main.css")
  body
    p This is a static file serving example.

A própria folha de estilo está localizada em ./public/css, que é exibida a partir de /static/main.css.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #CCCCFF;
}

Outros frameworks do Node.js, como Hapi, Koa e Sails, geralmente são compatíveis com a exibição de arquivos estáticos diretamente do aplicativo. Para mais detalhes sobre como configurar e usar conteúdo estático, consulte a documentação.

PHP

O ambiente de execução do PHP executa o Nginx para disponibilizar seu aplicativo, que está configurado para disponibilizar arquivos estáticos no diretório do projeto. É necessário declarar a raiz do documento especificando document_root no seu arquivo app.yaml:

runtime: php
env: flex

runtime_config:
  document_root: web

Python

O exemplo a seguir demonstra como exibir arquivos estáticos com o app para o ambiente de execução do Python 3.7 e versões anteriores. Para o Python versão 3.8 e posterior, consulte Ambiente de execução do Python para mais informações sobre o uso de versões mais recentes.

A maioria dos frameworks da Web é compatível com a exibição de arquivos estáticos. Nesta amostra, o aplicativo usa a capacidade integrada do Flask para exibir arquivos no diretório ./static do URL /static.

O aplicativo inclui uma visualização que renderiza o modelo. O Flask exibe tudo automaticamente no diretório ./static sem configurações adicionais.

import logging

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def hello():
    """Renders and serves a static HTML template page.

    Returns:
        A string containing the rendered HTML page.
    """
    return render_template("index.html")

@app.errorhandler(500)
def server_error(e):
    """Serves a formatted message on-error.

    Returns:
        The error message and a code 500 status.
    """
    logging.exception("An error occurred during a request.")
    return (
        f"An internal error occurred: <pre>{e}</pre><br>See logs for full stacktrace.",
        500,
    )

if __name__ == "__main__":
    # This is used when running locally. Gunicorn is used to run the
    # application on Google App Engine. See entrypoint in app.yaml.
    app.run(host="127.0.0.1", port=8080, debug=True)

O modelo renderizado pela visualização inclui uma folha de estilo localizada em /static/main.css.

<!doctype html>
<html>
<head>
  <title>Static Files</title>
  <!--
  Flask automatically makes files in the 'static' directory available via
  '/static'.
  -->
  <link rel="stylesheet" type="text/css" href="/static/main.css">
</head>
<body>
  <p>This is a static file serving example.</p>
</body>
</html>

A folha de estilo está localizada em ./static/main.css.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #CCCCFF;
}

Outras estruturas do Python, como Django, Pyramid e Bottle, normalmente são compatíveis com a exibição de arquivos estáticos diretamente do aplicativo. Consulte a documentação deles para saber como configurar e usar conteúdo estático.

Ruby

A maioria dos frameworks da Web é compatível com a exibição de arquivos estáticos. O exemplo a seguir demonstra como disponibilizar arquivos estáticos com o aplicativo para o ambiente de execução do Ruby no caso da versão 3.1 e anteriores e da versão 3.2. Você precisa atualizar o arquivo app.yaml para usar a nova versão. Consulte Ambiente de execução do Ruby para mais informações sobre como usar os novos ambientes de execução.

Sinatra

Por padrão, o framework da Web Sinatra (em inglês) exibe arquivos do diretório ./public. Este aplicativo inclui uma visualização que se refere a /application.css.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #CCCCFF;
}

A folha de estilo está localizada em ./public/application.css, que é exibida por /application.css.

Ruby on Rails

Por padrão, o framework da Web Ruby on Rails (em inglês) exibe arquivos do diretório ./public. O pipeline de recursos (em inglês) do Rails também gera arquivos estáticos JavaScript e CSS.

Esses aplicativos de exemplo contêm uma visualização de layout que inclui todas as folhas de estilo do aplicativo:

versão 3.2

doctype html
html
  head
    title Serving Static Files
    link rel="stylesheet" href="/application.css"
    script src="/application.js"
  body
    p This is a static file serving example.

versão 3.1 e anteriores

doctype html
html
  head
    title Serving Static Files
    = stylesheet_link_tag "application", media: "all"
    = javascript_include_tag "application"
    = csrf_meta_tags
  body
    = yield

versão 3.2

A própria folha de estilo é um arquivo .css localizado em ./public/application.css.

body {
  font-family: Verdana, Helvetica, sans-serif;
  background-color: #CCCCFF;
}

versão 3.1 e anteriores

A própria folha de estilo é um arquivo Sass (em inglês) localizado em ./app/assets/stylesheets/main.css.sass.

body
  font-family: Verdana, Helvetica, sans-serif
  background-color: #CCCCFF

Por padrão, os apps Rails não geram nem exibem recursos estáticos quando são executados em produção.

O ambiente de execução do Ruby executa rake assets:precompile durante a implantação para gerar recursos estáticos e define a variável de ambiente RAILS_SERVE_STATIC_FILES para ativar a exibição de arquivos estáticos em produção.

.NET

O exemplo a seguir demonstra como exibir arquivos estáticos com o aplicativo para o ambiente de execução .NET versão 3.1 e anterior e versão 6 ou posterior. Você precisa atualizar o arquivo app.yaml para usar a nova versão. Consulte Ambiente de execução do .NET para mais informações sobre como usar os novos ambientes de execução.

versão 6 e mais recentes

<html>
<head>
    <meta charset="utf-8" />
    <title>Hello Static World</title>
</head>
<body>
    <p>This is a static html document.</p>
    <p><img src="trees.jpg" /></p>
</body>
</html>

Para ativar a exibição de arquivos estáticos, adicione:

app.UseDefaultFiles();
app.UseStaticFiles();

versão 3.1 e anteriores

<html>
<head>
    <meta charset="utf-8" />
    <title>Hello Static World</title>
</head>
<body>
    <p>This is a static html document.</p>
    <p><img src="trees.jpg" /></p>
</body>
</html>

Para ativar a exibição de arquivos estáticos, adicione:

app.UseDefaultFiles();
app.UseStaticFiles();

Como disponibilizar a partir de uma rede de fornecimento de conteúdo de terceiros

Você pode usar qualquer CDN externa de terceiros para exibir seus arquivos estáticos e armazenar solicitações dinâmicas em cache, mas seu aplicativo poderá ter aumento de latência e custo.

Para melhorar o desempenho, use uma CDN de terceiros compatível com o CDN Interconnect.