OpenCode Portal is designed for remote access to your OpenCode instance. This guide shows you how to deploy the portal on a VPS and access it securely from your mobile device or any other machine using Tailscale.
Use Case
This setup allows you to:
- Access OpenCode from your mobile device when you don’t have your laptop
- Work on code from anywhere with an internet connection
- Share OpenCode access with team members securely
Architecture:
[Your Phone/Device] ---(Tailscale VPN)---> [VPS running Portal + OpenCode]
Prerequisites
- A VPS or remote server (Ubuntu, Debian, or similar)
- SSH access to your server
- A Tailscale account (free tier available)
Setup Steps
Install Bun on Your Server
SSH into your server and install Bun:curl -fsSL https://bun.sh/install | bash
Add Bun to your PATH (if not done automatically):export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
Add these lines to your ~/.bashrc or ~/.zshrc to make them permanent. Install OpenCode
Install OpenCode globally on your server:Verify the installation: Install OpenPortal
Install OpenPortal globally:bun install -g openportal
Install and Configure Tailscale
Install Tailscale on your server:curl -fsSL https://tailscale.com/install.sh | sh
Start and authenticate Tailscale:Follow the authentication URL to connect your server to your Tailscale network.Get your server’s Tailscale IP:Note this IP address - you’ll use it to access OpenPortal. Start OpenPortal on Your Server
Navigate to your project directory and start OpenPortal:cd /path/to/your/project
openportal
For production use, you’ll want to keep it running in the background. See the Process Management section below. Install Tailscale on Your Mobile Device
Install the Tailscale app on your phone:Sign in with the same Tailscale account. Access OpenPortal from Your Device
On your mobile device, open a browser and navigate to:http://[tailscale-ip]:3000
Replace [tailscale-ip] with your server’s Tailscale IP from Step 4.You should now see the OpenCode Portal interface!
Network Configuration
Binding to All Interfaces
By default, OpenPortal binds to 0.0.0.0 (all network interfaces), which allows access from Tailscale.
If you want to bind to a specific interface:
openportal --hostname 0.0.0.0
Custom Ports
If you need to use different ports:
# Custom Web UI port
openportal --port 8080
# Custom OpenCode server port
openportal --opencode-port 5000
# Both custom ports
openportal --port 8080 --opencode-port 5000
Remember to use the correct port when accessing from your device.
Process Management
For production use, you’ll want OpenPortal to run persistently in the background.
Using systemd
Create a systemd service file:
sudo nano /etc/systemd/system/openportal.service
Add the following content (adjust paths as needed):
[Unit]
Description=OpenCode Portal
After=network.target
[Service]
Type=simple
User=your-username
WorkingDirectory=/path/to/your/project
ExecStart=/home/your-username/.bun/bin/openportal
Restart=always
RestartSec=10
Environment="PATH=/home/your-username/.bun/bin:/usr/local/bin:/usr/bin:/bin"
[Install]
WantedBy=multi-user.target
Enable and start the service:
# Reload systemd
sudo systemctl daemon-reload
# Enable service to start on boot
sudo systemctl enable openportal
# Start the service
sudo systemctl start openportal
# Check status
sudo systemctl status openportal
Manage the service:
# Stop the service
sudo systemctl stop openportal
# Restart the service
sudo systemctl restart openportal
# View logs
sudo journalctl -u openportal -f
Using screen
For a simpler approach, use screen:
# Start a new screen session
screen -S openportal
# Start OpenPortal
cd /path/to/your/project
openportal
# Detach from screen: Press Ctrl+A, then D
Reattach to the session:
Using tmux
Alternatively, use tmux:
# Start a new tmux session
tmux new -s openportal
# Start OpenPortal
cd /path/to/your/project
openportal
# Detach from tmux: Press Ctrl+B, then D
Reattach to the session:
tmux attach -t openportal
Security Considerations
Tailscale Security
Tailscale provides secure, encrypted connections between your devices:
- All traffic is encrypted using WireGuard
- Only devices in your Tailscale network can access your server
- No need to expose ports to the public internet
Additional Security Measures
Never expose OpenPortal directly to the public internet without proper authentication and HTTPS.
If you need to expose OpenPortal publicly:
- Use a reverse proxy (nginx, Caddy) with HTTPS
- Add authentication (basic auth, OAuth)
- Configure firewall rules to restrict access
- Use strong passwords for your OpenCode instances
Example nginx configuration with basic auth:
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
auth_basic "Restricted";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Monitoring and Maintenance
Check Running Instances
View Logs (systemd)
# Follow logs in real-time
sudo journalctl -u openportal -f
# View recent logs
sudo journalctl -u openportal -n 100
Restart After Updates
After updating OpenPortal:
# Update OpenPortal
bun install -g openportal
# Restart the service
sudo systemctl restart openportal
# Or if using screen/tmux, stop and restart manually
openportal stop
openportal
Troubleshooting
Cannot Connect from Mobile Device
- Verify Tailscale is connected on both devices
- Check your server’s Tailscale IP:
tailscale ip -4
- Ensure OpenPortal is running:
openportal list
- Verify the port is correct (default: 3000)
Tailscale Connection Issues
# Check Tailscale status
tailscale status
# Restart Tailscale
sudo systemctl restart tailscaled
OpenPortal Service Not Starting
# Check service status
sudo systemctl status openportal
# View detailed logs
sudo journalctl -u openportal -n 50
# Check if OpenCode is installed
which opencode
Next Steps
- Explore Docker deployment for containerized setups
- Configure multiple project instances with custom names
- Set up automated backups for your project files