0

I'm stuck with the below scenarios. This is working fine on the local computer, however with GCP+NodeJs is not working.

Problem - I have an API that generates QR-Images using https://www.npmjs.com/package/qr-image, then it creates a zip using https://www.npmjs.com/package/archiver. Once the archive is done, it uses the nodemailer(https://www.npmjs.com/package/nodemailer) to send the mail.

Now, to store the generated image & archieve processing I'm using the fs library of NPM.

GCP Configuration - It's dynamic/Flexi app engine where the node app is deployed.

The mkdir function is giving the problem. I don't want to use bucket for simple stuff. Is there any other way, I can use the existing code without a tweak to send mail using nodemail (after archiving files(qr codes))?

Tried the API on the local computer working. For the mail test using mailtrap.io which seems to be working well. But not with GCP.

It is clear some GCP tweak is needed or some node/express JS magic.

Code part which is triggering the error -

const codesFolder = 'codes';
if (!fs.existsSync(codesFolder)) {
    fs.mkdirSync(codesFolder);
}

Error from the GCP Log -

2022-11-13 18:48:58 default[20221113t223118]  Processing email
2022-11-13 18:48:58 default[20221113t223118]  /workspace/node_modules/mysql/lib/protocol/Parser.js:437
2022-11-13 18:48:58 default[20221113t223118]        throw err; // Rethrow non-MySQL errors
2022-11-13 18:48:58 default[20221113t223118]        ^
2022-11-13 18:48:58 default[20221113t223118]  Error: EROFS: read-only file system, mkdir 'codes'      at Object.mkdirSync (node:fs:1382:3)      at Query.<anonymous> (/workspace/index.js:243:16)      at Query.<anonymous> (/workspace/node_modules/mysql/lib/Connection.js:526:10)      at Query._callback (/workspace/node_modules/mysql/lib/Connection.js:488:16)      at Query.Sequence.end (/workspace/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)      at Query._handleFinalResultPacket (/workspace/node_modules/mysql/lib/protocol/sequences/Query.js:149:8)      at Query.EofPacket (/workspace/node_modules/mysql/lib/protocol/sequences/Query.js:133:8)      at Protocol._parsePacket (/workspace/node_modules/mysql/lib/protocol/Protocol.js:291:23)      at Parser._parsePacket (/workspace/node_modules/mysql/lib/protocol/Parser.js:433:10)      at Parser.write (/workspace/node_modules/mysql/lib/protocol/Parser.js:43:10) {
2022-11-13 18:48:58 default[20221113t223118]    errno: -30,
2022-11-13 18:48:58 default[20221113t223118]    syscall: 'mkdir',
2022-11-13 18:48:58 default[20221113t223118]    code: 'EROFS',
2022-11-13 18:48:58 default[20221113t223118]    path: 'codes'
2022-11-13 18:48:58 default[20221113t223118]  }

App.YAML file

runtime: nodejs16

env_variables:
  # The following environment variables are set for all instances
  # of the app.
  NODE_ENV : "production"
Ysr Shk
  • 224
  • 5
  • 16
  • 1
    Can you share how are you writing the files and the error you get? – Puteri Nov 13 '22 at 18:15
  • @FerreginaPelona - Added code snippet & error logs from gcp – Ysr Shk Nov 13 '22 at 18:52
  • 2
    Can you confirm you're using Flex and not GAE standard? I've seen that error for GAE standard because it doesn't provide access to the file system. Not sure if it's the same for GAE Flex. You can also take a look at this response (even though it's for PHP) to see if you can get an idea - https://stackoverflow.com/questions/65781347/warning-mkdir-permission-denied-on-google-app-engine-php-application to – NoCommandLine Nov 13 '22 at 19:14
  • I don't see that option for the nodejs. I even tried explicitly adding same in app.yaml but no luck. It is standard.Added app.yaml file in the question for reference. – Ysr Shk Nov 14 '22 at 05:30

2 Answers2

2

There is some confusion. Your post says you're using flex env but your comment says standard env.

If you're using Standard, then your code won't work because Standard doesn't allow you write to the local disk (see Google documentation)

NoCommandLine
  • 5,044
  • 2
  • 4
  • 15
0

As @NoCommandLine was correct, earlier my app.YAML file was not containing the env attribute.

I have used flex with a little bit of tweak in YAML. The updated YAML will look like below -

runtime: nodejs
env: flex

env_variables:
  # The following environment variables are set for all instances
  # of the app.
  NODE_ENV : "production"

beta_settings:
  # The connection name of your instance, available by using
  # 'gcloud beta sql instances describe [INSTANCE_NAME]' or from
  # the Instance details page in the Google Cloud Platform Console.
  cloud_sql_instances: <<<connection_name>>>
Ysr Shk
  • 224
  • 5
  • 16