How can I pass NODE_ENV into npm run command as parameter?
Example package.json file:
NODE_ENV=8080
...
"script": {
"start": "http-server --port $NODE_ENV" // or something similar that
}
...
Note that NODE_ENV is set by another process, the npm run only can be read from it.
I met this problem when deploying my app into heroku (they will automatically set NODE_ENV). I found another solution for this problem on heroku but I still wanna to know if there is a way to pass NODE_ENV into npm run command.
Environment variables can be used directly, as you have tried to do:
{
"scripts": {
"start": "echo $FOO"
}
}
yarn start and npm run start will both echo the value of the FOO environment variable if you run this start script. I think you have two other problems.
First, you are trying to use the environment variable NODE_ENV to set the port your application listens on. Heroku provides this value via the PORT environment variable, not NODE_ENV. NODE_ENV will contain something like production.
Second, you are trying to set an environment variable in your package.json. This is possible, but it will override the value Heroku sets. Instead, consider using a .env file in development. Its contents can look something like this:
PORT=8080
You'll need tooling to load this file and populate your environment. dotenv is a popular choice. Note that your .env file should not be committed, so consider also adding it to your .gitignore.
There are other methods to set environment variables in your development environment, and any of them will work if you prefer.
Putting this all together, your package.json should contain something like
{
"scripts": {
"start": "http-server --port $PORT"
}
}
You are trying to accept value inside string in double quotes which is wrong. You can access in the following ways:
Option 1:
You need to concat two strings.
NODE_ENV=8080
"script": {
"start": "http-server --port "+NODE_ENV
}
Option 2:
You can use template literals
NODE_ENV=8080
"script": {
"start": `http-server --port ${NODE_ENV}`
}
In Option 2 NODE_ENV will be replaced with the actual value of the variable
Related
I am trying to accomplish the following -> Right now I use cypress to run e2e tests. It is being launched by npm command. I have several environments and different user permission. I created a shell script, where I have stored value of environment and user permission rights. What I want to do is to have opportunity to run npm command with parameters to change the value of variable from shell script. Could someone give a clue, is it even possible? The expected behaviour is to write something like:
npm run cy dev3,full
And have the opportunity to change the value of shell script variable to launch necessary environament and change value of user permissions.
package.json command:
"scripts": {
"cy": "./scripts/cypress.sh",
}
cypress.sh file content
#!/usr/bin/env bash
DEV_ENV="${DEV_ENV:-"dev3"}"
USER_TYPE="${USER_TYPE:-"full"}"
COMMAND="cypress open \
--browser chrome \
--config baseUrl=https://environment-$DEV_ENV.com \
--env DEV_ENV=https://environment-$DEV_ENV.com,USER_TYPE=$USER_TYPE
"
eval $COMMAND
Are you trying to change the environment variables seen in cypress.sh? If so, you can just execute npm run like this:
DEV_ENV=dev2 USER_TYPE=empty npm run cy
and it will change the value of DEV_ENV and USER_TYPE.
If you want to strictly run it by using the format you gave (npm run cy dev3,full), the args dev3,full are passed on to cypress.sh, so you can just parse the arguments directly in cypress.sh:
if [ ! -z "$1" ]; then
# do whatever here...
fi
I have a code that reads port number from environment variable or from config. Code looks like this
const port = process.env.PORT || serverConfig.port;
await app.listen(port);
To run app without defining environment variable, I run following yarn command.
yarn start:dev
This command works successfully in Linux shell and Windows command line.
Now, I want to pass environment variable. I tried following,
PORT=2344 yarn start:dev
This commands works successfully in Linux shell but failing in Windows command line. I tried following ways but couldn't get it to work.
Tried: PORT=2344 yarn start:dev
I got error: 'PORT' is not recognized as an internal or external command,
operable program or batch file.
Tried: yarn PORT=2344 start:dev
I got error: yarn run v1.17.3
error Command "PORT=2344" not found.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Any idea please? I know, I can define environment variables from System Properties in Windows. But any way if I can do it from command line?
i'd suggest you use the NPM module called cross-env. it allows adding particular env variables on the command line regardless of platform. with that said, you may try:
$ cross-env PORT=2344 yarn start:dev
You can chain commands on the Windows command prompt with &(or &&). To set an environment variable you need to use the set command.
The result should look like this: set PORT=1234 && yarn start:dev.
Found a solution for this problem in Windows command prompt.
Create a .env file in project root folder (outside src folder).
Define PORT in it. In my case, contents of .env file will be,
PORT=2344
Run yarn start:dev
Application will use port number that you have specified in .env file.
Put .env file at root. Then following command will expose content of .env file and then run yarn start command
$ source .env && yarn start
or this command
$ export $(cat .env) && yarn start
If update any variable in .env then close the terminal and open new terminal window and can again run above command. Or else can also run unset command to remove existing var.
unset VAR_NAME
You can use popular package dotenv:
create a file .env in root directory
put all your env vars
e.g.:
ENV=DEVELOPMENT
run your code like this
$ node -r dotenv/config your_script.js
here the explanation:
[https://github.com/motdotla/dotenv#preload]
To define environment variables in the Windows command prompt we can use the set command, you can then split your call into two lines.
set PORT=2344
yarn start:dev
The set command persists within the current command prompt, so you only need to run it once.
The equivalent command in bash is 'export'.
FYI (not a direct answer). I was attempting this in VS Code - passing .env variables through yarn to a JavaScript app. Google had very few examples so I'm sharing this for posterity as it's somewhat related.
The following simply substitutes text normally placed directly into the package.json or script file. Use this to quickly obfuscate or externalize your delivery configurations.
In Environment Variable File (.env)
PORT=2344
In Yarn File (package.json)
source .env; yarn ./start.sh --port $PORT
In Yarn Script (start.sh)
#!/bin/bash
while [ $? != 0 ]; do
node dist/src/index.js $1; #replace with your app call#
done
The app then accepts port as a variable. Great for multi-tenant deployments.
How do I pass a parameter? When I run "yarn generate" it will make both a "-p" and a "test" directory. But it works well when I run "mkdir -p test" in bash. I tried to [-p] as well but it only creates that directory.
"scripts": {
"generate": "mkdir -p test"
}
Although I could not reproduce the issue that you mentioned (my config: node v8.11.1 and yarn v1.2.1, latest MacOS), according to the yarn docs, you can pass the arguments to yarn script by appending them normally, like so:
yarn generate -p test
In this case your npm (yarn) scripts config (in the package.json, I assume) would look like
"scripts": {
"generate": "mkdir"
}
If you're using Windows, you indeed won't have the mkdir -p flag (read this). In order to make what you want (check if the folder does not exist and if so, create one) you'd need to use some cmd commands. So your package.json will contain smth like
"scripts": {
"generate": "IF NOT EXIST test mkdir test"
}
During the build stage of my docker images, i would like to set some environment variables automatically for every subsequent "RUN" command.
However, I would like to set these variables from within the docker conatiner, because setting them depends on some internal logic.
Using the dockerfile "ENV" command is not good, because that cannot rely on internal logic. (It cannot rely on a command run inside the docker container)
Normally (if this were not docker) I would set my ~/.profile file. However, docker does not load this file in non-interactive shells.
So at them moment I have to run each docker RUN command with:
RUN bash -c "source ~/.profile && do_something_here"
However, this is very tedious (and unclean) when I have to repeat this every time I want to run a bash command. Is there some other "profile" file I can use instead.
you can try setting the arg as env like this
ARG my_env
ENV my_env=${my_env}
in Dockerfile,
and pass the 'my_env=prod' in build-args so that you can use the set env for subsequent RUN commands
you can also use env_file: option in docker compose yml file in case of a stack deploy
I had a similar problem and couldn't find a satisfactory solution. What I did was creating a script that would source the variables, then do the operation. I would then rewrite the RUN commands in the Dockerfile to use that script instead.
In your case, if you need to run multiple commands, you could create a wrapper that loads the variables, runs the command given as argument, and include that script in the docker image.
On python/flask/gunicorn/heroku stack, I need to set an environment variable based on the content of another env variable.
For background, I run a python/Flask app on heroku.
I communicate with an addon via a environment variable that contains credentials and url.
The library I use to communicate with the addon needs that data, but needs it in a different format.
Also, it needs it as an environment variable.
So far, I had cloned and reformatted the environment variable manually, but that just brought disaster because the add-on provider was changing passwords.
OK, so I need to automate reading one environment variable and setting another, before the library starts looking for it.
The naive approach I tried was (file app.py):
app = Flask(__name__, ...)
env_in = os.environ['ADDON_ENV_VAR']
os.environ['LIB_ENV_VAR'] = some_processing(env_in)
...
if __name__ == '__main__':
app.run(host='0.0.0.0', port='5000')
That works fine when doing python app.py for debugging, but it fails when running via gunicorn app:app -b '0.0.0.0:5000' (as a Procfilefor foreman) for deploying a real webserver. In the second case, the env var doesn't seem to make it to the OS level. I'm not sure about how wsgi works, but maybe the environment changes once gunicorn starts running the app.
What can I do to have the environment variable set at the place it's needed?
you could also set the enviroment variables at run time as such
gunicorn -b 0.0.0.0:5000 -e env_var1=enviroment1 -e env_var2=environment2
OK, so the answer (via Kenneth R, Heroku) is to set the environment before running gunicorn. I.e. write a Procfile like
web: sh appstarter.sh
which calls a wrapper (shell, python, ..) that sets up the environment variable and then runs the gunicorn command, like for example
appstarter.sh:
export LIB_ENV_VAR=${ADDON_ENV_VAR}/some/additional_string
gunicorn app:app -b '0.0.0.0:5000'
Just in case it helps anyone else out there.
Set environment variable (key=value).
Pass variables to the execution environment. Ex.:
$ gunicorn -b 127.0.0.1:8000 --env FOO=1 test:app
and test for the foo variable environment in your application.
from: http://docs.gunicorn.org/en/stable/settings.html