skadi gist
Share MPS code snippets. More than just screenshots.
Repository Content
ide-plugin
: MPS Plugin that creates a gist from the IDE written in kotlin.js
: Type script sources used by the front end. Mostly hotwired.dev progressive enhancement. All core functionality is server side rendered!server
: Backend for theide-plugin
and serves the web interface. Written in kotlin with KTOR.shared
: Shared classes between theide-plugin
andserver
mostly constants and JSON messages.
Getting Started with Development
Prerequists
- an installed JDK at least Java 11 is required (IntelliJ can install it when opening the project)
- optionally: PostgreSQL (for running the tests)
- Node and Yarn
Editing Code
The repository contains a intelliJ project in the root directory which you can open and intelliJ will import the project for you. It will also download all the dependencies, and you get work on the project.
If you are using a different code editor e.g. VS Code or GitHub Codespaces your want to run ./gradlew assemble
before you open the project. This will download all dependencies and build the project.
Running the Tests
To run the tests you will need ProstgreSQL. The esiest way to get an instance up and running is via docker:
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres
This will start a container with a PostgreSQL sever and expose the server to port 5432
.
If you use this exact configuration you can run the test from intelliJ via the Tests in 'cloud.skadi'
runconfiguration. If you changed the port of the password you will need to change the environment variables in the configuration to match yours. If you modify the configuration it's best to create copy to not accidentially commit the changes.
If you don't use intelliJ to run the test you will need to set these four environment variables:
COOKIE_SALT="give me cookies"
SQL_USER=postgres
SQL_PASSWORD=mysecretpassword
SQL_HOST=localhost:5432
COOKIE_SALT
is used to authenticate cookies during the tests. The value doesn't matter for testing choose what ever you like. The SQL_*
variables need match your PostgreSQL configuration.
You can then run the test via ./gradlew build
.
Running your own Instance
The preferred way of running skadi gist is via a container. The container image is available at docker hub.
Storage Backend
skadi gist support to two backends for storing the screenshots: directory
and s3
. The models are always stored in the database.
S3 Storage
skadi gist support storing screenshots in AWS S3 or compatible storage ( e.g. digitalocean spaces , scaleway object storage or self-hosted minIO). When using this storage backend skadi will store all screenshots in S3 making the container entirely stateless.
Skadi gist will also leverage features like presigned urls for none public gists. This means the urls to screenshots are only valid for short period of time.
Configuration
To configure S3 storage set the STORAGE_KIND
environment varialbe to s3
.
Additional configuration via environment variables is required for authentication and the endpoint at your cloud provider:
S3_REGION=
S3_ACCESS_KEY=
S3_SECRET_KEY=
S3_BUCKET_NAME=
If you are not using AWS but another provider you can omit S3_REGION
. Instead, set S3_ENDPOINT
according to your providers' documentation.
Directory Storage
Directory storage uses the file system to store the screenshots. It then serves these files directly from the local filesystem. This storage is mainly useful for testing and small deployments.
Configuration
To confgiure directory storage set the STORAGE_KIND
environment varialbe to directory
.
For production deployments you definitly want to set STORAGE_DIRECTORY
to point to a directory that is persistent and not deleted when the container is updated. For testing no additional configuation is required.
Database
skadi gist uses PostgreSQL for storing all data except the screenshots. This includes the models that are stored as JSON in the database. You can configure the database connection with the following environment variables:
SQL_USER=
SQL_PASSWORD=
SQL_HOST=
SQL_DB=
Make sure the user has CREATE
permissions on the database in order to be able to create and update the database.
If you like to see support for a database backend that requires less configuration feel free to vode up this issue.
GitHub Authentication
Skadi gist uses OAuth to authenticate the user. At the moment only GitHub is supported. To use GitHub authentication you need to create a new OAuth App. The callback URL is the url of your skadi cloud instance. If you are testing locally this is http://localhost:8080
.
After the OAuth app is created you can start configuring skadi cloud to use it.
Configuration
skadi cloud uses environment variables to configure authentication:
GITHUB_SECRET=
GITHUB_ID=
In addition to the OAuth configuration a key for signing the cookies is required. That key is used to authenticate that the cookies a client presents aren't modified. Keep this key secret as others can use it to inpersionate any use with that key. If you change the key all existing user sessions are invalidated and the users need to login again.
To set the key use the environment variable COOKIE_SALT
. The value has not requirements since it is not used directly but the key for signing cookies is derived from the value.
Docker Compose Example
Make sure you replace the environemnt variables with your values!
Direct Access Deployment
This creates a deployment that exposes skadi gist directly on port 8080.
version: '3'
services:
skadi-gist:
image: skadicloud/gist-server
container_name: skadi-gist
restart: unless-stopped
ports:
- 8080:8080
security_opt:
- no-new-privileges:true
volumes:
- ./data:/data
environment:
- STORAGE_KIND=directory
- STORAGE_DIRECTORY=/data
- SQL_HOST=database
- SQL_USER=skadi
- SQL_PASSWORD=123456789
- SQL_DB=skadi-gist
- GITHUB_SECRET=addme
- GITHUB_ID=clientid
- COOKIE_SALT=replaceme
- IS_PRODUCTION=TRUE
depends_on:
- database
links:
- database
database:
image: 'postgres:latest'
ports:
- 5432
environment:
POSTGRES_USER: skadi # The PostgreSQL user (useful to connect to the database)
POSTGRES_PASSWORD: 123456789 # The PostgreSQL password (useful to connect to the database)
POSTGRES_DB: skadi-gist # The PostgreSQL default database (automatically created at first launch)
volumes:
- ./db/:/var/lib/postgresql/data/
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U skadi" ]
interval: 5s
timeout: 5s
retries: 5
With Treafik Ingress
This example uses traefik as an ingress handler. Traefik allows for automatic TLS configuration with certificates from Let's Encrypt.
docker-compose.yaml:
version: '3'
services:
traefik:
image: traefik:v2.4
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/traefik.yml:ro
- ./traefik/acme/:/data
skadi-gist:
image: skadicloud/gist-server
container_name: skadi-gist
restart: unless-stopped
networks:
- proxy
security_opt:
- no-new-privileges:true
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
environment:
- STORAGE_KIND=directory
- STORAGE_DIRECTORY=/data
- SQL_HOST=database
- SQL_USER=skadi
- SQL_PASSWORD=123456789
- SQL_DB=skadi-gist
- GITHUB_SECRET=addme
- GITHUB_ID=clientid
- COOKIE_SALT=replaceme
- IS_PRODUCTION=TRUE
depends_on:
- database
labels:
- "traefik.enable=true"
- "traefik.http.routers.skadi.entrypoints=https"
- "traefik.http.routers.skadi.rule=Host(`
`)"
- "traefik.http.routers.skadi.tls=true"
- "traefik.http.routers.skadi.tls.certresolver=myresolver"
- "traefik.docker.network=proxy"
links:
- database
database:
image: 'postgres:latest'
ports:
- 5432
networks:
- proxy
environment:
POSTGRES_USER: skadi # The PostgreSQL user (useful to connect to the database)
POSTGRES_PASSWORD: 123456789 # The PostgreSQL password (useful to connect to the database)
POSTGRES_DB: skadi-gist # The PostgreSQL default database (automatically created at first launch)
volumes:
- ./db/:/var/lib/postgresql/data/
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U skadi" ]
interval: 5s
timeout: 5s
retries: 5
networks:
proxy:
external: true
treafik.yml:
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
myresolver:
acme:
email:
storage: /data/acme.json
httpChallenge:
entryPoint: http
Kubernetes Example
For a kubernets example take a look at the kubernetes
subfolder of the repository. It contains the production confguration for skadi-gist. It doesn't include a database deployment because is uses a hosted postgreSQL database.