Complete guide to set up secure internet access to your E-ink display using Cloudflare Tunnel with authentication.
- Cloudflare account (free)
- Domain name added to Cloudflare (free .tk domain works fine)
If you don't have one:
- Free option: Get a .tk domain from dot.tk
- Cheap option: Buy a .xyz domain (~$2/year) from Namecheap
Add your domain to Cloudflare and wait for activation (5-30 minutes).
./setup_internet_access.shThis will:
- Install cloudflared
- Authenticate with Cloudflare
- Create a tunnel
- Set up DNS
- Configure system service
- Set up admin authentication
./start_internet_server.shYour E-ink display will be accessible at: https://eink.yourdomain.com
Use these settings in WebClient DAT:
- URL:
https://eink.yourdomain.com/upload - Authentication Type: None
- Custom Header:
- Name:
X-API-Key - Value:
[your-api-key-from-.env-file]
- Name:
# Check tunnel status
sudo systemctl status cloudflared.service
# View logs
sudo journalctl -u cloudflared.service -f
# Restart tunnel
sudo systemctl restart cloudflared.service- ✅ Admin password protection
- ✅ HTTPS encryption (automatic)
- ✅ Server binds to localhost only
- ✅ API key authentication for TouchDesigner
- ✅ No port forwarding needed
setup_internet_access.sh- One-time setupstart_internet_server.sh- Start the Flask serversetup_admin_password.py- Set/reset admin password.env- Your credentials (auto-generated)
If you're running without a GUI (headless):
- Authentication: When the setup asks for browser authentication, copy the URL and open it on your phone/laptop
- Domain setup: Add your domain to Cloudflare from any device with a browser
- Everything else works the same
- URL:
https://eink.yourdomain.com/upload - Method:
PUT(automatically optimized for tunnel) - Authentication Type:
None - Custom Header:
- Name:
X-API-Key - Value:
[your-api-key-from-.env-file]
- Name:
The system automatically detects your connection:
- Local network (192.168.x.x) → Uses PUT with
uploadFile - Internet tunnel (domain) → Uses POST with binary data
No configuration changes needed! Same code works everywhere.
# Your API key is in the .env file
cat .env | grep API_KEY# Use WebClient DAT - works both locally and through tunnel
connection_id = op('webclient1').request(
'https://eink.yourdomain.com/upload',
'PUT',
header={'X-API-Key': 'your-api-key-here'},
uploadFile='/path/to/image.jpg'
)Benefits:
- ✅ Same code works locally and through internet
- ✅ Automatic optimization for each connection type
- ✅ No manual switching between methods
- Problem: No domain in your Cloudflare account
- Solution: Add a domain to Cloudflare first (free .tk domain works)
- Problem: DNS record conflict (parking page A record exists)
- Solution:
- Go to Cloudflare Dashboard → DNS → Records
- Delete existing A record for your domain
- Run:
cloudflared tunnel route dns TUNNEL_ID yourdomain.com
- Problem: Existing DNS record conflicts with tunnel
- Solution: Delete conflicting records in Cloudflare dashboard first
- Problem: Missing or wrong API key
- Solution: Check your
.envfile for the correct API key
- Problem: Tunnel service not running
- Solution:
sudo systemctl start cloudflared.service
- Problem: Architecture mismatch
- Solution: The script automatically detects Pi Zero and uses the correct ARM binary
- Problem: Using quick tunnels instead of named tunnels
- Solution: You need a domain in Cloudflare for permanent URLs
- Admin password: Set a strong password (12+ characters)
- API key: Keep it secret, regenerate if compromised
- HTTPS only: Cloudflare provides automatic SSL
- Localhost binding: Flask server only accepts local connections
- No port forwarding: Tunnel makes outbound connections only
All endpoints require authentication (web login or API key):
| Endpoint | Method | Purpose |
|---|---|---|
/ |
GET | Web interface |
/upload |
POST/PUT | Upload files |
/api/files |
GET | List files with thumbnails |
/display_file |
POST | Display specific file |
/delete_file |
POST | Delete file |
/clear_screen |
POST | Clear display |
/status |
GET | Server status |
- Check the logs:
sudo journalctl -u cloudflared.service -f - Test locally first:
curl http://localhost:5000/status - Verify tunnel:
sudo systemctl status cloudflared.service - Check Flask server: Look for error messages when starting
Once everything is working, you'll have:
- ✅ Secure internet access to your E-ink display
- ✅ Admin web interface with authentication
- ✅ TouchDesigner integration with API keys
- ✅ Permanent HTTPS URL
- ✅ No router configuration needed
That's it! Clean and simple. 🎉