I recently set up a simple project with a .env file and called the env variables in my code with process.env.[variable name] and it totally worked without adding the dotenv package to my project.
Has node incorporated this natively? I tried googling but it didn't turn up any useful information so I am kind of confused. Thought it would be easy to confirm or deny.
Here is my 'app':
// Load the SDK and UUID
var AWS = require('aws-sdk');
var uuid = require('node-uuid');
// Create an S3 client
var s3 = new AWS.S3({
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
});
// Create a bucket and upload something into it
var bucketName = 'node-sdk-sample-' + uuid.v4();
var keyName = 'hello_colorado.txt';
s3.createBucket({Bucket: bucketName}, function() {
var params = {Bucket: bucketName, Key: keyName, Body: 'Coloradoical!'};
s3.putObject(params, function(err, data) {
if (err)
console.log(err)
else
console.log("Successfully uploaded data to " + bucketName + "/" + keyName);
});
});
And my package.json (without dotenv):
{
"dependencies": {
"aws-sdk": ">= 2.0.9",
"node-uuid": ">= 1.4.1"
}
}
Just a thought, could it be related to the fact that I am running my application from the command line with node simple.js? If so, can you explain why?
No, Node.js does not read .env files automatically.
Possible explanations for what's going on:
Perhaps the environment variable you are using is already set in your shell before you run the program.
Perhaps your AWS credentials are being stored/utilized some other way by your machine. (Based on our comment conversation, this looks like the case for you, but I'm including other things to generically help others who might be seeing something similar.)
Perhaps one of the modules you are loading is reading the .env file.
Suggested additional info from #maxwell:
AWS CLI help pages indicate that the precedence for configuration values is:
command line options
environment variables
configuration file
So sounds like the information was coming out of a configuration file for #maxwell.
I also hit the case that .env was read into process.env "automatically", which puzzled me a lot. I then found out it was because I install a zsh plugin called dotenv which will automatically load ENV variables from .env file when you cd into the directory.
Related
I am coding a website with Next.js and I tried to add google Tag Manager.
I followed the tutorial on the Next.js Github example but for some reasons I can't access to my environment variables.
It says my variable is undefined.
I created a file .env.local on my project folder (at the same level as components, node_modules, pages, etc)
In this file I created a variable like this (test purpose) :
NEXT_PUBLIC_DB_HOST=localhost
And on my index page I tried this code :
console.log("test ", process.env.NEXT_PUBLIC_DB_HOST);
But in my console I get a "test undefined".
I tried to put my variable into an .env file instead, without success.
What I am doing wrong ?
This envs just works in Server Side. To access this envs in Client Side, you need declare in the next.config.js
This way:
module.exports = {
reactStrictMode: true,
env: {
BASE_URL: process.env.BASE_URL,
}
}
Create .env (all environments), .env.development (development environment), and .env.production (production environment).
Add the prefix NEXT_PUBLIC to all of your environment variables.
NEXT_PUBLIC_API_URL=http://localhost:3000/
Use with prefix process.env
process.env.NEXT_PUBLIC_API_URL
Stop the server and restart it:
npm run dev
I hope it works.
This solution for latest version of nextJs (above 9)
Restarting the server worked for me.
Edit & save .env.local
Stop the server and restart it, npm run dev
You should get an output on the next line like this:
> klout#0.1.0 dev
> next dev
Loaded env from [path]/.env.local
For those using NextJS +9 and looking for environment variables in the browser, you should use the NEXT_PUBLIC_ prefix. Example:
NEXT_PUBLIC_ANALYTICS_ID=123456789
See documentation for reference.
After spending countless hours on this, I found that there is a tiny little paragraph in both the pre and post nextjs 9.4 documentation:
(Pre-9.4) https://nextjs.org/docs/api-reference/next.config.js/environment-variables (same as this answer)
Next.js will replace process.env.customKey with 'my-value' at build time.
(^9.4) https://nextjs.org/docs/basic-features/environment-variables
In order to keep server-only secrets safe, Next.js replaces process.env.* with the correct values at build time.
Key words being BUILD TIME. This means you must have set these variables when running next build and not (just) at next start to be available for the client side to access these variables.
This is my next.config.js file.
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
env: {
BASE_URL: process.env.NEXT_PUBLIC_SITE_URL,
},
};
module.exports = nextConfig;
Restart the server and it worked fine. using Nextjs 12.1.0 with typescript
In my case, Im pasting REACT_APP_API_URL instead of NEXT_PUBLIC_API_URL.
Adding with the most recent version of the documentation on this, v12+.
Using the next.config.js file you can specify server and client variables:
module.exports = {
serverRuntimeConfig: {
// Will only be available on the server side
mySecret: 'secret',
secondSecret: process.env.SECOND_SECRET, // Pass through env variables
},
publicRuntimeConfig: {
// Will be available on both server and client
staticFolder: '/static',
},
}
You can still use an env.local file, and pass the variable in to the next.config.js file. For example:
publicRuntimeConfig: {
DB_URL: process.env.DB_URL
}
And then you can access the variable like this:
import getConfig from 'next/config';
const { publicRuntimeConfig } = getConfig();
publicRuntimeConfig.DB_URL;
I am learning how to configure my Node.js App environment. For this I am using config module.
Below is my index.js file:
`
const config=require('config');
const express=require('express');
const app=express();
app.use(express.json()); //BUILT-IN EXPRESS MIDDLEWARE-FUNCTION
//CONFIGURATION
console.log('Current Working Environment:',process.env.NODE_ENV);
console.log('Name is:', config.get('name'));
console.log('Server is:', config.get('mail.host'));
console.log('Password is:', config.get('mail.password'));
`
I set NODE_ENV to production by the power shell command: $env:NODE_ENV="production".
My production.json file inside the config folder is:
`{
"name":"My Productoin Environmet",
"mail":{
"host": "Prod-Environment"
}
}`
And custom-environment-variables.json file is:
`{
"mail":{
"passwrod":"app_password"
}
}`
I set app_password to 12345678 by the power shell command : $env:app_password="12345678"
config.get() is supposed to look at various sources to look for this configurations including, json files, configuration files and also environment variables. But whenever I run my app, I get the following error:
`throw new Error('Configuration property "' + property + '" is not defined'); Error: Configuration property "mail.password" is not defined`
If I remove the line : console.log('Password is:', config.get('mail.password')); everything goes well. Please, guide me what is the solution?
Firstly you have a lot of syntactical errors for example in
custom-environment-variables.json
{
"mail":{
"password":"app_password"
}
}
Now if u need to store the password of your mail server in the environment variables
On windows
$env:app_password=12345
On Linux and OSX:
export app_password=12345
how to run ?
app.js
const config = require("config");
console.log("Mail Password: " + config.get("mail.password"));
i had the same problem because i didn't define an environment variable for storing the password of the mail server. So, my suggestion will be define your environment variable for storing the password using the below command line (mac) and then your code should work.
export app_password=/* the password you want to set */
how to define an environment variable for storing the password of the mail server.
While defining environment variables in command_prompt don't put space on either side of '=' sign.....
eg:
set app_password = 123456 -----> is wrong way
set app_password=123456 -----> will work
The issue in 99% of cases is in the name of the file in the config folder, storing your custom variables
To add on: make sure your file has .json extension.
How do i find the current path of the executing file when its in a meteor package?
I have a meteor package that needs to dynamically include a list of assets.
the fs.readdirSync command needs a full path it seems.
when running the package inside an app, things are fine, as the path to the package is easily deduced. Like this:
var path = Npm.require("path");
var fs = Npm.require("fs");
// normally found inside an app/packages dir like:
var packagePath = path.join(path.resolve("."), "packages", "reactive-ace");
var srcPath = path.join(packagePath, "vendor", "ace", "src") // files rel to package root
var files = fs.readdirSync(srcPath);
files.forEach(function(file){
console.log("add_file", file)
if (file === "snippets"){return;}
addPath = path.join("vendor", "ace", "src", file);
api.add_files(addPath, "client", {isAsset: true});
});
However, when i am local developing, using $PACKAGE_DIRS - the package repo is actually somewhere remote on my system. But I'm unable to deduce this just from the package.js
I tried __dirname and also require.main.filename but these both are unknown in the context of building a meteor package.
My current hack involves parsing process.env.PACKAGE_DIRS but that is ugly.
Any pointers appreciated.
In production I have AWS credentials stored as heroku config variables.
In development I want to include the config details in config/local.js, but how do I access the config details in a controller?
local.js contains:
module.exports = {
aws_key: "...", aws_secret: "..."
}
In my controller I have tried aws_key, config.aws_key, and others - but no luck. Is there a main app namespace that I can use to scope into the properties exported by local.js?
I am new to sails and I feel like this should be straight forward - any help would be appreciated.
Solution found. Step 3 was where I was having trouble.
tl;dr
What I didn't realize was that the module.exports.thing makes the thing object available through sails.config.thing. Good to know.
1) I created a new file at config/aws.js with the contents
// Get heroku config values
module.exports.aws = {
key: process.env.AWS_KEY,
secret: process.env.AWS_SECRET
}
2) In local.js put the actual AWS creds (this won't end up in the repository since sails automatically ignores local.js using gitignore).
aws: {
key: actual-key,
secret: actual-secret
}
This allows for local testing where we don't have access to the heroku config settings, while protecting these values from being exposed in a github repo.
3) Now, to access in the controller:
var aws_config = sails.config.aws;
AWS.config.update({
accessKeyId: aws_config.key,
secretAccessKey: aws_config.secret
});
I've been trying for many days now to upload a file (message.txt) to aws s3 using knox and node js.
I keep having a signature doesnt match error.
my code in node js (upload was not working so i'm just trying to do a get) :
var client = knox.createClient({
key: 'myAWSkey'
, secret: 'mySecretKey'
, bucket: 'mybucket'
, endpoint: 'mybucket.s3-eu-west-1.amazonaws.com'
});
client.get('/').on('response', function(res){
console.log(res.statusCode);
console.log(res.headers);
res.setEncoding('utf8');
res.on('data', function(chunk){
console.log(chunk);
});
}).end();
I also tried the amazon to compare the test signature with many different methods like this one : html and python version
Nothing worked for me, I'm probably a bit lost in the process...
If someone could give me some big lines to guide me and/or a script to generate correctly a signature in javascript/node js I would be very grateful.
You might want to try the AwsSum library. It's actively maintained and also comes with a load of examples and another repo with more fully featured scripts.
https://github.com/appsattic/node-awssum/
And for your needs, there is an example upload script in the scripts repo (separate GitHub project):
https://github.com/appsattic/node-awssum-scripts/blob/master/bin/amazon-s3-upload.js
Let me know if you need any help or if you get on ok. Disclaimer: I'm the author of AwsSum. :)
I just struggled with this issue for a few days. Assuming you're on Windows, it seems like it's an issue on Knox's end. Apparently the problem has been solved, but the solution has not not pulled into the main project yet.
See this thread: https://github.com/LearnBoost/knox/issues/56
My workaround was to just remove the knox library and clone this repository into my node_modules folder: https://github.com/domenic/knox.git
Hope that helps!
For NodeJS, there is an API which helps to generate Signature. It is available at NPM repo with name aws4.
Can refer from link: https://www.npmjs.com/package/aws4
To download and install, use below command:
npm i aws4
Can add in package.json file
{
"dependencies": {
"aws4": "^1.11.0",
"https": "^1.0.0",
"crypto": "^1.0.1"
}
}
Following parameters are used for generating signature:
host: host of service, mandatory
path: Path of the file being uploaded, mandatory
service: Service name e.g. s3
region: Region name e.g. us-east-1
method: HTTP method e.g. GET, PUT
accessKeyId: Access Key ID for the service, mandatory
secretAccessKey: Secret for access key id, mandatory
sessionToken: Temporary session token, optional
Use below code to upload a file:
var https = require('https')
var aws4 = require('aws4')
var crypto = require('crypto');
var fs = require('fs');
var fileBuffer = fs.readFileSync('1.jpg'); //File name from local which need to upload
var hashSum = crypto.createHash('sha256');
hashSum.update(fileBuffer);
var hex = hashSum.digest('hex'); //Generate SHA256 from the file
var opts = aws4.sign({
host: '<host name for the s3 service>',
path: '<bucket and file path in s3>',
service: 's3',
region: 'us-east-1',
method: 'PUT',
headers: {
'X-Amz-Content-Sha256': hex
},
body: undefined
}, {
accessKeyId: '<access key>',
secretAccessKey: '<secret key>'
sessionToken: '<session token>'
}
)
opts.path = '<complete path: https://host+bucket+filepath>';
opts.headers['Content-Type'] = 'image/jpeg'; //Content type of the file
opts.headers['User-Agent'] = 'Custom Agent - v0.0.1'; //Agent name, optional
opts.headers['Agent-Token'] = '47a8e1a0-87df-40a1-a021-f9010e3f6690'; // Agent unique token, optional
opts.headers['Content-Length'] = fileBuffer.length; //Content length of the file being uploaded
console.log(opts) //It will print generated Signature
var req = https.request(opts, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.write(fileBuffer);
req.end();
Note: The SHA256 is generated manually and passed into the argument before generating signature and body set as undefined in aws4.sign() method. This important when uploading a file as binary data therefore, SHA256 is generated and set before aws4.sign() method call.
This same API can be used for all different calls e.g. GET call for file download.
The sessionToken is optional as it is only required for the cases where temporary session token is generated for accessing S3 service.