|
| 1 | +# Lights Out |
| 2 | + |
| 3 | +A lightweight Go service that combines ping health checks with power management for GCE instances. Acts as both a health endpoint and an activity monitor that can automatically shut down instances after periods of inactivity. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **HTTP Health Endpoints**: `/ping` (monitored) and `/health` (healthcheck) |
| 8 | +- **Activity Monitoring**: Tracks requests to `/ping` endpoint |
| 9 | +- **Configurable Timeouts**: Environment-controlled inactivity periods |
| 10 | +- **GCP Integration**: Automatic instance suspension via GCP API service |
| 11 | + |
| 12 | +## Usage |
| 13 | + |
| 14 | +### As Docker Container |
| 15 | + |
| 16 | +```bash |
| 17 | +docker run -p 8808:8808 -e INACTIVITY_TIMEOUT=90 lightswitch:latest |
| 18 | +``` |
| 19 | + |
| 20 | +### Environment Variables |
| 21 | + |
| 22 | +| Variable | Default | Description | |
| 23 | +| -------------------- | ------- | ---------------------------------------- | |
| 24 | +| `PORT` | `8808` | HTTP server port | |
| 25 | +| `INACTIVITY_TIMEOUT` | `90` | Seconds of inactivity before shutdown | |
| 26 | +| `CHECK_INTERVAL` | `30` | Seconds between activity checks | |
| 27 | +| `LIBOPS_PROXY_URL` | - | GCP proxy URL for suspension | |
| 28 | +| `LIBOPS_KEEP_ONLINE` | - | Set to "yes" to disable auto-shutdown | |
| 29 | +| `LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARN, ERROR) | |
| 30 | + |
| 31 | +### Endpoints |
| 32 | + |
| 33 | +- `GET /ping` - Returns "pong", activity is logged and monitored |
| 34 | +- `GET /health` - Returns "healthy", used for container healthchecks |
| 35 | + |
| 36 | +## Integration |
| 37 | + |
| 38 | +This service is designed to work in tandem with [ppb (Proxy Power Button)](https://github.com/libops/ppb) to create a complete on-demand infrastructure solution: |
| 39 | + |
| 40 | +### How ppb and lightsout work together: |
| 41 | + |
| 42 | +1. **ppb (Boot)**: Acts as an ingress proxy that automatically starts GCE instances when requests arrive |
| 43 | + - Receives incoming requests for dormant instances |
| 44 | + - Starts the GCE instance via GCP API |
| 45 | + - Proxies requests to the now-running backend |
| 46 | + |
| 47 | +2. **lightsout (Shutdown)**: Monitors activity and automatically shuts down instances during idle periods |
| 48 | + - Tracks activity via `/ping` endpoint calls |
| 49 | + - Monitors for configurable inactivity timeouts |
| 50 | + - Automatically suspends the GCE instance to save costs |
| 51 | + |
| 52 | +### Deployment Architecture: |
| 53 | + |
| 54 | +``` |
| 55 | +Internet → ppb (ingress) → GCE Instance (running lightsout + your app) |
| 56 | +``` |
| 57 | + |
| 58 | +- Deploy ppb as your public-facing service |
| 59 | +- Deploy lightsout alongside your application on GCE instances |
| 60 | +- Configure your application to periodically call `/ping` to signal activity |
| 61 | +- ppb handles instance startup, lightsout handles instance shutdown |
| 62 | + |
| 63 | +### Required IAM Permissions |
| 64 | + |
| 65 | +The Google Service Account (GSA) used by this service requires the following IAM permissions: |
| 66 | + |
| 67 | +- `compute.instances.suspend` - To suspend/stop the GCE instance |
| 68 | +- `compute.instances.get` - To check the current status of the instance |
| 69 | + |
| 70 | +These can be granted via the predefined `Compute Instance Admin (v1)` role, or by creating a custom role with only the specific permissions needed: |
| 71 | + |
| 72 | +```bash |
| 73 | +# Create custom role with minimal permissions |
| 74 | +gcloud iam roles create lightsout.instanceManager \ |
| 75 | + --project=YOUR_PROJECT_ID \ |
| 76 | + --title="Lightsout Instance Manager" \ |
| 77 | + --description="Minimal permissions for lightsout service" \ |
| 78 | + --permissions=compute.instances.suspend,compute.instances.get |
| 79 | + |
| 80 | +# Assign to service account |
| 81 | +gcloud projects add-iam-policy-binding YOUR_PROJECT_ID \ |
| 82 | + --member="serviceAccount:YOUR_SERVICE_ACCOUNT@YOUR_PROJECT_ID.iam.gserviceaccount.com" \ |
| 83 | + --role="projects/YOUR_PROJECT_ID/roles/lightsout.instanceManager" |
| 84 | +``` |
0 commit comments