Problem

TNG provides settlement reports via SFTP with IP whitelisting. n8n server has no static IP. Solution: route through ev-prod-vpn (whitelisted jump host).

  • n8n server: 54.151.191.198 (runs as node user inside Docker)
  • ev-prod-vpn: 18.139.20.216 (whitelisted jump host, ec2-user)

Key insight: Docker user context

n8n runs as the node user inside its container, not as ec2-user on the host. This means:

  • SSH keys must be in /home/node/.ssh/, not /home/ec2-user/.ssh/
  • File paths must exist inside the container filesystem
  • docker cp is required to move files between host and container
# Verify inside n8n Execute Command node
whoami  # → node
pwd     # → /home/node

What didn’t work

  • n8n native SFTP node with ProxyJump — SFTP library doesn’t read ~/.ssh/config
  • SSH tunnel + n8n SFTP node — file path access issues across Docker/host boundary
  • cat file to stdout — encoding issues with large CSVs

Final working solution

Single command executed via SSH to ev-prod-vpn:

echo -e "cd {folder}\nget {filename} {localPath}\nbye" | \
  sshpass -p '{password}' sftp -o StrictHostKeyChecking=no -P {port} {user}@{host} && \
  scp {localPath} n8n:~/tng_settlement/{filename} && \
  ssh n8n -t "docker cp ~/tng_settlement/{filename} n8n:{localPath}"

Three steps in one command:

  1. SFTP download: TNG → ev-prod-vpn (/tmp/)
  2. SCP: ev-prod-vpn → n8n host (~/tng_settlement/)
  3. docker cp: n8n host → n8n container

Then use Read Binary File node (not stdout/cat) to read the file for Google Drive upload.

SSH host alias on ev-prod-vpn

# ~/.ssh/config on ev-prod-vpn
Host n8n
  HostName 54.151.191.198
  User ec2-user
  IdentityFile ~/.ssh/some-key

Allows scp file n8n:~/destination instead of full IP.

Architecture

Schedule (9 AM daily)
  → Set Variables (dates, paths, credentials)
  → SSH to ev-prod-vpn (3-step command above)
  → Read Binary File from container path
  → Upload to Google Drive
  → Cleanup temp files