{"id":15222232,"url":"https://github.com/googlecloudplatform/elixir-runtime","last_synced_at":"2025-05-07T20:12:47.871Z","repository":{"id":24367799,"uuid":"101318311","full_name":"GoogleCloudPlatform/elixir-runtime","owner":"GoogleCloudPlatform","description":"The community-supported runtime for Elixir on Google App Engine.","archived":false,"fork":false,"pushed_at":"2024-05-01T17:52:28.000Z","size":264,"stargazers_count":181,"open_issues_count":8,"forks_count":14,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-05-07T20:12:46.410Z","etag":null,"topics":["appengine","docker","elixir","elixir-runtime","google-cloud","phoenix"],"latest_commit_sha":null,"homepage":"https://cloud.google.com/elixir","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-24T16:58:10.000Z","updated_at":"2025-05-02T04:17:21.000Z","dependencies_parsed_at":"2024-09-28T15:21:21.997Z","dependency_job_id":null,"html_url":"https://github.com/GoogleCloudPlatform/elixir-runtime","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Felixir-runtime","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Felixir-runtime/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Felixir-runtime/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Felixir-runtime/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/elixir-runtime/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252949285,"owners_count":21830153,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appengine","docker","elixir","elixir-runtime","google-cloud","phoenix"],"created_at":"2024-09-28T15:11:13.674Z","updated_at":"2025-05-07T20:12:47.852Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Elixir Runtime for Google Cloud Platform\n\n[![Travis-CI Build Status](https://travis-ci.org/GoogleCloudPlatform/elixir-runtime.svg)](https://travis-ci.org/GoogleCloudPlatform/elixir-runtime/)\n\nThis repository contains the source for the Elixir Runtime for the\n[Google App Engine Flexible Environment](https://cloud.google.com/appengine/docs/flexible/).\nIt can also be used to run Elixir applications in\n[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine) and\nother Docker-based hosting environments.\n\nThis runtime is maintained by Google, but is experimental and not covered by\nany SLA or deprecation policy. It may change at any time.\n\n## Elixir on Google App Engine\n\n[Google App Engine](https://cloud.google.com/appengine/) is a\nplatform-as-a-service offering on Google Cloud Platform. It is an easy way to\nbuild scalable web and mobile backends in any language on Google's\ninfrastructure.\n\nYou may consider deploying your Elixir application to Google App Engine if:\n\n*   Your application is an HTTP web or mobile backend using an Elixir-based\n    framework such as [Phoenix](https://phoenixframework.org).\n*   You want to focus on application development, and allow Google's\n    infrastructure and operations teams to handle your operations needs such as\n    monitoring, scaling, and upgrades.\n\nYou should consider a different hosting solution such as, e.g.,\n[Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/) if:\n\n*   Your application uses Erlang's hot upgrade feature because it stores\n    critical state in long-running processes. App Engine is designed for\n    \"stateless\" apps that use a separate store such as a database for long-term\n    state.\n\nElixir support is specific to the\n[flexible environment](https://cloud.google.com/appengine/docs/flexible/) of\nApp Engine. The standard environment does not currently support Elixir.\n\n## Using the Elixir Runtime\n\nThe Elixir Runtime for Google Cloud Platform is an experimental runtime making\nit easy to run a Elixir web application in the Flexible Environment of\n[Google App Engine](https://cloud.google.com/appengine/). It is not a\n\"custom runtime\" in that it does not require you to use docker or provide your\nown Dockerfile. Instead, it is a full-featured runtime built on the same\ntechnology that powers the official language runtimes provided by Google.\n\nTo use the Elixir Runtime, you should have an Elixir project that, when run,\nlistens on port 8080 or honors the `PORT` environment variable. A project\nthat uses [Phoenix](http://phoenixframework.org/) will work. You will also\nneed a Google Cloud project with billing enabled, and you must have the\n[Google Cloud SDK](https://cloud.google.com/sdk/) installed.\n\n(Note: some very early versions of this README directed you to set the\n`app/use_runtime_builders` configuration in gcloud. This step is no longer\nnecessary with gcloud 175.0.0 and later, and you should now remove this config\nif you currently have it.)\n\n### Configuring an app with releases\n\nGenerally, we recommend that you set up releases for your application. Releases\nare the community's standard way to package and deploy your code, and they also\nhelp optimize the size and performance of your deployed application. Releases\ncan be built using the\n[mix release](https://elixir-lang.org/getting-started/mix-otp/config-and-releases.html#releases)\nfeature of Elixir 1.9 or later, or using the\n[Distillery](https://github.com/bitwalker/distillery) package.\n\nIf your application uses releases, the Elixir Runtime will build a release\nautomatically, in the `:prod` environment, when you deploy to App Engine.\nYou must set `include_erts: true` in your release configuration so the Erlang\nruntime is included. The release will be built in the cloud on the same OS and\narchitecture that it will run on, so you do not need to worry about\ncross-compilation.\n\nOnce you have configured releases, create a file called `app.yaml` at the root\nof your application directory, with the following contents:\n\n    env: flex\n    runtime: gs://elixir-runtime/elixir.yaml\n    runtime_config:\n      release_app: my_app\n\nReplace `my_app` with the name of your release.\n\nSee the [App Engine documentation](https://cloud.google.com/appengine/docs/flexible/)\nfor more information on things you can set in the `app.yaml` configuration\nfile. A variety of settings are available to control scaling, health checks,\ncron jobs, and so forth. There is no Elixir-specific section in the\ndocumentation, but much of the information for other languages such as Ruby\nwill still apply.\n\n### Configuring an app without releases\n\nThe Elixir Runtime also supports deploying an application that does not build\nreleases. If your app does not use releases, create a file called `app.yaml` at\nthe root of your application directory, with the following contents:\n\n    env: flex\n    runtime: gs://elixir-runtime/elixir.yaml\n    entrypoint: mix phx.server\n\nSet the `entrypoint` field to a command that launches your app in the\nforeground. If you do not specify an entrypoint, the Elixir Runtime will\nexamine your app and attempt to guess an appropriate command to use. Generally,\nthis guess will be `mix phx.server` for Phoenix apps, or `mix run --no-halt`\nfor non-Phoenix apps. However, for best results, it is recommended that you\nprovide an explicit entrypoint.\n\nSee the [App Engine documentation](https://cloud.google.com/appengine/docs/flexible/)\nfor more information on things you can set in the `app.yaml` configuration\nfile. A variety of settings are available to control scaling, health checks,\ncron jobs, and so forth. There is no Elixir-specific section in the\ndocumentation, but much of the information for other languages such as Ruby\nwill still apply.\n\n### Deploy your application\n\nOnce the `app.yaml` config file is set up, you can deploy to App Engine with\n\n    gcloud app deploy\n\nBy default, the Runtime will build your project by downloading its deps, and\ncompile with `MIX_ENV=prod`. For Phoenix apps that use Brunch, it will also\nperform a brunch build. Finally, if you are using releases, a release will be\nbuilt for your application automatically; otherwise your application code will\nbe compiled in place.\n\nYou may update your application by modifying your source and redeploying.\nAgain, the Elixir Runtime will take care of rebuilding your application in\nthe cloud when you deploy.\n\n### Changing the environment/config\n\nIf your application needs environment variables to be set, you can use the\nstandard `env_variables:` field in the `app.yaml` file. For example:\n\n    env_variables:\n      MY_VAR: value1\n      SERVICE_HOSTNAME: example.com\n\nThis will set those environment variables both at build time and at runtime.\n\nOne environment variable of particular note is `MIX_ENV`, which controls the\n\"environment\" your application runs in. It can affect build parameters such as\ncompilation settings; and many frameworks, including Phoenix, use it to select\na set of configuration to use.\n\nBy default, the Elixir runtime builds and runs your app in the `prod`\nenvironment, but you can change this by setting the `MIX_ENV` environment\nvariable. For example:\n\n    env_variables:\n      MIX_ENV: staging\n\nThis will not only set the `MIX_ENV` during the building and running of your\napplication, but if you are using a Distillery release, it will also cause\nDistillery to build the app with that environment. (So make sure there is a\ncorresponding clause for the environment in your `rel/config.exs` file.)\n\n### Specifying the Erlang and Elixir versions\n\nThe Elixir Runtime uses the [asdf](https://github.com/asdf-vm/asdf) tool to\ninstall and manage Erlang and Elixir. By default, it will run your application\non recent stable releases of those languages. However, the default versions may\nchange at any time, and indeed may depend on the type of application. (For\nexample, as of July 2019, the default Elixir version for most applications is\n1.9.0, except if the application uses a version of Distillery prior to 2.1, in\nwhich case it defaults to 1.8.2 to avoid mix task collisions.)\n\nIf you need more stability in the language versions used, you may provide a\n`.tool-versions` file with versions for `erlang` and `elixir`. See the\n[asdf](https://github.com/asdf-vm/asdf) documentation for more information on\nthe format of the `.tool-versions` file.\n\nWhen you deploy an Elixir application, the Elixir runtime will install the\nrequested releases of Erlang and Elixir into your application image\n\"just-in-time\". In most cases, this is pretty quick. Asdf installs Elixir\ndirectly from precompiled binaries hosted on hex.pm. For Erlang, the Elixir\nRuntime itself provides prebuilt binaries of most recent versions of Erlang\nsince Erlang 20, and can install any of these directly.\n\nHowever, if you request an Erlang version for which we do not have a prebuilt\nbinary, the Elixir runtime will have to build Erlang from source. This can\ntake a good 10-20 minutes by itself, and it often causes App Engine deployment\nto time out. To fix this, set the following:\n\n    gcloud config set app/cloud_build_timeout 60m\n\nThis allocates 60 minutes to the \"build\" phase of app engine deployment, which\nshould be more than sufficient to build both Erlang and your application. (Feel\nfree to set it to a different value if you want.) If this gcloud configuration\nis not explicitly set, it defaults to 10 minutes.\n\n### Customizing application builds\n\nThe Elixir Runtime provides a standard build script that includes installation\nof Erlang and Elixir, fetching dependencies, compiling your application, and\n(for release-based applications) building the release.\n\nThere is also a space for custom build commands that are executed after\ncompilation but before release generation. Your application might use this\nspace for application-specific or framework-specific build steps such as\nbuilding asset files or obtaining credentials.\n\nPhoenix applications generally use Webpack or Brunch to build assets. So, by\ndefault, if the Elixir runtime detects that your app uses Phoenix and contains\na brunch or webpack config file, it will automatically give you a custom build\ncommand that attempts the appropriate build.\n\nSpecifically, for Phoenix 1.4 using Webpack, this command is:\n\n    cd assets \\\n    \u0026\u0026 npm install \\\n    \u0026\u0026 node_modules/webpack/bin/webpack.js --mode production \\\n    \u0026\u0026 cd .. \\\n    \u0026\u0026 mix phx.digest\n\nSimilarly, for Phoenix 1.3 using Brunch, this command is:\n\n    cd assets \\\n    \u0026\u0026 npm install \\\n    \u0026\u0026 node_modules/brunch/bin/brunch build --production \\\n    \u0026\u0026 cd .. \\\n    \u0026\u0026 mix phx.digest\n\n(It is slightly different for Phoenix 1.2 applications, and for Phoenix\numbrella applications.)\n\nYou may also provide your own custom build commands, by setting the\n`runtime_config: -\u003e build:` setting in your `app.yaml` file. The value should\nbe an array of shell commands to be executed in order. For example:\n\n    runtime_config:\n      build:\n        - mix phx.digest\n        - mix do.something.else\n\nNote that if you provide your own custom build commands, they will override\nany Webpack or Brunch build that the Elixir Runtime gives you by default, so\nif you still want to use one of those asset build systems, you will have to\ninclude a command explicitly in your config.\n\n### Installing Debian packages\n\nThe Elixir runtime provides a minimal set of Debian packages needed to run\nERTS. If your application requires additional packages, you may specify them\nin the `runtime_config: -\u003e packages:` setting of your `app.yaml` file. The\nElixir runtime will then make sure they get installed in the Docker image.\nFor example:\n\n    runtime_config:\n      packages:\n        - libpq-dev\n        - imagemagick\n\n## Inside the Elixir Runtime\n\nThe Elixir Runtime comprises three parts:\n\n*   A series of base Docker images that are used by the runtime, and can also\n    be used directly by applications. They are all based on a stable version of\n    Debian (the same Debian base image used by Google's officially supported\n    runtimes).\n    *   `elixir-ubuntu18` contains an installation of Ubuntu 18.04 plus a few\n        dependencies for the Erlang VM, and some common configuration for\n        App Engine runtimes. However, it does not include an installation of\n        Erlang or Elixir itself. This image is used as a runtime base image for\n        release-based applications. An application release, with its embedded\n        ERTS, is installed directly atop this image.\n    *   `elixir-asdf` extends `elixir-ubuntu18` by installing\n        [asdf](https://github.com/asdf-vm/asdf) and the erlang and elixir\n        plugins, but does not include any actual installations. This image is\n        used as a base image for most other images.\n    *   `elixir-base` extends `elixir-asdf` by installing a default recent\n        version of both Erlang and Elixir. It may be used as a convenient\n        base image for applications that do not care about specific versions\n        of the language.\n    *   `elixir-builder` extends `elixir-asdf` and installs additional build\n        tools such as NodeJS and the Google Cloud SDK. It is used as a base\n        image for builds, but still requires that asdf be used to install a\n        version of Erlang and Elixir.\n*   An `elixir-generate-dockerfile` image. This is the heart of an App Engine\n    runtime. It analyzes an Elixir project and constructs a Dockerfile that can\n    be used to build the project and prepare it for running in App Engine. When\n    you deploy an Elixir application to App Engine, this analyzer-generator\n    runs on your application first, and then the generated Dockerfile is used\n    to build the Docker image that gets pushed to App Engine servers. The\n    generated Dockerfile generally contains two stages: a build stage based on\n    `elixir-builder` that performs the build, and a runtime stage based on\n    either `elixir-ubuntu18` (for release-based builds) or `elixir-asdf` (for\n    non-release-based).\n*   A configuration file that references a specific build of the above\n    analyzer-generator image. This file serves as the official definition of\n    the Elixir Runtime, and is available in Google Cloud Storage at the\n    location `gs://elixir-runtime/elixir.yaml`. When you set the `runtime`\n    field of your `app.yaml`, it points at this configuration file.\n\n## Building and Releasing\n\nBuild and release scripts are provided that support test builds as well as\nofficial releases.\n\n### Prerequisites\n\nYou must have the [gcloud sdk](https://cloud.google.com/sdk/) installed, and\nhave access to a Google Cloud project. The CloudBuild API must be enabled in\nyour project. You should also set up a cloud storage bucket that will hold\nyour test runtime definition.\n\nTo perform an official build/release, you must have write access to the\n`gcp-elixir` project and the `elixir-runtime` storage bucket.\n\n### Test builds\n\nTo perform a test build, run the `runtime-build.sh` script:\n\n    ./runtime-build.sh\n\nBy default, this will build the runtime images to Google Cloud Container\nRegistry in your current project (which should be configured in gcloud). It\nwill tag them with the current date and time. It will also build a runtime\ndefinition and write it to a `tmp` directory in this repo directory.\n\nIf you want to upload the definition to cloud storage (and thus make it\navailable to use for App Engine deployments), you must provide the name of\na cloud storage bucket to upload it to. You must of course have write access\nto this storage bucket.\n\n    ./runtime-build.sh -b my-storage-bucket\n\nYou can then use the build of the runtime by pointing at the uploaded\ndefinition file in cloud storage:\n\n    runtime: gs://my-storage-bucket/elixir-\u003cdatetime-tag\u003e.yaml\n\nYou may also mark the build as a \"staging\" build by providing the `-s` flag\nto `runtime-build.sh`. This will tag the built images with the `staging` tag,\nand will also write an `elixir-staging.yaml` definition, so you can use:\n\n    runtime: gs://my-storage-bucket/elixir-staging.yaml\n\nThere are several additional options to `runtime-build.sh`. Pass the `-h` flag\nfor more information.\n\n### Prebuilding Erlang binaries\n\nA basic test build as configured above will likely be slow because it must\ncompile Erlang from source while deploying. To fix this, provide a set of\nprebuilt Erlang binaries.\n\nFirst, choose the Erlang versions that will be covered. This list should\ninclude at least the default Erlang version specified in the `runtime-build.sh`\nscript. Write them, one per line, in a file in this directory called\n`erlang-versions.txt`.\n\nNext, execute the `erlang-build.sh` script to build these versions of Erlang.\nThis script uses the \"elixir-asdf\" base image so you must first build the\nruntime itself.\n\nThe runtime build script also uses the `erlang-versions.txt` file to decide\nwhich Erlang versions it can install using prebuilt binaries. So after you\nedit the version list, you must rebuild the runtime itself.\n\nFrom this point, the prebuilt binaries can be revved independent of the\nruntime. When you update the runtime, you generally will not need to rebuild\nthe Erlang prebuilt images, or vice versa.\n\n### Releases\n\nOfficial releases of the Elixir Runtime are done in the `gcp-elixir` project\nand uploaded to the `elixir-runtime` storage bucket. If you have sufficient\naccess, you can perform an official release as follows:\n\n    ./runtime-build.sh -p gcp-elixir -n runtime -b elixir-runtime -s -i\n    ./runtime-release.sh -p gcp-elixir -n runtime -b elixir-runtime\n\nTo update the official prebuilt Erlang binaries, do this:\n\n    ./erlang-build.sh -p gcp-elixir -n runtime -s -e \u003cversions-to-build\u003e\n    ./erlang-release.sh -p gcp-elixir -n runtime -e \u003cversions-to-release\u003e\n\nGenerally, you should provide versions explicitly, otherwise it will build or\nrelease ALL versions in the erlang-versions.txt file, which would take a very\nlong time.\n\n## Contributing changes\n\n* See [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## License\n\n* See [LICENSE](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Felixir-runtime","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Felixir-runtime","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Felixir-runtime/lists"}