11 How to interact with the Virtual Machine (VM) that hosts PIP
11.1 Access and Session Management
11.1.1 Login to the VM
Go to PrivX.
Use SSO login (World Bank Authenticator App).
In the Connections tab, select the VM you want:
- Development:
Linux-wzlxdpip01.worldbank.org - QA:
Linux-wzlxqpip01.worldbank.org - Production:
Linux-wzlxppip01.worldbank.org
- Development:
Once connected, switch to the
srvpipuser:sudo su - srvpip
11.1.2 Copy, Paste, and Keyboard Shortcuts
| Shortcut | Action | Notes |
|---|---|---|
| Ctrl + C | Stop the current running process | e.g. stop an infinite loop or hanging R process |
| Ctrl + D | Log out of the current shell | Ends your session as srvpip |
| Shift + Ctrl + V | Paste from clipboard | Works in most PrivX terminals |
| Shift + Insert | Paste (alternative) | Often easier in remote shells |
Notice that Ctrl + C does not copy text in terminal. You only need to highlight with your mouse the section you want to copy. Once you stopped highlighting, the text is copied to your clipboard automatically.
11.2 Understanding the Environment
11.2.1 Users and Permissions
- Your account: initial login via PrivX (not root)
srvpipuser: used to manage Docker containersrootuser: required for system-level commands; use only withsudo
Common prefixes:
docker→ run Docker as normal user (often fails without permissions)sudo docker→ correct way when managing containerssudo su - srvpip→ switch to service account context
11.2.2 Architecture Overview
+-------------------------------------------------------------+
| Linux VM (Host) |
| |
| Persistent Data: |
| /Data/pip/files/data <---+ |
| | (bind mount) |
| v |
| --------------------------------------------------------- |
| | Docker Container: povertyscoreapi | |
| | | |
| | - Mounts /Data/pip/files/data → /Data | |
| | - Runs: Rscript /app/main.R | |
| | - Listens on port 8080 (internal) | |
| --------------------------------------------------------- |
| ^ |
| | |
| Host Port 80 <--------------+ (mapped to container 8080) |
+-------------------------------------------------------------+
Legend: - Data written to /Data inside the container is actually stored on the host at /Data/pip/files/data. - The API runs inside the container on port 8080, but is accessible from outside the VM on port 80.
11.3 Essential Docker Commands (Cheat Sheet)
| Task | Command | Notes | |
|---|---|---|---|
| List all containers | sudo docker ps -a |
Shows running & stopped | |
| View logs | sudo docker logs -f povertyscoreapi |
Add --tail 200 to see last lines |
|
| Enter container shell | sudo docker exec -it povertyscoreapi /bin/bash |
For interactive debugging | |
| Check mounted volumes | sudo docker inspect povertyscoreapi | grep Mounts -A 5 |
See /Data source |
|
| Delete stopped containers | sudo docker container prune |
Cleans unused ones | |
| Delete old images | sudo docker image prune -a |
Be cautious — removes all unused | |
| Check Docker service status | sudo systemctl status docker |
Confirms Docker is active |
11.4 Managing Data
11.4.1 Data on the VM (Persistent)
Main data location:
cd /Data/pip/files/dataInspect space usage:
df -h | grep Data du -h --max-depth=1 | sort -hPreview files safely:
ls -lahView folder sizes:
du -sh *
11.4.1.1 🔍 Find large or old files
find /Data/pip/files/data -type f -mtime +365 | head -n 2011.4.2 Data Inside Containers (Ephemeral)
Check where containers mount volumes:
sudo docker inspect povertyscoreapi | grep Mounts -A 5You’ll see:
"Mounts": [
{
"Type": "bind",
"Source": "/Data/pip/files/data",
"Destination": "/Data"
}
]That means:
- Inside container →
/Data - On host →
/Data/pip/files/data
11.4.2.1 Access via container shell:
sudo docker exec -it povertyscoreapi ls -lh /Data11.4.3 Safe Deletion and Cleanup
Preview first:
ls -d /Data/pip/files/data/project_*Delete specific folders:
rm -rf /Data/pip/files/data/folder1 /Data/pip/files/data/folder2Delete all contents but keep parent folder:
rm -rf /Data/pip/files/data/*Move to trash instead of deleting:
mkdir -p /Data/pip/files/trash
mv /Data/pip/files/data/folder1 /Data/pip/files/trash/⚠️ Caution: rm -rf is irreversible — always check with ls first.
11.5 Diagnosing API or Container Issues
11.5.1 Check Container State
sudo docker ps -aGet detailed exit info:
sudo docker inspect povertyscoreapi --format='ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}'ExitCode=0→ normal exitExitCode=137→ killed (likely out of memory)
11.5.2 View Logs
sudo docker logs povertyscoreapi | head -n 20 # startup logs
sudo docker logs --tail 200 povertyscoreapi # recent logs11.5.3 Reproduce Interactively
Start an interactive debug session:
sudo docker run --rm -it \
--name povertyscoreapi-debug \
-p 8080 \
-v /Data/pip/files/data:/Data \
itsesippscoreregistryprod.azurecr.io/povertyscoreapi:latest \
/bin/bashInside:
Rscript /app/main.RPress Ctrl + C to stop and exit to leave.
11.5.4 Restart or Rebuild Containers
sudo docker restart povertyscoreapiOr rebuild completely:
sudo docker stop povertyscoreapi
sudo docker rm povertyscoreapi
sudo docker pull itsesippscoreregistryprod.azurecr.io/povertyscoreapi:latest
sudo docker run -d --name povertyscoreapi \
-p 80:8080 \
-v /Data/pip/files/data:/Data \
itsesippscoreregistryprod.azurecr.io/povertyscoreapi:latest11.6 Testing API Endpoints
11.6.1 From Inside the Container
curl http://localhost:80/api/v1/health-check11.6.2 Loop through common endpoints
for ep in health-check pkgs-version data-signature gh-hash; do
echo "---- Testing $ep ----"
curl -s http://localhost:80/api/v1/$ep
echo
done11.6.3 From Outside (VM host or browser)
curl http://wzlxdpip01.worldbank.org/api/v1/health-check11.7 Troubleshooting Common Errors
| Symptom | Likely Cause | Fix |
|---|---|---|
curl: (7) Failed connect |
Container not running or wrong port | sudo docker ps -a |
Exited (137) |
Out of memory (OOMKilled) | Increase VM memory or limit API load |
authentication required |
Not logged in to Azure Container Registry | sudo az acr login --name itsesippscoreregistryprod |
permission denied on /Data |
Wrong user ownership | sudo chown -R srvpip /Data |
| No logs shown | Container failed before startup | Run sudo docker inspect povertyscoreapi |
| Port 8080 works but 80 doesn’t | Port not mapped | Run container with -p 80:8080 |
11.8 Understanding Ports (80 vs 8080)
Inside Docker, the API runs on 8080:
pipapi::start_api(port = 8080, host = "0.0.0.0")Outside Docker (host or browser), you can map any port using:
-p 80:8080This means:
host_port:container_portSo users access:
http://wzlxdpip01.worldbank.org/api/v1/...even though internally it listens on 8080.
11.9 Monitoring Resource Usage
Watch real-time CPU and memory:
sudo docker stats povertyscoreapiOr globally:
top -u srvpip11.10 Appendix
11.10.1 Check Disk Usage Quickly
df -h | grep Data11.10.2 Check Docker Service Logs
sudo journalctl -u docker --since "2025-09-23 17:00"11.10.3 Check R version inside container
sudo docker exec -it povertyscoreapi Rscript -e "R.version.string"