Oryx: Azure App Service's automatic build system, usable on its own
Build your repo automatically.
At a glance
- What is it?
- Oryx inspects a repository, decides which language toolsets apply, and generates both a build script and a startup script, which is how Azure App Service builds web apps without a pipeline file. The pieces ship as container images, so you can run the same detection and script generation locally for troubleshooting.
- Who is it for?
- Use Oryx directly when you are debugging why an App Service deployment built the wrong thing, or when you want the same automatic detection in your own container pipeline, because the build and runtime images let you run the identical steps on a laptop and compare. Do not treat it as a general purpose build orchestrator, since it is opinionated about a small set of language stacks and its two commands are a detector plus a script generator.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Detection by file, not by configuration
Oryx is described as a build system which automatically compiles source code repos into runnable artifacts, and it is used to build web apps for Azure App Service and other platforms. The mechanism is deliberately simple. Oryx generates and runs an opinionated build script within a build container based on analysis of a codebase's contents. If package.json is discovered in the repo, Oryx includes npm run build in the build script; if requirements.txt is found, it includes pip install -r requirements.txt. That is the whole detection idea: the presence of a manifest file selects the toolset, and the build script is derived from it. The consequence for a user is that there is no build file to write and no pipeline to configure, but also that a repository with an unusual layout can be detected in a way you did not intend, since the detection is a file-name match rather than a semantic read of your project.
Two commands, one for building and one for starting
Oryx includes two command line applications, and the distinction between them matters when you read the documentation. The first is included in the build image and generates a build script by analysing a codebase. The second is included in the run images and generates a startup script. Both are aliased and accessible as oryx in their respective images, which is why the same binary name appears in two different contexts. When oryx build runs, the system detects which programming platforms appear to be in use and applies the toolsets appropriate for each one, and the default choices can be overridden through configuration. The output parameter, or -o, specifies where the prepared artifacts are placed, and if it is not specified the source directory is used for output as well. In the runtime images the generated start script is named run.sh, by default in the same folder as the compiled artifact. For all options, the README says to specify oryx --help.
Build container, run container, and the artifacts in between
The pipeline shape is described in five approximate steps, and the run container example is the clearest thing in the README. You mount the repo as a volume in the Oryx build container, run oryx build inside the repo directory to produce a runnable artifact, then mount the output directory into an appropriate run container such as the node-10.14 one. Inside that run container you run oryx to write the startup script, and then you run the generated script, by default /run.sh.
docker run --volume $(pwd):/repo \
'mcr.microsoft.com/oryx/build:latest' \
oryx build /repo --output /repoThe generated startup script covers the run-time side, including typical start commands such as npm run start for Node.js or a WSGI module and server for Python. The built artifacts and the start script are then loaded into a minimalistic run container and run. That separation is the design point: the build container carries the compilers and the toolchain, and the run container carries only what the application needs. The component list says the same thing: a build image, a collection of runtime images, a build script generator and a collection of startup script generators.
appsvc.yaml overrides the defaults
The App Service YAML file, appsvc.yaml, is used to specify the build and run commands for a web app, overriding any defaults provided by the App Service Build Service, and App Service expects it in the root directory of the project. The format has ordered keys for pre-build, post-build and run, and the commands or scripts referenced by those keys are executed in order. If a key is missing it is skipped and the next one is processed. There is also an optional version key that specifies the version of the appsvc.yaml file, if new versions are introduced later, which is a forward compatibility hook rather than decoration.
version: 1
pre-build: apt-get install jq
post-build: |
python manage.py makemigrations
python manage.py migrate
run: gunicorn myapp.app --workers 5The example is instructive about the intended use. A pre-build step installs a system package, a post-build step runs Django migrations as part of the build, and the run key names the WSGI server invocation. This is how you express the parts of a deployment that a manifest-based detector cannot infer, without giving up the automatic detection for everything else.
The build server exposes the same operations with more flags
For teams that want the detection and script generation behind a service rather than a container invocation, the README documents a build server path. You build the Oryx solution, create an image with oryx and the platform binaries using the build image script with a target tag, then run Docker with port mapping, a volume mount, the image carrying oryx build and invoke the BuildServer. Under the hood the invocation reaches oryx build, with the fuller option set visible in the sample command.
oryx build [sourcePath] \
--platform [platform] \
--platform-version [version] \
--output [outputPath] \
--log-file [logPath]The extra flags matter for a hosted service, where the platform and its version have to be pinned explicitly and where a log file gives you something to inspect after the fact. The documented sequence for using it includes checking build status with a given id and checking the server healthcheck, which is the sort of operational surface that a CI system needs and a local invocation does not. The repository also carries a vsts directory, which is where the Azure DevOps integration lives.
Runtime versions move, and the announcements tracker is the channel
Oryx's supported platforms and versions live in a document under the doc directory, and the README links to it rather than listing versions in the readme itself. Patches in the 0.0.x range are applied as soon as possible after they are released upstream, which tells you the patch line is a fast-moving compatibility layer rather than a stable series. For keeping up, the README points at Azure Updates and at the azure/app-service-announcements tracker repository on GitHub, and says to subscribe to one or watch the other to receive updates on runtimes and versions supported by Oryx and App Service. This is a meaningful dependency for anyone building on Oryx directly: your build result depends on a runtime image whose contents change outside your repository, so the announcement channel is part of your operational surface.
Where Oryx is the wrong choice
Four limits apply. It is opinionated by design, so a project with an unusual build will either need appsvc.yaml to correct it or will be detected wrongly, and there is no general build definition format. It covers a small set of language stacks rather than arbitrary toolchains, so a repository built with a bespoke compiler invocation is out of scope. It is written for container deployment, so if you are not shipping a container image the two-image structure is overhead. And the release history tells you how to read the versioning: the tags are dated, with 20240408.1, 20240401.1 and 20240325.1 published in the first half of 2024, while the last push to the repository was on 2026-10-19, so the code has moved well past the last tagged release and the tags are a calendar rather than a version you can reason about. The licence field on the repository carries a custom licence that GitHub cannot classify, even though the README states MIT and points at the LICENSE file, so read that file before shipping anything built on it.
Editorial conclusion
Use Oryx directly when you are debugging why an App Service deployment built the wrong thing, or when you want the same automatic detection in your own container pipeline, because the build and runtime images let you run the identical steps on a laptop and compare. Do not treat it as a general purpose build orchestrator, since it is opinionated about a small set of language stacks and its two commands are a detector plus a script generator. Verify first that your repository shape is one Oryx recognises, since detection is based on files such as package.json and requirements.txt, that you read the appsvc.yaml format before relying on it to override the defaults, and that the licence question is settled for your organisation, because the licence field on the repository carries a custom licence GitHub cannot classify while the README states MIT.
Frequently asked questions
What is Oryx and how does it decide how to build my repository?
Oryx is a build system that automatically compiles source repositories into runnable artifacts. It analyses the codebase contents, so a discovered package.json leads to npm run build in the generated build script, and a found requirements.txt leads to pip install -r requirements.txt.
What is the difference between oryx build and oryx create-script?
Two command line applications ship, both aliased as oryx in their respective images. The one in the build image generates a build script by analysing the codebase, and the one in the runtime images generates a startup script named run.sh, by default in the same folder as the compiled artifact.
How do I override Oryx's default build and run commands?
You add an appsvc.yaml file to the root directory of your project. Its ordered pre-build, post-build and run keys specify the commands and are executed in order, a missing key is skipped, and an optional version key records the file format version.
How do I build and run an app with Oryx locally?
Mount the repo into the Oryx build container and run oryx build with an output path, then mount that output into a runtime container, run oryx there to write the startup script and execute /run.sh. The README gives the exact docker run commands for both steps.
Which runtimes and versions does Oryx support?
The supported platforms and versions are listed in the doc directory of the repository, and the README links to that document instead of restating them. Patches in the 0.0.x range are applied as soon as they are released upstream, and the Azure Updates channel and the app-service-announcements tracker are the places to watch for changes.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/microsoft-oryx)Was this useful?