Easily manage and monitor applications on your machine via Tailscale.
This project provides a web-based application manager that runs on your Tailscale network, allowing you to start, stop, and monitor configured applications from anywhere on your tailnet. It features real-time log streaming, a modern web interface, and RESTful API access.
go install github.com/sierrasoftworks/tailon@latestAt its simplest, you can start managing applications by creating a configuration file and running the tailon command:
# Start tailon with the default configuration file
tailon
# Start with a custom configuration file
tailon --config /path/to/config.yaml
# Enable verbose logging
tailon --verboseTo expose tailon on your Tailscale network, you'll need to configure the Tailscale integration in your configuration file. Here's how to set it up:
tailscale:
name: "my-tailon-server" # The hostname that will appear on your tailnet
state_dir: "/var/lib/tailscale" # Directory to store Tailscale state
applications:
- name: "my-app"
path: "/path/to/executable"For automated deployments or headless servers, you can authenticate using an authkey:
# Set your Tailscale authkey as an environment variable
export TS_AUTHKEY="tskey-auth-your-key-here"
# Start tailon (it will automatically authenticate on first run)
tailonFor temporary deployments or testing, you can run in ephemeral mode where the service is removed from your tailnet when stopped:
tailscale:
ephemeral: trueOnce configured and running, your tailon service will be available at:
https://my-tailon-server.your-tailnet.ts.net(if HTTPS certificates are available)http://my-tailon-server.your-tailnet.ts.net(fallback to HTTP)
Note: Replace my-tailon-server with the name you specified in your configuration, and your-tailnet with your actual Tailscale tailnet name.
The service is configured via a YAML file (default: config.yaml) that defines the applications you want to manage:
applications:
- name: "my-app"
path: "/path/to/executable"
args: ["--flag", "value"]
env:
- "ENV_VAR=value"
listen: "localhost:8080" # Optional: local interface binding
tailscale:
name: "my-tailon-server" # Hostname on Tailscale network
state_dir: "/tmp/tailscale-state" # Tailscale state directoryApplications can specify a working directory where they will run. This is useful for applications that expect to run from a specific location or need access to files in a particular directory:
applications:
- name: "web-server"
path: "/usr/bin/python3"
args: ["-m", "http.server", "8000"]
working_dir: "/var/www/html" # Serve files from this directory
env:
- "PYTHONPATH=/app"
- name: "file-processor"
path: "/usr/bin/python3"
args: ["process.py"]
working_dir: "/data/input" # Process files from this directory
env:
- "DATA_PATH=/data/input"Tailon includes comprehensive security features to control access and protect sensitive information:
# Security configuration
security:
# Default role for anonymous users (when Tailscale is disabled)
default_role: "admin" # Options: admin, operator, viewer, or "" (none)
applications:
- name: "secure-app"
path: "/app/server"
env:
- "API_KEY=secret123" # Will be hidden if hide_env_vars: true
- "DATABASE_URL=postgres://..."TailOn implements a flexible role-based authorization system with four permission levels:
admin: Full access - can view, start, stop, and restart applicationsoperator: Control access - can view, start, stop, and restart applications (environment variables may be hidden)viewer: Read-only access - can view application status and logs onlynoneor"": No access - cannot access applications
When using Tailscale, you can grant users specific roles for applications using Tailscale's capabilities feature. Add the sierrasoftworks.com/cap/tailon capability to your Tailscale ACL policy:
{
"acls": [
{
"action": "accept",
"src": ["group:admins"],
"dst": ["my-tailon-server:80", "my-tailon-server:443"]
}
],
"groups": {
"group:admins": ["user:[email protected]"]
},
"grants": [
{
"src": ["user:[email protected]"],
"dst": ["my-tailon-server"],
"app": {
"sierrasoftworks.com/cap/tailon": [
{
"role": "operator",
"applications": ["web-server", "api-service"]
}
]
}
},
{
"src": ["group:admins"],
"dst": ["my-tailon-server"],
"app": {
"sierrasoftworks.com/cap/tailon": [
{
"role": "admin",
"applications": ["*"]
}
]
}
}
]
}In this example:
[email protected]getsoperatorrole forweb-serverandapi-serviceapplications- Members of
group:adminsgetadminrole for all applications (*wildcard)
Note that if Alice is a member of the admins group then the most specific rule will win and
she will NOT have admin on web-server or api-service (instead she will be limited to operator
access).
For Production Environments:
security:
default_role: "" # No default access for anonymous users
tailscale:
enabled: true # Use Tailscale for secure accessFor Development/Internal Use:
listen: "localhost:8080" # Bind to localhost only
security:
default_role: "admin" # Allow full access for developmentOnce configured, you can manage your applications through the web interface or API:
- Web Interface: Navigate to your tailon service in a browser to access the modern web UI
- RESTful API: Use HTTP requests to programmatically manage applications
- Real-time Logs: Stream application output in real-time through the web interface or API
The service integrates deeply with Tailscale to provide seamless network access:
- Automatic TLS: Attempts to obtain HTTPS certificates when available
- MagicDNS: Uses your Tailscale hostname for easy discovery
- Network Security: Inherits Tailscale's zero-trust network model
- State Persistence: Saves Tailscale configuration for reliable restarts
You can use Tailscale's Access Control Lists (ACLs) to restrict who can access your tailon service. This provides fine-grained control over which users or devices can manage your applications:
{
"acls": [
{
"action": "accept",
"src": ["group:admins"],
"dst": ["my-tailon-server:80", "my-tailon-server:443"]
},
{
"action": "accept",
"src": ["user:[email protected]"],
"dst": ["my-tailon-server:*"]
}
],
"groups": {
"group:admins": ["user:[email protected]", "user:[email protected]"]
}
}This example configuration:
- Allows members of the
adminsgroup to access the service on ports 80 and 443 - Grants
[email protected]full access to all ports on the service - Blocks all other users from accessing the tailon service
For more information on configuring Tailscale ACLs, see the Tailscale ACL documentation.
Applications are monitored continuously with comprehensive logging:
- Circular buffer of up to 1,000 log lines per application
- Combined stdout and stderr with timestamps
- Real-time streaming via Server-Sent Events
- In-memory storage (logs are not persisted to disk)
Tailon provides comprehensive audit logging for security and compliance:
- User Tracking: All actions are logged with user identification
- IP Address Logging: Anonymous users are tracked by IP address (
$anonymous-192.168.1.100$) - Action Logging: Start, stop, restart operations are recorded with timestamps
- Enhanced Context: Logs include user display names, IP addresses, and detailed action context
Example audit log entries:
INFO User started application action=start target=web-server user_id=$anonymous-127.0.0.1$ ip_address=127.0.0.1
INFO Alice Smith stopped application (Gracefully stopping application (SIGTERM)) action=stop target=web-server [email protected]
The tailon service provides a RESTful API for programmatic access to application management:
curl http://localhost:8080/api/v1/appscurl -X POST http://localhost:8080/api/v1/apps/my-app/startcurl -X POST http://localhost:8080/api/v1/apps/my-app/stopcurl -X POST http://localhost:8080/api/v1/apps/my-app/restartcurl http://localhost:8080/api/v1/apps/my-app/logscurl -H "Accept: text/event-stream" http://localhost:8080/api/v1/apps/my-app/logs--config, -c: Path to configuration file (default: "config.yaml")--verbose, -v: Enable verbose logging
If you wish to allow people to access your TailOn server without needing to go via Tailscale,
you can set the listen option in your configuration. We strongly recommend binding this to
localhost:* or 127.0.0.1:* to avoid the risk of bad actors with network access to your device
being able to manage your application remotely.
listen: "localhost:8080" # Bind to local interface
# Configure security settings for non-Tailscale access
security:
allow_anonymous: true # Allow access without Tailscale authSecurity Warning: When binding to non-localhost addresses (e.g., 0.0.0.0:8080), anyone with network access to your machine can control your applications. Always use appropriate security configuration and consider using Tailscale for secure remote access instead.