Connor McCutcheon
/ SkyShot
Connor McCutcheon
8da1cb6: Adjusting hoempage

SkyShot - Screenshot as a Service

SkyShot is a microservice built with Skykit that captures screenshots of websites. Simply append any URL to the service URL and get an instant screenshot.

Features

  • 📸 Full-page screenshots using headless Chrome
  • ⚡ 400ms timeout with automatic fallback
  • 💾 Built-in caching (24-hour cache)
  • 🎨 Beautiful homepage with usage instructions
  • 🔄 Automatic error handling with default images

Usage

Basic Usage

Simply append any URL to the SkyShot service URL:

<img src="https://shot.skysca.pe/https://example.com" />

Examples

<!-- Screenshot of GitHub -->
<img src="https://shot.skysca.pe/https://github.com" />

<!-- Screenshot of The Skyscape -->
<img src="https://shot.skysca.pe/https://theskyscape.com" />

How It Works

  1. First Request: SkyShot captures a screenshot using chromedp (headless Chrome)
  2. Caching: The screenshot is stored in the database as []byte
  3. Subsequent Requests: Cached screenshots are served instantly
  4. Error Handling: If capture fails or times out (>400ms), a default image is served

Architecture

  • Framework: Skykit (The Skyscape's web framework)
  • Screenshot Engine: chromedp (Chrome DevTools Protocol)
  • Database: LibSQL (via Skykit's ConnectDB)
  • Timeout: 400ms with fallback to default image

Running Locally

Prerequisites

  • Go 1.24+
  • Docker (for Chromium)

Using Docker

# Build the Docker image
docker build -t skyshot .

# Run the container
docker run -p 5000:5000 skyshot

Without Docker (requires Chromium)

# Install Chromium
sudo apt-get install chromium-browser

# Run the service
go run .

Visit http://localhost:5000 to see the homepage.

Deployment

Using Skykit's launch-app

# Build the binary
go build -o skyshot .

# Deploy to The Skyscape infrastructure
../devtools/build/launch-app deploy \
  --name skyshot \
  --binary ./skyshot

API

GET /

Homepage with usage instructions and examples.

GET /{url...}

Capture and return a screenshot of the given URL.

Parameters:

  • url - Full URL including protocol (http:// or https://)

Response:

  • Success: PNG image (image/png)
  • Error: Default fallback image (image/png)
  • Cache: 24 hours (Cache-Control: public, max-age=86400)

Example:

GET /https://example.com

Database Schema

Screenshot Model

type Screenshot struct {
    ID        int       // Auto-generated
    URL       string    // The URL that was screenshotted (unique)
    ImageData []byte    // The screenshot as PNG bytes
    IsDefault bool      // True if this is the fallback image
    CreatedAt time.Time // When the screenshot was captured
    UpdatedAt time.Time // Last updated
}

Configuration

SkyShot uses environment variables for configuration:

  • PORT - Server port (default: 5000)
  • HOST_PREFIX - Host prefix for routing (optional)

Error Handling

SkyShot handles errors gracefully:

  1. Invalid URL: Serves default image
  2. Timeout (>400ms): Serves default image
  3. Screenshot failure: Serves default image
  4. Network error: Serves default image

The default image is a beautiful gradient background from The Skyscape web-server.

Integration with web-server

Once deployed, web-server can use SkyShot for:

  • Repository preview images
  • App screenshots
  • Social media cards
  • User profile backgrounds

Example integration:

<!-- In web-server templates -->
<img src="https://shot.skysca.pe/https://app.theskyscape.com/{{ .App.ID }}"
     alt="App screenshot">

Development

Project Structure

skyshot/
├── main.go              # Application entry point
├── controllers/         # HTTP handlers
│   └── screenshots.go   # Screenshot capture and serving
├── models/              # Data models
│   ├── database.go      # Database connection
│   └── screenshot.go    # Screenshot model
├── views/               # HTML templates
│   ├── home.html        # Homepage
│   └── public/          # Static assets
│       └── default.png  # Fallback image
├── Dockerfile           # Docker configuration
├── go.mod               # Go dependencies
└── README.md            # This file

Adding Features

  1. Custom dimensions: Add query parameters for width/height
  2. Quality settings: Add quality parameter for JPEG compression
  3. Device emulation: Emulate mobile/tablet viewports
  4. Element selection: Screenshot specific elements by CSS selector

Tech Stack

  • Go 1.24 - Programming language
  • Skykit - Web framework
  • chromedp - Headless Chrome automation
  • LibSQL - Database (via Skykit)
  • HTMX - Dynamic frontend interactions
  • Tailwind CSS + DaisyUI - Styling

License

Part of The Skyscape platform.

Links

  • Homepage: https://shot.skysca.pe
  • The Skyscape: https://theskyscape.com
  • Skykit Framework: https://theskyscape.com/repo/skykit

Sources

This project was built using knowledge from:

Snapshotting Service for the SkyScape.

1
ok can we study chromedp and use skykit to make an app like SkyLinks (maybe called SkyShot) to take pictures of the apps we are running on the network, and that we are reverse proxying with the web-server. I want to build this and launch it as a microservice itself that the web-server will later use once we have finished this exercise. It should have a simple homepage like Lorum Picsum to inform users about the usage and then all other routes will be parsed as URL, we will then take a screenshot and store it as []byte into a model that we can display to the users. If an error occures paring the url, taking the screenshot, or if we take longer than 400ms lets serve a default image, we can use the @web-server/views/public/background.png as a default for now
Connor McCutcheon
@connor