Deno(/tmp/2dbb7d09) - NotFound: No such file or directory (os error 2)

I’m trying to save some files in temporary directory in order to do file conversion using ffmpeg in deno. I was deploying my app using github actions and initially faced the issue then i also tryied deploying from my machine using fly deploy but the issue still persisted

Here’s the code for downloadVoiceFile and its usage. Using both currentDirectory and tempDirectory as the directory for temporary files don’t work


// function itself
export async function downloadVoiceFile(
  url: string,
  filename: string,
  dir: string
): Promise<string | undefined> {
  console.log("calling downloadVoiceFile", { url, filename, dir });
  const oggDestination = `${dir}/${filename}.ogg`;
  const mp3Destination = `${dir}/${filename}.mp3`;

  await Deno.open(mp3Destination, { create: true, append: true });

  try {
    const input = await Deno.open(oggDestination, {
      create: true,
      append: true,
    });
    const { body } = await fetch(url);

    if (body === null) {
      console.log(`Download failed, no response body from '${url}'`);
      throw new Error(`reply:Could not process file`);
    }

    await body.pipeTo(input.writable);

    // @see https://github.com/riefer02/fresh-deno-api/blob/main/routes/api/audio/index.ts#L15
    const p = Deno.run({
      cmd: [
        "ffmpeg",
        "-i",
        oggDestination,
        "-vn",
        "-ar",
        "44100",
        "-b:a",
        "192k",
        mp3Destination,
        "-y",
      ],
    });

    const status = await p.status();

    if (!status.success) {
      console.log("ffmpeg failed");
      throw new Error(`reply:Could not transcribe the file`);
    }

    console.log("ffmpeg success");

    return mp3Destination;
  } catch (error) {
    console.error(error);
    throw error;
  }
}

// usage
const currentDirectory = Deno.cwd();
      const tempDirectory = await Deno.makeTempDir();

      console.log({ currentDirectory, tempDirectory });

      localFilePath = await downloadVoiceFile(
        url,
        filename,
        config.isProd ? tempDirectory : `${currentDirectory}/playground` // both on my mac without any issue
      );

Dockerfile

# Based on https://github.com/denoland/deno_docker/blob/main/alpine.dockerfile

ARG DENO_VERSION=1.32.4
ARG BIN_IMAGE=denoland/deno:bin-${DENO_VERSION}
FROM ${BIN_IMAGE} AS bin

FROM jrottenberg/ffmpeg:4.4.1-alpine313
FROM frolvlad/alpine-glibc:alpine-3.13

RUN apk --no-cache add ca-certificates

RUN addgroup --gid 1000 deno \
  && adduser --uid 1000 --disabled-password deno --ingroup deno \
  && mkdir /deno-dir/ \
  && chown deno:deno /deno-dir/

ENV DENO_DIR /deno-dir/
ENV DENO_INSTALL_ROOT /usr/local

ARG DENO_VERSION
ENV DENO_VERSION=${DENO_VERSION}
COPY --from=bin /deno /bin/deno

COPY . ./deno-dir
WORKDIR /deno-dir

# See everything (in a linux container)...
RUN ls -la


RUN /bin/deno cache deps.deno.ts

# Compile the main app so that it doesn't need to be compiled each startup/entry.
RUN /bin/deno cache api/edge.ts --lock=deno.lock --lock-write


EXPOSE 8000

ENTRYPOINT ["/bin/deno"]

fly.toml

# fly.toml file generated for xxx on 2023-04-15T14:23:33Z

app = "xxx"
kill_signal = "SIGINT"
kill_timeout = 5
# mounts = []
primary_region = "ams"


[experimental]
  auto_rollback = true

[deploy]
  release_command = "task migrate:up"

[env]
  APP_ENV = "production"
  APP_URL = "https://xxx.fly.dev"
  DEBUG = "*"
  ENABLE_WEBHOOK_CHANGES = "true"
  LOG_CHANNEL = "stderr"
  LOG_LEVEL = "info"
  PRIMARY_REGION = "ams"
  PORT = "8000"


