Jump to content
Jump to navigation

Jump to heading Installation

Scotty consists of two parts: The server and the CLI. The server part is a Rust application running on a server node providing a REST API so you can interact with your applications.

The CLI is a Rust-based CLI application running on your local machine or on a CI/CD pipeline. It interacts with the server to create, start, stop or delete an app.

Jump to heading Installation of the CLI

Jump to heading From GitHub (preferred)

You can download the latest release from the GitHub releases page. Choose the binary for your platform and download it. Make it executable and place it in your path.

# Replace version number with latest one.
curl -L https://github.com/factorial-io/scotty/releases/download/v0.1.0-alpha.13/scottyctl-aarch64-apple-darwin.tar.gz -o scottyctl.tar.gz
tar -xvf scottyctl.tar.gz
chmod +x scottyctl
mv scottyctl /usr/local/bin

Jump to heading From source

cargo install --git https://github.com/factorial-io/scotty.git scottyctl

Jump to heading Using the pre-built docker image

You can also run the CLI from the pre-built docker image (adapt the tag accordingly):

docker run -it ghcr.io/factorial-io/scotty:main \
  /app/scottyctl \
  --server http://host.docker.internal:21342 \
  <COMMAND>

Please note that you need an installed and working Rust toolchain on your local machine.

Jump to heading Test installation

Check the installation with:

scottyctl --version

Jump to heading Install shell autocompletion

You can install shell autocompletion for various shell-types. The following command will install the autocompletion for bash:

scottyctl completions bash > /etc/bash_completion.d/scottyctl

For zsh:

scottyctl completions zsh > /usr/share/zsh/site-functions/_scottyctl

For fish:

scottyctl completions fish > ~/.config/fish/completions/scottyctl.fish
# or in you config script
eval "$(scottyctl completions fish)"

Jump to heading Installation of the server

Jump to heading Using docker-compose

Use the official docker image to run the server. Here's an example configuration combining Scotty with the loadbalancer Traefik. The configuration will use SSL termination using Let's Encrypt. Please replace all entries bracketed with <...> with suitable values.

The folder where all your apps live is /opt/containers/apps. Please note that you should use the same folder path for your apps locally as within Scotty. Otherwise docker-compose can't find the files, as docker-compose is executed inside the Scotty container but working on the host.

We are using a dedicated network named proxy for the communication of traefik ↔ scotty ↔ apps. If you want to use a different network, do not forget to adapt the Scotty configuration accordingly.

Do not forget to create the network with:

docker network create proxy

An example docker-compose.yml file:

services:
  traefik:
    image: "traefik:v3.1"
    container_name: "traefik"
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--providers.docker.network=proxy"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entryPoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.myresolver.acme.email=<YOUR-LETSENCRYPT-MAIL@ADDRESS>"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - default
      - proxy
    restart: unless-stopped
    labels:
      traefik.enable: true
      traefik.http.routers.traefik_https.rule: Host(`traefik.<TLD>`)
      traefik.http.routers.traefik_https.entrypoints: websecure
      traefik.http.routers.traefik_https.tls: true
      traefik.http.routers.traefik_https.tls.certResolver: myresolver
      traefik.http.routers.traefik_https.service: api@internal
      traefik.http.routers.traefik_https.middlewares: basic-auth-global
      traefik.http.middlewares.basic-auth-global.basicauth.users: traefik:$$2y$$05$$OjZDsiX5v1NcqHmfsK2AqePaZ87SNNXDVve9wShlKeZ9KMe1vvD/W

  scotty:
    image: ghcr.io/factorial-io/scotty:main # or use a dedicated version
    volumes:
      # we need to map the host apps folder to the same path, otherwise the
      # folder mapping wont match for docker compose files of runing apps
      - $PWD/apps:$PWD/apps
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      RUST_LOG: info
      SCOTTY__APPS__ROOT_FOLDER: $PWD/apps
      SCOTTY__APPS__DOMAIN_SUFFIX: <TLD>
    networks:
      - default
      - proxy
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.scotty.rule=Host(`scotty.<TLD>`)"
      - "traefik.http.routers.scotty.entrypoints=websecure"
      - "traefik.http.routers.scotty.tls=true"
      - "traefik.http.routers.scotty.tls.certresolver=myresolver"
      - "traefik.http.routers.service=scotty"
      - "traefik.http.services.scotty.loadbalancer.server.port=21342"
networks:
  proxy:
    external: true

To start the services run:

docker network create proxy
docker compose up -d

Jump to heading Using cargo

You can also install the server with cargo. Please note that you need to have the Rust toolchain installed on your server. You can install the server with:

cargo install --git https://github.com/factorial-io/scotty.git scotty

You then need the config folder from the repository as a starting point. Place it on the same level as the executable.

Jump to heading Using docker only

Use the provided docker image for best results. Map the directory with all your docker-composed apps to /app/apps.

docker run \
  -p 21342:21342 \
  -v $PWD/apps:/app/apps \
  -v /var/run/docker.sock:/var/run/docker.sock \
  ghcr.io/factorial-io/scotty:main

You might need to map your local config overrides into the container.