Running a 1-Click App? Use
instapods env set - it writes to the app’s own config file and restarts the app automatically. The .env-in-app-directory approach below is for custom-code pods (Static, PHP, Node.js, Python, Go).Setting Environment Variables
Option 1: The instapods env command (Recommended)
Set one or more variables straight from the CLI:
--show-values):
/home/instapod/app/.env and restarts the app service. For 1-Click Apps it targets the app’s own config file and restarts the app. Either way you do not need to run reload or restart afterwards.
Option 2: Create a .env File
The manual approach — create a .env file in your app directory via the CLI:
#, a quote or a newline in it: env set
quotes the value so it reads back exactly as typed, and a heredoc does not.
Option 3: Set at Pod Creation (API)
Pass environment variables when creating a pod via the API:/etc/environment, which login shells read. Systemd does not read /etc/environment, so your app service does not inherit them. For anything your app needs to see, use instapods env set (Option 1) — those land in .env and reach your app.
How your app reads them
instapods env set writes KEY=value into /home/instapod/app/.env and restarts your app. Your app
then gets those values two ways, and either one is enough:
- We put them in the process environment for you. The app’s systemd unit reads a copy of your
.envthat InstaPods generates, soprocess.env.API_KEY/os.environ["API_KEY"]/os.Getenv("API_KEY")work with no library and no code. - Your app reads the file itself, with
dotenv,load_dotenv(),godotenv.Load(), or the support already built into Laravel, Symfony, Next and Vite.
Three cases where you still need to read the file yourself
The generated copy is deliberately conservative. It leaves a variable out rather than risk handing your app a value that is subtly different from what you typed. A variable is skipped when:- It is one we manage.
PORT,HOST,HOSTNAMEandNODE_ENVare set by InstaPods so the proxy can reach your app. Setting them yourself is ignored on purpose - if it were not, your app would bind somewhere we do not route to and stop serving traffic. - Its value contains both an apostrophe and a newline (or a carriage return). That combination is the one shape we cannot guarantee systemd reads identically to dotenv, so we leave it out rather than risk corrupting it. A multi-line key or JSON credential with no apostrophe is passed through fine.
- You edited
.envby hand - over SSH, in the Web IDE, or withinstapods exec. We cannot tell what changed, so we switch the generated copy off for that pod until your nextenv setor dashboard save. Your app keeps working; it just has to read the file itself until then.
/home/instapod/app/.env, so a dotenv.config() or
load_dotenv() in your app covers you. Adding one is never wrong.
The rest of this section shows that code for each stack.
Node.js
The systemd service setsNODE_ENV=production by default. That one comes from the unit itself, and
a value you set for it in .env is ignored.
process.env.DATABASE_URL already works with no library. Use the dotenv package if you also want
the file read directly (see the three cases above):
If your pod was created before mid-2026, some values may still live in
/home/instapod/app/.env.local
from an older layout. instapods env set keeps both files in step for the keys you set, so a stale
.env.local cannot shadow them at build time. New keys go to .env.Python
Usepython-dotenv:
PHP
PHP-FPM provides access to system environment variables viagetenv(). For .env files, parse them manually or use a library:
.env for you, so there is nothing to add.
PHP pods have no
app service, so instapods env set has nothing to restart - PHP re-reads the
file on the next request. The exception is a cached Laravel config: if you have run
php artisan config:cache, run it again after changing a variable, or the cached values keep
winning.Go
Usegodotenv:
Static
Static sites don’t run server-side code. For JavaScript apps that need configuration, use aconfig.js file:
Common Pattern: Database Credentials
After installing a database service, get the credentials and set them as env vars:Variables InstaPods sets itself
Four keys belong to the platform, and a value you set for them is not applied:
The write still goes through - the file is yours - but
instapods env set and the dashboard both
warn you at the moment you save, rather than leaving you to discover it as a 502 later:
warnings array on the response.
File permissions
.env holds secrets, so it is not readable by other accounts on the pod: InstaPods keeps it at mode
600, owned by instapod. On a PHP pod it is 640 and group www-data, because php-fpm reads the
file as that group.
If you create the file yourself over SSH, set the mode yourself - chmod 600 .env. InstaPods
re-applies the safe mode on every env set, so the simplest way to fix a file you wrote by hand is
to set one variable through the CLI.
Updating Variables
instapods env set merges: the keys you pass are updated or added, everything else in the file is
left alone, and comments and blank lines survive.
/home/instapod/app/.env by hand instead - over SSH, in the Web IDE, or with
instapods exec - nothing restarts your app, so run instapods pods reload my-app yourself. See
Deploy, Reload, Restart.
A hand edit also switches off the copy we put in the process environment for that pod, because we
cannot tell what you changed. Your app has to read .env itself until your next instapods env set
or dashboard save, which regenerates it.
Multi-line values - a private key, a service-account JSON - are supported. Quote the value in your
shell and instapods env set stores it whole, newlines and all, so it reads back exactly as you
typed it:
Best Practices
- Never commit secrets to git — always use
.envfiles or environment variables - Use defaults in code — Always provide fallback values (
process.env.PORT || 3000) - Load the file anyway — Your app gets the variables from the process environment without any
code, but a
load_dotenv()/dotenv.config()also covers the three cases above where we deliberately leave a variable out of the generated copy. It costs one line and never hurts - Prefer
instapods env setover editing the file — it restarts the app for you and quotes values that contain#, quotes or newlines so they read back exactly as typed - Separate configs — Use different
.envfiles for development vs production