An itty-bitty PaaS that uses git push to deploy micro-services and websites on your own servers, like Okurrr!!!
Sailor is a tiny PaaS to install on your servers/VPS (DigitalOcean, Hetzner, Linode).
It uses git push
to deploy micro-apps, micro-services and sites.
It natively supports Python, Nodejs, Static sites, and any other languages that can use the command line.
Sites deployed with Sailor automatically have SSL assigned with LetsEncrypt.
Sailor can run long-running background workers and cron jobs.
It allows you to deploy multiple sites/apps using a single repository.
It gives you the option of having testing/staging/production environment deployed from the same codebase.
Sailor let’s you see some stats about your apps, along with scaling them.
Sailor makes deploying apps a smooth sailing.
Ship it like a Sailor!
ls, start, stop, reload, rm, stop, scale, log, info
etcrelease, predeploy, postdeploy, destroy
On the server, run the code below to setup the environment for Sailor and install all its dependencies. A new user, sailor
, will be created and will be used to interact with SSH for Sailor.
curl https://raw.githubusercontent.com/mardix/sailor/master/install.sh > install.sh
chmod 755 install.sh
./install.sh
On your local machine, point a Git remote to your Sailor server (set in step 2), with sailor
as username.
Format: git remote add sailor sailor@$host:$app_name
With:
$host
The server name or IP address $app_name
The name of the application, that is set in the sailor.yml
(the manifest to deploy)Example: git remote add sailor sailor@my-server-host.com:myappname.com
…go into your repo and do what you do best, like a sailor!
At the root of your app directory, create sailor.yml
(required).
# sailor.yml
---
apps:
# -> with remote: sailor@$host:myapp.com
- name: myapp.com
runtime: python
process:
web:
cmd: app:app
server_name: myapp.com
workers: 2
cron: "0 0 * * * python backup.py"
myownworker: python events-listener.py
Example: git remote add sailor sailor@$host:myapp.com
Push your code: git push sailor master
We did it, Okurrr!
Sailor communicates with your server via SSH, with the user name: sailor
You must already already have SSH access to the machine for it to work.
ie: ssh sailor@$host
ssh sailor@$host
ls
ssh sailor@$host ls
The command above will show the minimal info. To expand:
ssh sailor@$host ls x
start $app_name
ssh sailor@$host start $app_name
stop $app_name
ssh sailor@$host stop $app_name
rm $app_name
To completely delete the application
ssh sailor@$host rm $app_name
To force remove an app without prompt rm -f $app_name
ssh sailor@$host rm -f $app_name
reload $app_name
To reload a running application
ssh sailor@$host reload $app_name
info $app_name
ssh sailor@$host info $app_name
log $app_name
ssh sailor@$host log $app_name
reset-ssl $app_name
To re-issue the SSL
ssh sailor@$host reset-ssl $app_name
To increase/decrease the total workers for this process
ssh sailor@$host scale $app_name $proc=$count $proc2=$count2
Example:
ssh sailor@$host scale site.com web=4
reload-all
ssh sailor@$host apps:reload-all
stop-all
ssh sailor@$host apps:stop-all
x:version
ssh sailor@$host system:version
x:update
To update Sailor to the latest from Github
ssh sailor@$host system:update
Additionally, you can update from a specific branch, usually for testing purposes
ssh sailor@$host system:update $branch-name
Sailor is a utility to install on a host machine, that allows you to deploy multiple apps, micro-services, webites, run scripts and background workers on a single VPS (Digital Ocean, Linode, Hetzner).
Sailor follows a process similar to Heroku or Dokku where you Git push code to the host and Sailor will:
Sailor supports deployment for:
Sailor is a simpler alternative to Docker containers or Dokku. It mainly deals with your application deployment, similar to Heroku.
Sailor takes away all the complexity of Docker Containers or Dokku and gives you something simpler to deploy your applications, similar to Heroku, along with SSL.
Sailor
Sailor supports a Heroku-like workflow, like so:
git
SSH remote pointing to your Sailor server with the app name as repo name.git remote add sailor sailor@[yourserver]:[appname]
.git push sailor master
.requirements.txt
into a virtualenv
.package.json
into node_modules
.sailor.yml
and starts the relevant applications using a generic process manager.release
worker which is run once when the app is deployed.static
worker type, with the root path as the argument, can be used to deploy a gh-pages style static site.sailor.yml
is a manifest format for describing apps. It declares environment variables, scripts, and other information required to run an app on your server. This document describes the schema in detail.
sailor.yml
contains an array of all apps to be deploy, and they are identified by name
.
When setting up the remote, the name
must match the name
in the sailor.yml
# ~ Sailor ~
# sailor.yml
# Sailor Configuration (https://mardix.github.io/sailor)
#
---
# *required: list/array of all applications to run
apps:
-
# *required - the name of the application
name:
# runtime: python|node|static|shell
# python for wsgi application (default python)
# node: for node application, where the command should be ie: 'node inde.js 2>&1 | cat'
# static: for HTML/Static page and PHP
# shell: for any script that can be executed via the shell script, ie: command 2>&1 | cat
runtime: static
# auto_restart (bool): to force server restarts when deploying
auto_restart: true
# static_paths (array): specify list of static path to expose, [/url:path, ...]
static_paths:
# SSL issuer: letsencrypt(default)|zerossl
ssl_issuer: letsencrypt
# threads (int): The total threads to use
threads: 4
# wsgi (bool): if runtime is python by default it will use wsgi, if false it will fallback to the command provided
wsgi: true
# nginx (object): nginx specific config. can be omitted
nginx:
include_file: ''
# uwsgi (object): uwsgi specific config. can be omitted
uwsgi:
gevent: false
asyncio: false
# env (object) custom environment variable
env:
KEY: VALUE
KEY2: VALUE2
# scripts to run during application lifecycle
scripts:
# release (array): commands to execute each time the application is released/pushed
release:
# destroy (array): commands to execute when the application is being deleted
destroy:
# predeploy (array): commands to execute before spinning the app
predeploy:
# postdeploy (array): commands to execute after spinning the app
postdeploy:
# *required - process - list of all processes to run.
# 'web' is special, it’s the only process type that can receive external HTTP traffic
# only one web proctype can exist
# all other process name will be regular worker.
# The name doesn't matter
process:
# == web
# (dict/object): it’s the only process type that can receive external HTTP traffic
web:
# == (required) cmd(str) - the command to execute
#-> cmd: app:app (for python using wsgi)
#-> cmd: node server.js 2>&1 cat (For other web app which requires a server command)
#-> cmd: /web-root-dir-name (for static html+php)
cmd:
# == (required) server_name(str)
# the server name without http/https
server_name:
# == server_port(str)
# to use IP/PORT based instead of server_name. To give access to http://IP:8080
# ie:
# server_name: _ # server_name must be set to '_'
# server_port: 8080
server_port:
# === workers(int)
# the number of workers to run, by default 1
workers: 1
# === enabled(bool)
# a boolean to enable/disable this process, by default true
enabled: true
# ==
# other processes (string): command to run, with a name. The name doesn't matter - It can be named anything
worker1:
# == (required) cmd(str) - the command to execute
cmd:
# === workers(int)
# the number of workers to run, by default 1
workers: 1
# === enabled(bool)
# a boolean to enable/disable this process, by default true
enabled: true
# ==
# for simplicity you can pass the command in the name as a string
# workerX: python script.py
workerX:
# == cron
# Cron proc allows you to run script periodically like cronjob
# similar to web, only one cron can exist. And it can only have 1 worker
# Also, put the cron in quotes to prevent deploy error
# Simple cron expression:
# minute [0-59], hour [0-23], day [0-31], month [1-12], weekday [1-7] (starting Monday, no ranges allowed on any field)
# cron: "* * * * * python cron.py"
cron:
You can deploy a site without a server name.
The server IP will be used instead of a server name
You need to set the web.server_port
to the desired port.
Beware the connection will not be behind NGINX nor use SSL.
This option is mainly for internal or IP based app.
# example sailor.yml
...
process:
web:
...,
#-- set server name to _
server_name: _
#-- set server port
server_port: 8081
TODO
0.12.0
python3.11
install-2004.sh
0.11.1
rm -f|--force
to force remove an application without the prompt. ie: sailor rm -f $app_name
0.11.0
0.10.0
enabled
to run/not-run a process. Especially if you don’t want to run a process without removing the code.0.5.0
0.4.0
cron
workers, which require a simplified cron
expression preceding the command to be run (e.g. cron: * * * * * python batch.py
to run a batch every minyte
proces:
cron: "* * * * * python cron.py"
expand process list to allow process to have extended properties as dict/hash:
process:
web:
cmd:
server_name:
workers:
others:
cmd:
workers:
server_name
can now be added in process.web.server_name
system:update 1.2.0
0.3.1
0.2.0
0.1.0
Credit: Sailor is a fork of Piku https://github.com/piku/piku. Great work and Thank you.
Author: Mardix
License: MIT
Copyright 2021, 2022 to Forever