[processes]
    app = "task edge"


[[services]]
  http_checks = []
  internal_port = 8000
  processes = ["app"]
  protocol = "tcp"
  script_checks = []
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
      grace_period = "10s"
      interval = "15s"
      restart_limit = 0
      timeout = "30s"

I also wrote some small utility to print out the list of directories in my cwd


const directories: Deno.DirEntry[] = [];
for await (const dirEntry of Deno.readDir(Deno.cwd())) {
  if (dirEntry.isDirectory) {
    console.log({ dirEntry });
    directories.push(dirEntry);
  }
}

And here’s the output that shows that the playground directory exists in my cwd

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] directories in cwd {

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] directories: [

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "deps", isFile: false, isDirectory: true, isSymlink: false },

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "npm", isFile: false, isDirectory: true, isSymlink: false },

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "location_data", isFile: false, isDirectory: true, isSymlink: false },

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "api", isFile: false, isDirectory: true, isSymlink: false },

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "playground", isFile: false, isDirectory: true, isSymlink: false },

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] { name: "gen", isFile: false, isDirectory: true, isSymlink: false }

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] ]

2023-04-16T17:29:01.911 app[1781944a404e08] ams [info] }

Strange that it’d work on your PC.

Can you see if adding relevant permissions (ex: --allow-all) to your deno cmd makes a difference?

I added the -Aflag to the edge task as you can see below

{
  "tasks": {
    "check": "deno cache --check=all dev.ts",
    "flint": "deno fmt && deno lint",
    "dev": "deno run -A --watch=api/oak/ ./api/dev.ts",
    "edge": "deno run -A ./api/edge.ts",
    "bot": "deno run -A --watch=api/utils/,api/db/ ./api/bot.ts",
    "migrate": "deno run --allow-read --allow-env --allow-net ./api/db/migrate.ts",
    "migrate:up": "deno task migrate --up",
    "migrate:down": "deno task migrate --down",
    "migrate:reset": "deno task migrate --reset",
    "migrate:up:prod": "deno task migrate --prod --up",
    "migrate:down:prod": "deno task migrate --prod --down",
    "migrate:reset:prod": "deno task migrate --prod --reset",
    "refresh": "deno cache --reload ./api/dev.ts",
    "db:pull": "deno run -A npm:prisma db pull && deno run -A --unstable npm:prisma generate --data-proxy",
    "db:push": "deno run -A npm:prisma db push && deno run -A --unstable npm:prisma generate --data-proxy"
  },
  "importMap": "./import_map.json",
  "lock": true,
  "lint": {
    "files": {
      "include": [
          "./api/**/*.ts"
      ],
      "exclude": [
        "node_modules/"
      ]
    },
    "rules": {
      "tags": [
        "recommended"
      ],
      "include": [
        "ban-untagged-todo"
      ],
      "exclude": [
        "no-unused-vars",
        "no-explicit-any"
      ]
    }
  },
  "fmt": {
    "files": {
      "include": [
          "./api/**/*.ts"
      ],
      "exclude": [
        "node_modules/"
      ]
    },
    "options": {
      "useTabs": true,
      "lineWidth": 80,
      "indentWidth": 4,
      "singleQuote": true,
      "proseWrap": "preserve"
    }
  },
  "compilerOptions": {
    "lib": [
      "dom",
      "dom.iterable",
      "dom.asynciterable",
      "deno.ns",
      "deno.unstable"
    ],
    "types": [
      "./types.d.ts"
    ]},
  "test": {
    "files": {
      "include": [
        "src/"
      ],
      "exclude": [
        "src/testdata/"
      ]
    }
  }
}

I see you have a release_command in your fly.toml. Is that what’s failing on flyctl deploy (release_command is run once before every deploy)? If so, check the migrate command in the package.json shared above, which doesn’t have the -A switch.

Curiously, unless you’re running it explicitly, the release_command likely isn’t being run when testing the container on your PC.