# Audiobookshelf won't start after a Docker upgrade

> Fix the Cannot find module /index.js crash after upgrading Audiobookshelf Docker to v2.22.0+ by removing working_dir and recreating the container

Source: https://soundleafapp.com/server/audiobookshelf-docker-upgrade-crash/
Published: 2026-04-14

---

Audiobookshelf v2.22.0 changed the Docker image's working directory from `/` to `/app`. If your container or management tool cached the old `working_dir`, the startup command `node index.js` looks for `/index.js` instead of `/app/index.js` and crashes immediately.

The error in your logs looks like this:

```
Error: Cannot find module '/index.js'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1212:15)
    at Module._load (node:internal/modules/cjs/loader:1043:27)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:164:12)
    at node:internal/main/run_main_module:28:49 {
  code: 'MODULE_NOT_FOUND',
  requireStack: []
}
Node.js v20.19.1
```

This affects Synology, Portainer, Cosmos Cloud, plain docker-compose, and anything else that caches container settings. Downgrading to 2.21.0 works as a temporary fix, but the real solution is removing the stale `working_dir`. There are multiple threads about this on GitHub ([#4292](https://github.com/advplyr/audiobookshelf/issues/4292), [#4309](https://github.com/advplyr/audiobookshelf/issues/4309), [#4289](https://github.com/advplyr/audiobookshelf/issues/4289)).

The image also got smaller (from ~600MB to ~310MB) because `curl` and other tools were removed. If you had a healthcheck using `curl`, that breaks too.

## The fix: remove working_dir and recreate

This is the fix that works for most people. Check your docker-compose file or container settings for a `working_dir` entry and remove it.

```yaml
# BEFORE - this breaks v2.22.0+
services:
  audiobookshelf:
    image: advplyr/audiobookshelf:latest
    working_dir: /          # <-- DELETE THIS LINE
    volumes:
      - ./config:/config
      - ./audiobooks:/audiobooks

# AFTER - let the image use its own default (/app)
services:
  audiobookshelf:
    image: advplyr/audiobookshelf:latest
    volumes:
      - ./config:/config
      - ./audiobooks:/audiobooks
```

After removing `working_dir`, you need to **fully recreate the container**, not just restart it. The old container has the cached working directory baked in.

```bash
docker compose down
docker compose up -d
```

If you didn't explicitly add `working_dir` yourself, it might have been set automatically by your management tool. Check Portainer's "Advanced container settings > Commands & logging" section, or Cosmos Cloud's compose editor.

## Platform-specific fixes

### Synology Container Manager

Synology caches container settings aggressively. A simple "restart" won't cut it.

1. Stop the container
2. In Container Manager, right-click the project and select **Clean**
3. Rebuild the project

If that doesn't work, delete the container entirely (don't delete your volumes/data) and create a new one pointing to the same volumes.

### Portainer

If you're using Portainer stacks:

1. Go to **Advanced container settings > Commands & logging**
2. Click **Revert to default** on both Command and Entrypoint
3. Clear the **Working Dir** field (leave it blank)
4. Redeploy the stack

If you can't find the working_dir setting, there's a [trick that forces Portainer to reset](https://github.com/advplyr/audiobookshelf/issues/4292#issuecomment-2883905544): temporarily add these lines to your compose, recreate, then remove them and recreate again:

```yaml
entrypoint: ["/bin/sh", "-c"]
command: ["ls && tail -f /dev/null"]
```

### Cosmos Cloud

Remove any `NUSQLITE` environment variables and the `working_dir` entry from the Cosmos compose editor. Cosmos modifies compose files internally and can cache stale values.

## Fix your healthcheck too

If your container was using a `curl`-based healthcheck, it'll fail now because `curl` was removed from the image. Switch to `wget`:

```yaml
healthcheck:
  test: ["CMD", "wget", "-qO-", "http://127.0.0.1/healthcheck"]
  interval: 1m
  timeout: 10s
  start_period: 30s
```

## If nothing works: nuclear option

If you've tried everything above and it still crashes:

```bash
# Stop and remove the container
docker compose down

# Remove the cached image
docker rmi advplyr/audiobookshelf:latest

# Pull fresh and start
docker compose pull
docker compose up -d
```

Your data is safe as long as your volumes are properly mounted (config, audiobooks, metadata directories). Removing the image and container doesn't touch mounted volumes.

If even that doesn't work, pin to a specific version while you troubleshoot:

```yaml
image: advplyr/audiobookshelf:2.21.0
```

But don't stay on an old version long-term. You'll miss security patches. The real fix is removing `working_dir`.

## Affected versions

This affects upgrades **to v2.22.0 and later** from any older version. The root cause is [this Dockerfile change](https://github.com/advplyr/audiobookshelf/commit/fd0af6b2dddce3f951f5a27da8e9568baaaeb59c) that moved the working directory from `/` to `/app`.

If you're doing a fresh install (no existing container), you won't hit this.
