| [](https://github.com/dart-lang/labs/actions/workflows/appengine.yml) | |
| [](https://pub.dev/packages/appengine) | |
| [](https://pub.dev/packages/appengine/publisher) | |
| ## Dart support for Google AppEngine | |
| This package provides support for running server applications written in Dart on | |
| [Google App Engine](https://cloud.google.com/appengine/) using | |
| [Custom Runtimes with Flex Environment](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/). | |
| ## Status: Experimental | |
| **NOTE**: This package is currently experimental and published under the | |
| [labs.dart.dev](https://dart.dev/dart-team-packages) pub publisher in order to | |
| solicit feedback. | |
| For packages in the labs.dart.dev publisher we generally plan to either graduate | |
| the package into a supported publisher (dart.dev, tools.dart.dev) after a period | |
| of feedback and iteration, or discontinue the package. These packages have a | |
| much higher expected rate of API and breaking changes. | |
| Your feedback is valuable and will help us evolve this package. For general | |
| feedback, suggestions, and comments, please file an issue in the | |
| [bug tracker](https://github.com/dart-lang/appengine/issues). | |
| ## Prerequisites | |
| ### Install Dart and Cloud SDKs | |
| This page assumes the Dart SDK (see | |
| [dart.dev/get-dart](https://dart.dev/get-dart)) as well as the Google | |
| Cloud SDK (see [cloud.google.com/sdk](https://cloud.google.com/sdk/)) were | |
| installed and their bin folders have been added to `PATH`. | |
| ### Setup gcloud | |
| To ensure gcloud was authorized to access the cloud project and we have the | |
| `app` component installed, we assume the following has been run: | |
| ```console | |
| $ gcloud auth login | |
| $ gcloud auth application-default login | |
| $ gcloud config set project <project-name> | |
| $ gcloud components update app | |
| ``` | |
| Instead of running `gcloud auth application-default login` it is also possible | |
| to authenticate by making the environment variable | |
| `GOOGLE_APPLICATION_CREDENTIALS` point to a file containing | |
| _exported service account credentials_. | |
| ## Creating a hello world application | |
| To setup a hello world application we need 4 different things: | |
| #### An `app/pubspec.yaml` file describing the Dart package: | |
| ```yaml | |
| name: hello_world | |
| version: 0.1.0 | |
| environment: | |
| sdk: '>=2.0.0 <3.0.0' | |
| dependencies: | |
| appengine: ^0.12.0 | |
| ``` | |
| #### An `app/app.yaml` file describing the AppEngine app: | |
| ```yaml | |
| runtime: custom | |
| env: flex | |
| service: default | |
| ``` | |
| #### An `app/Dockerfile` describing how to build/bundle the app: | |
| ```Dockerfile | |
| FROM google/dart-runtime | |
| ### NOTE: Uncomment the following lines for local testing: | |
| #ADD key.json /project/key.json | |
| #ENV GOOGLE_APPLICATION_CREDENTIALS /project/key.json | |
| #ENV GOOGLE_CLOUD_PROJECT dartlang-pub | |
| ``` | |
| This requires _exported service account credentials_ in `key.json`. | |
| #### An `app/bin/server.dart` containing the app code | |
| ```dart | |
| import 'dart:io'; | |
| import 'package:appengine/appengine.dart'; | |
| requestHandler(HttpRequest request) { | |
| request.response | |
| ..write('Hello, world!') | |
| ..close(); | |
| } | |
| main() async { | |
| await runAppEngine(requestHandler); | |
| } | |
| ``` | |
| ## Running the app locally | |
| There are two ways to run the application locally - with or without docker. | |
| ### Running without Docker | |
| The simplest way to run the application is on the command line like this: | |
| ```console | |
| $ gcloud auth application-default login | |
| $ export GOOGLE_CLOUD_PROJECT=<project-name> | |
| $ dart bin/server.dart | |
| ``` | |
| This will serve the application at [localhost:8080](http://localhost:8080)! | |
| ### Running with Docker | |
| To be closer to the production environment one can run the application inside a | |
| docker container. In order to do so, docker needs to be installed first (see the | |
| [official instructions](https://docs.docker.com/engine/installation/). | |
| In order to run the application locally we uncomment the 3 lines in the | |
| `Dockerfile` and place the service account key in `key.json`: | |
| ```Dockerfile | |
| ADD key.json /project/key.json | |
| ENV GOOGLE_APPLICATION_CREDENTIALS /project/key.json | |
| ENV GOOGLE_CLOUD_PROJECT dartlang-pub | |
| ``` | |
| We can then run the application via: | |
| ```console | |
| $ docker build . | |
| ... | |
| Sucessfully built <docker-imgage-hash> | |
| $ docker run -it <docker-imgage-hash> | |
| ... | |
| ``` | |
| In order to find out at which IP the Docker container is available we inspect | |
| the running container via: | |
| ```console | |
| $ docker ps | |
| CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES | |
| <container-id> ... | |
| app % docker inspect --format '{{ .NetworkSettings.IPAddress }}' <container-id> | |
| 172.17.0.2 | |
| ``` | |
| Then the application will be available at [172.17.0.2:8080](http://172.17.0.2:8080). | |
| ## Deployment | |
| Before deploying the app, be sure to remove the environment variables in the | |
| `Dockerfile` which we used for local testing! | |
| To deploy the application to the cloud we run the following command (optionally | |
| passing the `--no-promote` flag to avoid replacing the production version) | |
| ```console | |
| $ gcloud app deploy --no-promote app.yaml | |
| ... | |
| Updating service [default]...done. | |
| Deployed service [default] to [https://<version-id>-dot-<project-id>.appspot.com] | |
| ... | |
| ``` | |
| This will perform a remote docker build in the cloud and deploy a new version. | |
| You can find the URL to the version that got deployed | |
| in the output of `gcloud app deploy` (as well as via the | |
| [Cloud Console](https://console.cloud.google.com) under `AppEngine > Versions`). | |
| ## Regenerating protobuf | |
| You need to have protoc in `$PATH`. | |
| Run the `tool/fetch_protos_and_regenerate_dart.sh` script. It will fetch the | |
| latest protos and compile them for dart using the protoc_plugin in | |
| `dev_dependencies`. |