Skip to content

[Bug/Improvement] Error: EBUSY: resource busy or locked, rename '.db.json.tmp' -> 'db.json' #186

@MatWise

Description

@MatWise

I have a dedicated soundbot folder that includes the db.json + the data and config folders. I then tried to build the bot via the regular, suggested command on docker hub:

docker run --name soundbot --restart=always -v $(pwd)/sounds:/app/sounds -v $(pwd)/db.json:/app/db.json -v $(pwd)/config:/app/config -e CLIENT_ID="<>" -e TOKEN="<>" markokajzer/discord-soundbot

This worked in previous iterations, however after updating the image I ran into problems whenever the bot tried to write to the db. Inside the container, the following message was issued and it terminated immediately afterwards:

  binding.rename(
          ^

Error: EBUSY: resource busy or locked, rename '.db.json.tmp' -> 'db.json'
    at renameSync (node:fs:1019:11)
    at TextFileSync.write (file:///app/node_modules/lowdb/lib/adapters/node/TextFile.js:52:9)
    at JSONFileSync.write (file:///app/node_modules/lowdb/lib/adapters/node/DataFile.js:43:23)
    at LowSync.write (file:///app/node_modules/lowdb/lib/core/Low.js:44:26)
    at Object.incrementCount (/app/dist/src/util/db/Sounds.js:37:26)
    at AudioPlayer.handleFinishedPlayingSound (/app/dist/src/queue/SoundQueue.js:146:16)
    at AudioPlayer.emit (node:events:508:28)
    at AudioPlayer.signalIdle (/app/dist/src/queue/SoundQueue.js:132:25)
    at AudioPlayer.emit (node:events:508:28)
    at set state (/app/node_modules/@discordjs/voice/dist/index.js:444:10) {
  errno: -16,
  code: 'EBUSY',
  syscall: 'rename',
  path: '.db.json.tmp',
  dest: 'db.json'
}

Node.js v24.12.0

Further diagnosing the problem revealed that, when you mount a single file in Docker (-v $(pwd)/db.json:/app/db.json), Docker maintains a reference to that specific file's inode. When lowdb (which, I can see, was updated in December) tries to rename .db.json.tmp to db.json, it's attempting to replace the mounted file, which conflicts with Docker's bind mount.

I was then able to solve the issue by a) mounting a folder (containing db.jsononly) and b) creating symlinks inside the container to refer to it. Looks like this:

docker run --name soundbot --restart=always -v $(pwd)/sounds:/app/sounds -v $(pwd)/config:/app/config -v $(pwd)/db:/data -e CLIENT_ID="<>" -e TOKEN="<>" --entrypoint /bin/sh markokajzer/discord-soundbot -c "cd /app && ln -sf /data/db.json db.json && npm start"

After that, no further isses have arised so far, so I assume my workaround did the trick. Overall, I feel like this should be handled differently. I guess the easiest solution would be to have the db.json inside a folder that can then be mounted. Another option would be to make the db path configurable. But my personal favorite would actually be to move config, sounds and db.json to the same root folder. This would reduce the required mounts to 1 and makes it easier to create backups, since everything user-specific would be in there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions