Azure / Azure/webapps-deploy

azure/webapps-deploy@v3 / OneDeploy 409 left Linux Python App Service in compressed-only wwwroot state; startup.sh missing

Open
#544 1 comment 1 reaction 0 assignees View on GitHub
need-to-triage
Dominant language
TypeScript
Stars
338
Forks
234
Avg merge
53m
Merged PRs (30d)
3

Description

## Summary

`azure/webapps-deploy@v3` failed during OneDeploy with `409 Conflict` and left a Linux Python App Service in a broken partial deployment state.

After the failed deploy, `/home/site/wwwroot` contained only:

```text
.ostype
hostingstart.html
output.tar.zst
```

The expected app files were inside `output.tar.zst`, but were not extracted/activated into `wwwroot`. Because the App Service startup command was `startup.sh`, the app failed to boot with:

```text
/opt/startup/startup.sh: 23: startup.sh: not found
```

## Environment

- Azure App Service on Linux
- Python 3.12
- Deployment via GitHub Actions
- Action: `azure/webapps-deploy@v3`
- Deployment backend: OneDeploy
- Startup command: `startup.sh`

## Deploy failure

```text
Package deployment using OneDeploy initiated.
Error: Failed to deploy web package to App Service.
Error: Deployment Failed, Error: Failed to deploy web package using OneDeploy to App Service.
Conflict (CODE: 409)
```

## Runtime failure

```text
Site's appCommandLine: startup.sh
Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite -userStartupCommand 'startup.sh'
WARNING: Could not find virtual environment directory /home/site/wwwroot/antenv.
/opt/startup/startup.sh: 23: startup.sh: not found
```

## Kudu findings

Deployment state appeared stuck/incomplete:

```text
/home/site/deployments/pending
/home/site/deployments/temp-*
/home/site/locks/status.lock
```

The compressed artifact did contain the expected files:

```text
./startup.sh
./pyproject.toml
./antenv/
./app/app.py
```

## Manual recovery

The app was recovered by clearing the stale deployment state and manually extracting the artifact:

```bash
rm -f /home/site/locks/status.lock
rm -f /home/site/locks/info.lock
rm -f /home/site/deployments/pending
rm -rf /home/site/deployments/temp-*

cd /home/site/wwwroot
tar --zstd -xf output.tar.zst
chmod +x startup.sh
```

After restarting, App Service successfully found the startup file and virtual environment.

## Expected behavior

If OneDeploy fails, the App Service should either:

1. Complete extraction/activation of the artifact, or
2. Fail atomically and preserve the previous working deployment.

It should not leave `wwwroot` containing only `output.tar.zst` while the configured startup command points to a file that exists only inside the archive.

## Questions

- Is this a known issue with `azure/webapps-deploy@v3`, OneDeploy, Linux App Service, Python/Oryx, or `output.tar.zst` activation?
- Under what conditions can OneDeploy leave `wwwroot` in this compressed-only state?
- What is the recommended production-safe deployment configuration to prevent this?
- Should the action detect or recover from stale `pending`, `temp-*`, or `status.lock` deployment state?

## Impact

This caused a production outage and required manual Kudu intervention to restore service.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reproducing the azure/webapps-deploy@v3 OneDeploy path for a Linux Python App Service and inspect the Kudu deployment state, including pending, temp-* and lock files. Compare the wwwroot contents with output.tar.zst after a 409; done means a failed deployment either activates the artifact completely or preserves the previous working deployment without manual intervention.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, github-actions, python, typescript
Domain
cloud, devops
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.