MCPcopy Index your code
hub / github.com/applikatoni/applikatoni

github.com/applikatoni/applikatoni @1.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release 1.3.0 ↗ · + Follow
277 symbols 938 edges 46 files 2 documented · 1%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Applikatoni - Deployments Al Forno Build Status GoDoc

Applikatoni is a self-hosted deployment server for small teams, that takes your code from GitHub and deploys it to your servers, by running shell commands you define.

Introduction

Applikatoni was developed at flinc for internal use and later open sourced.

With its web-frontend and its deep GitHub integration it allows you to deploy your applications to multiple servers with the click of a button.

Besides giving your team a history of deployments, so you can see what has been deployed by whom to which servers, it also offers integration into a multitude of a third-party services, so your team never misses a deployment. Deploy pull requests from GitHub, check the Travis CI status of a branch before deploying, notify your team in Flowdock or Slack about deployments, tell NewRelic about the current revision of your application and reset Bugsnag after a deployment.

No database server is needed. Applikatoni stores information about deployment in a sqlite3 file. Easy to use, easy to maintain and easy to backup.

At its core, Applikatoni is technology agnostic. Deploy Rails, Node.js, Java and Go applications. It doesn't matter to Applikatoni. It doesn't do more than taking your code from GitHub and deploying it to your servers by running the shell commands you specify.

You can run different scripts on different hosts, if they fulfill different roles in your system. Your application server may need to run different commands than your background worker server, or your database server. Applikatoni can handle all of this.

With the ability to deploy multiple applications to different servers with varying deployment strategies you can use Applikatoni however you like.

And if clicking isn't your thing and you prefer a terminal over a web frontend: check out toni -- the CLI for your Applikatoni server.

Also: there is a lot of pizza involved! 🍕

Getting started

  1. Create a GitHub Application for your organization so Applikatoni can access your code:

      https://github.com/organizations/<YOUR ORGANIZATION>/settings/applications
    

    Enter the OAuth2 callback URL:

      <where your applikatoni instance will be hosted>/oauth2/callback
    
  2. Install Applikatoni on your server. See Installation for more information

  3. Configure Applikatoni. See Configuration for detailed instructions.

  4. Setup the database with the packaged goose binary. See Usage on how to do that.

  5. Start Applikatoni

Installation

Dependencies

Download a packaged version

See the Releases section and download a packaged version of Applikatoni.

Installing using go get

    go get github.com/applikatoni/applikatoni/server

Usage

  1. Make sure the database file is setup and migrated:
    go get bitbucket.org/liamstask/goose/cmd/goose
    vim db/dbconf.yml
    goose -env="production" up
    
    1. Create a configuration.json file for your needs. See Configuration for more information.

      cp configuration_example.json configuration.json vim configuration.json 3. Start the server:

      ./applikatoni -port=:8080 -db=./db/production.db -conf=./configuration.json -env=production

How it works

Applikatoni is a server with a web-frontend that allows users to deploy specific commits hosted on GitHub to multiple servers.

A deployment process consists of multiple stages, which Applikatoni will execute sequentially on each server, but at the same time on all servers.

A stage is nothing more than a few lines of shell commands, that you specify. These shell commands can contain variables, like CommitSha, RubyVersion, WorkingDirectory and so on. Before the deployment process starts, Applikatoni "renders" these scripts templates into fully executable commands, by injecting the values of the variables.

With the templates fully rendered, Applikatoni then connects to the specified servers via SSH (and a username and private SSH key you specify) and executes these shell commands.

If one stage fails, the whole deployment process is stopped after the failed stage has finished on all servers, so there is no inconsistent state.

Which stages are executed on which servers depends on which roles each server fulfills in your system. If the server one.your-company.com has the role "application-server" and two.your-company.com has the role "queue-server" only the stages specified for the respective stages get executed on the servers.

Here is an excerpt from an example configuration.json:

"default_stages": ["PRE_DEPLOYMENT", "CODE_DEPLOYMENT", "POST_DEPLOYMENT"],
"available_stages": ["PRE_DEPLOYMENT", "CODE_DEPLOYMENT", "MIGRATE_DATABASE", "POST_DEPLOYMENT"],
"hosts": [
  {
    "name": "web.shipping-company.com:22",
    "roles": ["web", "migrator"]
  },
  {
    "name": "workers.shipping-company.com:22",
    "roles": ["workers"]
  }
],
"roles": [
  {
    "name": "workers",
    "script_templates": {
      "PRE_DEPLOYMENT": "sudo /etc/init.d/workers stop",
      "CODE_DEPLOYMENT": "cd {{.Dir}}/current && git fetch origin && git reset -q --hard {{.CommitSha}}",
      "POST_DEPLOYMENT": "sudo /etc/init.d/workers start"
    },
    "options": {
      "Dir": "/var/www/our-main-application"
    }
  },
  {
    "name": "web",
    "script_templates": {
      "PRE_DEPLOYMENT": "sudo /etc/init.d/application-server prepare",
      "CODE_DEPLOYMENT": "cd {{.Dir}}/current && git fetch origin && git reset -q --hard {{.CommitSha}}",
      "POST_DEPLOYMENT": "sudo /etc/init.d/application-server reload"
    },
    "options": {
      "Dir": "/var/www/our-main-application"
    }
  },
  {
    "name": "migrator",
    "script_templates": {
      "MIGRATE_DATABASE": "cd {{.Dir}} && make migrate-database"
    },
    "options": {
      "Dir": "/var/www/our-main-application",
    }
  }
]

The web.shipping-company.com host has the roles web and migrator. The workers.shipping-company.com host has the role workers.

With a default deployment, the stages PRE_DEPLOYMENT, CODE_DEPLOYMENT and POST_DEPLOYMENT will be run on those two hosts.

If you also select MIGRATE_DATABASE before creating the deployment, the stages PRE_DEPLOYMENT, CODE_DEPLOYMENT, MIGRATE_DATABASE and POST_DEPLOYMENT will be run on those two hosts. In this order. And since workers.shipping-company.com doesn't fulfill the migrator role, the MIGRATE_DATABASE stage will be skipped on this server.

Before running the commands, Applikatoni converts this:

cd {{.Dir}}/current && git fetch origin && git reset -q --hard {{.CommitSha}}

into this:

cd /var/www/our-main-application/current && git fetch origin && git reset -q --hard F00B4R

where F00B4R is the commit SHA you selected in the web frontend.

Terminology

  • application - Applikatoni can deploy multiple applications
  • target - The target environment of a deployment, e.g.: production
  • host - Each target has one or more hosts, the servers to which to deploy to. e.g.: web-application.production.shipping-company.com
  • role - Every host of each target fulfills different roles. What gets executed and when on which host depends on the roles this host has. e.g.: database-server or web-app-server.
  • stage - A deployment consists of one or more stages. A role defines one or more stages (by defining script_templates for each stage). A stage can succeed or fail while deploying the application. If a stage failed, the deployment stops after this change. All stages are executed synchronously on all hosts (but in parallel).

Configuration

Requirements

  • a user on the servers you want to deploy your application to with a SSH-Key
  • a GitHub OAuth application (See here)

The configuration.json

The Applikatoni is configured by reading a configuration.json file.

You can find a simplified example for a Rails application with two Unicorn web servers and one Sidekiq worker server here: configuration_example.json. Or read on to get a run down of what it's doing.

Sample

Here is a sample configuration.json for an application called our-main-application with its source code hosted under github.com/shipping-company/our-main-application.

The application will be deployed to three servers:

  • 1.unicorn.production.shipping-company.com
  • 2.unicorn.production.shipping-company.com
  • 1.workers.production.shipping-company.com

