Overview
gopsutil allows you to override the default locations of system directories using environment variables. This is particularly useful when:
Running gopsutil inside containers to monitor the host system
Testing with mock filesystem fixtures
Working with chrooted environments
Accessing systems with non-standard directory layouts
Environment variables provide a simpler alternative to context-based configuration when you don’t need programmatic control.
Supported Environment Variables
The following environment variables can be set to override default system paths:
Variable Default Description Example Use Case HOST_PROC/procLinux proc filesystem Container monitoring HOST_SYS/sysLinux sys filesystem Hardware information HOST_ETC/etcConfiguration directory OS detection, release info HOST_VAR/varVariable data directory User sessions, logs HOST_RUN/runRuntime data directory PID files, sockets HOST_DEV/devDevice filesystem Disk devices HOST_ROOT/Root filesystem Docker detection HOST_PROC_MOUNTINFO(empty) Mount information override Custom mount tables
These environment variables are primarily applicable to Linux systems. Other platforms may ignore them or use them differently.
Basic Usage
Setting Environment Variables
Shell
Dockerfile
Docker Compose
Kubernetes
# Set single variable
export HOST_PROC = / host / proc
# Set multiple variables
export HOST_PROC = / hostfs / proc
export HOST_SYS = / hostfs / sys
export HOST_ETC = / hostfs / etc
# Run your application
./myapp
How Environment Variables Are Used
Gopsutil’s internal common package uses these environment variables to construct paths:
// From internal/common/common.go
func HostProc ( combineWith ... string ) string {
return GetEnv ( "HOST_PROC" , "/proc" , combineWith ... )
}
func HostSys ( combineWith ... string ) string {
return GetEnv ( "HOST_SYS" , "/sys" , combineWith ... )
}
func HostEtc ( combineWith ... string ) string {
return GetEnv ( "HOST_ETC" , "/etc" , combineWith ... )
}
// GetEnv retrieves the environment variable key.
// If it does not exist it returns the default.
func GetEnv ( key , dfault string , combineWith ... string ) string {
value := os . Getenv ( key )
if value == "" {
value = dfault
}
return combine ( value , combineWith )
}
The combineWith parameter allows paths to be constructed by joining the base directory with subdirectories, ensuring correct path separators across platforms.
Configuration Priority
When resolving paths, gopsutil follows this priority order:
Context Values (Highest Priority)
Values set programmatically via context.Context override everything else. ctx := context . WithValue ( context . Background (),
common . EnvKey ,
common . EnvMap { common . HostProcEnvKey : "/custom/proc" },
)
// Uses /custom/proc regardless of environment variables
Environment Variables
If no context value is set, gopsutil checks for environment variables. export HOST_PROC = / container / proc
# Your program uses /container/proc
Default Values (Lowest Priority)
If neither context nor environment variables are set, platform defaults are used. // Uses /proc on Linux by default
v , _ := mem . VirtualMemory ()
Common Use Cases
Docker Container Monitoring Host
Monitor the host system from inside a Docker container:
Dockerfile
Run Container
Application Code
FROM golang:1.21-alpine
WORKDIR /app
COPY . .
RUN go build -o host-monitor .
# Configure environment for host monitoring
ENV HOST_PROC=/host/proc \
HOST_SYS=/host/sys \
HOST_ETC=/host/etc \
HOST_DEV=/host/dev
CMD [ "./host-monitor" ]
Testing with Mock Filesystem
Use environment variables to point to test fixtures:
package mypackage_test
import (
" os "
" testing "
" github.com/shirou/gopsutil/v4/host "
)
func TestHostInfo ( t * testing . T ) {
// Set environment variables to test fixtures
os . Setenv ( "HOST_PROC" , "testdata/proc" )
os . Setenv ( "HOST_SYS" , "testdata/sys" )
os . Setenv ( "HOST_ETC" , "testdata/etc" )
defer func () {
os . Unsetenv ( "HOST_PROC" )
os . Unsetenv ( "HOST_SYS" )
os . Unsetenv ( "HOST_ETC" )
}()
info , err := host . Info ()
if err != nil {
t . Fatalf ( "Failed to get host info: %v " , err )
}
// Test against known fixture values
if info . Platform != "ubuntu" {
t . Errorf ( "Expected ubuntu, got %s " , info . Platform )
}
}
Kubernetes DaemonSet
Deploy as a DaemonSet to monitor all nodes:
apiVersion : apps/v1
kind : DaemonSet
metadata :
name : node-monitor
namespace : monitoring
spec :
selector :
matchLabels :
app : node-monitor
template :
metadata :
labels :
app : node-monitor
spec :
hostNetwork : true
hostPID : true
containers :
- name : monitor
image : myregistry/node-monitor:latest
env :
- name : HOST_PROC
value : "/host/proc"
- name : HOST_SYS
value : "/host/sys"
- name : HOST_ETC
value : "/host/etc"
- name : HOST_VAR
value : "/host/var"
- name : HOST_RUN
value : "/host/run"
- name : HOST_DEV
value : "/host/dev"
- name : HOST_ROOT
value : "/host"
volumeMounts :
- name : proc
mountPath : /host/proc
readOnly : true
- name : sys
mountPath : /host/sys
readOnly : true
- name : etc
mountPath : /host/etc
readOnly : true
- name : var
mountPath : /host/var
readOnly : true
- name : run
mountPath : /host/run
readOnly : true
- name : dev
mountPath : /host/dev
readOnly : true
- name : root
mountPath : /host
readOnly : true
resources :
requests :
memory : "64Mi"
cpu : "100m"
limits :
memory : "128Mi"
cpu : "200m"
volumes :
- name : proc
hostPath :
path : /proc
- name : sys
hostPath :
path : /sys
- name : etc
hostPath :
path : /etc
- name : var
hostPath :
path : /var
- name : run
hostPath :
path : /run
- name : dev
hostPath :
path : /dev
- name : root
hostPath :
path : /
Systemd Service
Create a systemd service with custom paths:
[Unit]
Description =System Monitor
After =network.target
[Service]
Type =simple
User =monitor
Group =monitor
WorkingDirectory =/opt/monitor
Environment = "HOST_PROC=/custom/proc"
Environment = "HOST_SYS=/custom/sys"
ExecStart =/opt/monitor/bin/monitor
Restart =on-failure
RestartSec =10
[Install]
WantedBy =multi-user.target
Implementation Details
The environment variable implementation in gopsutil:
Source Code: common.go:344-443
// GetEnvWithContext retrieves the environment variable key.
// If it does not exist it returns the default.
// The context may optionally contain a map superseding os.Getenv.
func GetEnvWithContext ( ctx context . Context , key , dfault string , combineWith ... string ) string {
var value string
if env , ok := ctx . Value ( common . EnvKey ).( common . EnvMap ); ok {
value = env [ common . EnvKeyType ( key )]
}
if value == "" {
value = os . Getenv ( key )
}
if value == "" {
value = dfault
}
return combine ( value , combineWith )
}
// GetEnv retrieves the environment variable key.
// If it does not exist it returns the default.
func GetEnv ( key , dfault string , combineWith ... string ) string {
value := os . Getenv ( key )
if value == "" {
value = dfault
}
return combine ( value , combineWith )
}
func combine ( value string , combineWith [] string ) string {
switch len ( combineWith ) {
case 0 :
return value
case 1 :
return filepath . Join ( value , combineWith [ 0 ])
default :
all := make ([] string , len ( combineWith ) + 1 )
all [ 0 ] = value
copy ( all [ 1 :], combineWith )
return filepath . Join ( all ... )
}
}
func HostProc ( combineWith ... string ) string {
return GetEnv ( "HOST_PROC" , "/proc" , combineWith ... )
}
func HostSys ( combineWith ... string ) string {
return GetEnv ( "HOST_SYS" , "/sys" , combineWith ... )
}
func HostEtc ( combineWith ... string ) string {
return GetEnv ( "HOST_ETC" , "/etc" , combineWith ... )
}
func HostVar ( combineWith ... string ) string {
return GetEnv ( "HOST_VAR" , "/var" , combineWith ... )
}
func HostRun ( combineWith ... string ) string {
return GetEnv ( "HOST_RUN" , "/run" , combineWith ... )
}
func HostDev ( combineWith ... string ) string {
return GetEnv ( "HOST_DEV" , "/dev" , combineWith ... )
}
func HostRoot ( combineWith ... string ) string {
return GetEnv ( "HOST_ROOT" , "/" , combineWith ... )
}
Best Practices
Use Read-Only Mounts When mounting host directories into containers, always use :ro (read-only) to prevent accidental modifications.
Document Requirements Clearly document which environment variables your application expects and why they’re needed.
Provide Defaults Design your application to work with default values when environment variables aren’t set.
Test Both Ways Test your application with both environment variables and default paths to ensure compatibility.
Troubleshooting
Environment variables not working
Make sure:
Variables are exported in the shell: export HOST_PROC=/host/proc
Variables are set before the application starts
Variable names match exactly (case-sensitive)
You’re not using context-based configuration which takes precedence
Debug by printing the resolved paths: import " github.com/shirou/gopsutil/v4/internal/common "
fmt . Println ( "PROC:" , common . HostProc ())
fmt . Println ( "SYS:" , common . HostSys ())
Permission denied errors in containers
Ensure host directories are properly mounted: docker run -v /proc:/host/proc:ro -v /sys:/host/sys:ro ...
For Kubernetes, verify hostPath volumes are configured: volumes :
- name : proc
hostPath :
path : /proc
Check priority order:
Context values override everything
Environment variables are checked next
Defaults are used last
If using context, environment variables are ignored: // This ignores HOST_PROC environment variable
ctx := context . WithValue ( context . Background (),
common . EnvKey ,
common . EnvMap { common . HostProcEnvKey : "/override/proc" },
)
Paths not joining correctly
Let gopsutil handle path construction: // Don't do this:
// path := os.Getenv("HOST_PROC") + "/meminfo"
// Do this:
path := common . HostProc ( "meminfo" )
// Result: /proc/meminfo or $HOST_PROC/meminfo
Next Steps
Context Usage Learn programmatic configuration with contexts
Caching Optimize performance with caching
Docker Examples See complete Docker integration examples
Architecture Understand gopsutil’s design principles