devops2024-02-01Β·10 minΒ·326/348

Linux Environment Variables: Configuration and Management

Managing Linux environment variables for applications, including PATH, configuration files, and best practices for development and production.

Introduction

Environment variables control the behavior of Linux applications and shells. From PATH to JAVA_HOME, these key-value pairs configure everything from where executables are found to how applications connect to databases. Understanding how to manage them is essential for development and deployment. This post covers environment variable management on Linux.

Environment

The examples use Bash on Ubuntu 22.04 LTS, with applications requiring specific environment configurations.

echo $SHELL
# /bin/bash

bash --version | head -1
# GNU bash, version 5.1.16(1)-release

Problem

Applications fail to start because environment variables are not set:

java -jar app.jar
# Error: JAVA_HOME not set

./deploy.sh
# deploy.sh: line 3: node: command not found
# The PATH does not include the Node.js installation

Analysis

Environment variables are set at different levels:

LevelFileScope
System-wide/etc/environmentAll users
System-wide/etc/profileAll users (login shells)
User~/.bashrcCurrent user (interactive)
User~/.profileCurrent user (login)
Sessionexport VAR=valueCurrent session only

Solution

1. Check current environment

# View all environment variables
env

# View specific variable
echo $HOME
# /home/user

echo $PATH
# /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin

# View specific variable
echo $JAVA_HOME
# (empty if not set)

2. Set environment variables temporarily

# Set for current session
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH

# Verify
java -version
# openjdk version "17.0.9" 2023-10-17

3. Set environment variables permanently

# For user-specific variables
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc

# Reload
source ~/.bashrc

4. Set system-wide environment variables

# /etc/environment (key=value format, no export)
sudo nano /etc/environment
# JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
# NODE_HOME="/usr/local/node"

# /etc/profile.d/ for modular configuration
sudo nano /etc/profile.d/java.sh
# export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
# export PATH=$JAVA_HOME/bin:$PATH

5. Configure application-specific variables

# Create a .env file for your application
cat > /opt/myapp/.env << 'EOF'
DATABASE_URL=postgresql://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379
SECRET_KEY=abc123def456
LOG_LEVEL=info
EOF

# Load in your application
source /opt/myapp/.env

6. Use environment variables in systemd

# /etc/systemd/system/myapp.service
[Service]
Environment="JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64"
EnvironmentFile=/opt/myapp/.env
ExecStart=/usr/bin/java -jar /opt/myapp/app.jar

7. Set PATH correctly

# Add custom directory to PATH
export PATH=$HOME/bin:$HOME/.local/bin:$PATH

# Add for all users
echo 'export PATH=/opt/myapp/bin:$PATH' | sudo tee /etc/profile.d/myapp.sh

8. Unset environment variables

# Remove from current session
unset JAVA_HOME

# Remove from .bashrc
sed -i '/JAVA_HOME/d' ~/.bashrc

9. Use env command to run with modified environment

# Run with specific variables
env JAVA_HOME=/usr/lib/jvm java -jar app.jar

# Run without any variables
env -i /opt/myapp/start.sh

10. Debug environment issues

# Show where a variable is set
grep -r "JAVA_HOME" /etc/profile.d/ ~/.bashrc ~/.profile

# Show effective environment for a process
cat /proc/$(pidof myapp)/environ | tr '\0' '\n'

11. Use direnv for directory-specific variables

# Install direnv
sudo apt-get install direnv

# Add to ~/.bashrc
eval "$(direnv hook bash)"

# Create .envrc in your project
cat > .envrc << 'EOF'
export DATABASE_URL=postgresql://localhost/mydb
export REDIS_URL=redis://localhost:6379
EOF

# Allow it
direnv allow

Lessons Learned

Environment variables should be managed at the appropriate level: system-wide for shared services, user-specific for development tools, and application-specific for service configuration. Use /etc/profile.d/ for modular system configuration. And always use env files for application secrets, never hardcode them in scripts.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.