The deployment process reflects one of a typical Rails application with the Unicorn webserver and Sidekiq as a background worker process.

  1. Shut down sidekiq
  2. Pull down the code from GitHub (the CommitSha variable is injected by Applikatoni into the script templates and represents the commit the user wants to deploy)
  3. Install dependencies
  4. Hot-reload Unicorn / start sidekiq
{
  "ssl_enabled": false,
  "host": "applikatoni.shipping-company.com",
  "session_secret": "<SECRET>",
  "oauth2_state_string": "<UNGUESSABLE RANDOM OAUTH2 STATE STRING>",
  "github_client_id": "<CLIENT_ID>",
  "github_client_secret": "<CLIENT_SECRET>",
  "mandrill_api_key": "<API_KEY>",
  "applications": [
    {
      "name": "our-main-application",
      "read_usernames": ["<CAN READ DEPLOYMENT HISTORY BUT NOT DEPLOY>"],
      "github_owner": "shipping-company",
      "github_repo": "our-main-application",
      "github_branches": ["master", "develop", "production", "production"],
      "travis_image_url": "https://magnum.travis-ci.com/shipping-company/our-main-application.svg?token=<KEY HERE>",
      "daily_digest_receivers": ["team@shipping-company.com"],
      "daily_digest_target": "production",
      "targets": [
        {
          "name": "production",
          "deployment_user": "deploy",
          "deployment_ssh_key": "<SSH KEY>",
          "deploy_usernames": ["<YOUR GITHUB USERNAME>"],
          "default_stages": ["CHECK_CONNECTION", "PRE_DEPLOYMENT", "CODE_DEPLOYMENT", "POST_DEPLOYMENT"],
          "available_stages": ["CHECK_CONNECTION", "PRE_DEPLOYMENT", "CODE_DEPLOYMENT", "MIGRATE_DATABASE", "POST_DEPLOYMENT"],
          "bugsnag_api_key": "<YOUR BUGSNAG API KEY>",
          "flowdock_endpoint": "<FLOWDOCK REST ENTRY POINT WITH HTTP AUTH>",
          "new_relic_api_key": "<NEW RELIC API KEY>",
          "new_relic_app_id": "<NEW RELIC APP ID>",
          "slack_url": "<SLACK INCOMING WEBHOOK URL>",
          "webhooks": [
            {
              "url": "<URL>",
              "entries": ["<ENTRYTYPE>"]
            }
          ],
          "hosts": [
            {
              "name": "1.unicorn.production.shipping-company.com:22",
              "roles": ["web", "migrator"]
            },
            {
              "name": "2.unicorn.production.shipping-company.com:22",
              "roles": ["web"]
            },
            {
              "name": "1.workers.production.shipping-company.com:22",
              "roles": ["workers"]
            }
          ],
          "roles": [
            {
              "name": "workers",
              "script_templates": {
                "CHECK_CONNECTION": "test -d {{.Dir}}",
                "PRE_DEPLOYMENT": "sudo /etc/init.d/sidekiq stop",
                "CODE_DEPLOYMENT": "cd {{.Dir}}/current && git fetch --tags -q origin && git reset -q --hard {{.CommitSha}}\ncd {{.Dir}}/current && RAILS_ENV={{.RailsEnv}} bundle install --gemfile {{.Dir}}/current/Gemfile --path {{.Dir}}/shared/bundle --deployment --quiet --without development test",
                "POST_DEPLOYMENT": "sudo /etc/init.d/sidekiq start"
              },
              "options": {
                "Dir": "/var/www/our-main-application",
                "RailsEnv": "production"
              }
            },
            {
              "name": "web",
              "script_templates": {
                "CHECK_CONNECTION": "test -d {{.Dir}}",
                "PRE_DEPLOYMENT": "echo 'Unicorn will keep on working'",
                "CODE_DEPLOYMENT": "cd {{.Dir}}/current && git fetch --tags -q origin && git reset -q --hard {{.CommitSha}}\ncd {{.Dir}}/current && RAILS_ENV={{.RailsEnv}} bundle install --gemfile {{.Dir}}/current/Gemfile --path {{.Dir}}/shared/bundle --deployment --quiet --without development test",
                "POST_DEPLOYMENT": "sudo /etc/init.d/unicorn hot-reload"
              },
              "options": {
                "Dir": "/var/www/our-main-application",
                "RailsEnv": "production"
              }
            },
            {
              "name": "migrator",
              "script_templates": {
                "MIGRATE_DATABASE": "cd {{.Dir}} && RAILS_ENV={{.RailsEnv}} bundle exec rake db:migrate"
              },
              "options": {
                "Dir": "/var/www/our-main-application",
                "RailsEnv": "production"
              }
            }
          ]
        }
      ]
    }
  ]
}

General Properties

  • ssl_enabled - Turn this on if your Applikatoni instance is accessed via https.
  • host - The host of your Applikatoni instance. Example: applikatoni.shipping-company.com
  • session_secret - The secret for encrypt sessions in cookies. Use a generated, random secret.
  • `oauth2_s

Extension points exported contracts — how you extend this code

Listener (FuncType)
(no doc)
deploy/logging.go

Core symbols most depended-on inside this repo

Log
called by 16
deploy/deployment_logger.go
Close
called by 16
deploy/worker.go
Add
called by 14
server/kill_registry.go
Announce
called by 13
deploy/logging.go
Subscribe
called by 13
deploy/logging.go
createDeployment
called by 13
server/database.go
Get
called by 13
server/kill_registry.go
NewLogRouter
called by 12
deploy/logging.go

Shape

Function 181
Method 59
Struct 32
TypeAlias 4
FuncType 1

Languages

Go90%
TypeScript10%

Modules by API surface

server/handlers.go27 symbols
server/database.go23 symbols
server/database_test.go22 symbols
deploy/logging.go18 symbols
deploy/deployment_logger.go16 symbols
server/assets/clickspark.min.js14 symbols
deploy/manager.go14 symbols
server/github.go13 symbols
server/assets/applikatoni.js11 symbols
deploy/worker.go11 symbols
deploy/logging_test.go9 symbols
server/daily_digest.go8 symbols

For agents

$ claude mcp add applikatoni \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact