fold

module
v0.1.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2021 License: MPL-2.0

README

Fold

Fold is a platform and a set of tools for developing and deploying backends. The goal is to make running a set of microservices on the cloud as easy as running them locally.

WARNING: This is seriously alpha...

Table of Contents

Overview

Fold aims to take cloud based infrastructure and serverless computing to its ultimate conclusion. Infrastructure shouldn't just be easy, we shouldn't have to think about it at all.

It has happened countless times already in our industry. Compilers removed the need to think about machine code, garbage collection freed us from managing memory, web frameworks liberated us from network programming and boilerplate, and cloud computing unchained us from looking after servers in cupboards.

Fold aims to do the same for cloud based applications. No one wants to spend hours fiddling with yaml and cursing configuration errors. No, we want to develop applications simply and locally, and then magically have them deployed around the globe at any scale we like.

Fold is trying to build that, here are the principles behind the experience we're trying to create:

  • Local development is a first class citizen. If it works locally it should work remotely.
  • You shouldn't have to think about where your application is running or how it will get there.
  • You shouldn't have to think about creating and managing infrastructure such as databases or message brokers.
  • You should be able to write the application in the same way whether you are serving 10 or 10,000,000 customers.
  • You shouldn't have to spend any time iterating on complex configuration.

Installation

You just need a binary for the command line tool, foldctl. Head over to the releases page to grab the latest release for your system. Simply download and extract the binary, make it executable and place it somewhere on your $PATH.

The only dependency for local development is docker, which foldctl uses to build containers and run them for you locally. You can get docker from the docker website.

Linux

You will need to use the foldctl-$VERSION-linux-amd64.tar.gz release.

For example:

tar xzvf foldctl-$VERSION-darwin-amd64.tar.gz
chmod +x ./foldctl-$VERSION-linux-amd64
sudo mv ./foldctl-$VERSION-linux-amd64 /usr/local/bin/foldctl

Mac

You will need to use the foldctl-$VERSION-darwin-amd64.tar.gz release.

For example:

tar xzvf foldctl-$VERSION-darwin-amd64.tar.gz
chmod +x ./foldctl-$VERSION-darwin-amd64
sudo mv ./foldctl-$VERSION-darwin-amd64 /usr/local/bin/foldctl

Build from Source

Alternatively you can easily build the tool from source if you have the go compiler available. Simply check out the source at the tag you want and run:

go install ./cmd/foldctl/

Speed Run

To get started you will need to use the new command, which is used to create new fold projects and services. They will both guide you through a few set up options.

The up command will then start your new service. You will have to change the path depending on the name you chose for your service in the setup. The below example assumes you called your service new-service

foldctl new project
foldctl new service
foldctl up new-service/

Once the up command has run succesfully it will be available as an HTTP service on your machine. The command should give you some information about how to reach your new service and which routes have been registered:

Fold gateway is available at http://localhost:6123

    new-service is available at http://localhost:6123/service-name
    new-service routes:
        GET http://localhost:6123/new-service/hello/:name

Note the new-service in the URL. The gateway creates a path for every service, based on its name, and you must include that in the URL to contact the service you are interested in.

This is because fold supports running multiple services (as many as you'd like) and you need to be able to identify the right one through the gateway. You can try this out by creating a new service and starting it:

foldctl new service
foldctl up second-service/

The new service will be available on:

localhost:6123/second-service

When you're done run foldct down from the project root to bring down the services.

Working with Fold

Project Templates

You can find example projects over in the templates repository. These templates are also what foldctl uses to create new services. The foldctl new service command will present you with options based on what is available there.

Feel free to submit your own via a PR! The intention over time is to create a repository of useful generic services which can be added to your project with a single command.

For example, there may be an auth-service, removing the need for you to build an integrate it yourself.

Project Structure

A fold project has a very simple structure. It consists of a project root, which is identified by the fold.yaml file, and services.

Services are simply subdirectories within a fold project that container a valid Dockerfile and which are registered in your fold.yaml file. The only caveat is that the Dockerfile must build an image which implements the fold runtime interface.

Project Config

A key aim of the fold platform is to eliminate all of the endless yaml that typically comes with looking after modern cloud based applications. That said, a small concession has been made in the form of the fold.yaml file which resides in your project root.

It looks something like this:

email: [email protected]
maintainer: me
name: fold-project
repository: github.com/foo
services:
- name: user-service
  path: ./user-service
  mounts:
  - ./app
- name: score-service
  path: ./score-service
  mounts:
  - ./app

It is just used to configure a few bits of metadata and to register services. Additionally, there are a few options on the services that allow you to configure things for local development, for example which directories to mount on your containers so you can hot reload your changes.

Hot Reloading

In the service config, there is a key called mounts which simply takes a list of paths to mount to your running development containers. The paths are relative to the service and will be mounted related to the WORKDIR in yoru container.

For example, if I have a service located at ./foo, and mount ./bar/baz, then the directory ./foo/bar/baz (relative to the project root) will be mounted at WORKDIR/bar/baz in your development containers.

The fold runtime will watch for changes in all mounted directories during local development and reload the service if it detects any changes.

There are two key points to bear in mind if you are not familiar with how bind mounts work on a docker container.

  1. If the directory does not exist on your host then the container will fail to start.
  2. The directory on the host overwrites the directory on the container. This means that if the the directory is empty on the host (for example a build output directory) then it will also be empty in the container. Don't worry though, if you end up here the just build the service locally and the fold runtime will detect the changes and start up the service.

SDKs

Currently there are two fold SDKs, one for NodeJS, supporting both TypeScript and JavaScript, and another for go.

There is no documentation for the SDKs yet but they are still very small and simple to use. The examples from the templates show off more or less everything they can do right now.

Deployment

You can't yet, coming soon!

Fold Runtime

The fold runtime acts as the interface between your services, implemented using the fold sdk, and the infrastructure which the fold platform has provisioned for you.

In cloud design pattern parlance it is akin to an ambassador, however it is embedded directly in your container.

All of your services must implement the runtime interface. The easiest way is to use a provided base image but you can create your own very easily too.

Base Images

A valid fold service is simply an OCI image that implements the fold runtime interface. In order to make things easy there are some base images that you can extend, check out the available tags on docker hub.

In order to use one of these, you just have to extend the image and set the CMD in your Dockerfile to be the command for invoking your application. It's important that you don't override the ENTRYPOINT.

Custom Images

It's very easy to create your own image if you need a bit more control. You just need to get a copy of the foldrt binary from the releases page. It is pretty small (around 12MB) and has no dependencies (not even libc), so it is very easy to work with.

All you need to do is set your container up to run the foldrt binary with your application command and arguments passed as the arguments to foldrt. For example, if you normally run your app with the command node ./dist/index.js, you need to run foldrt node ./dist/index.js.

Directories

Path Synopsis
cmd
foldctl/commands
This file contains a number of 'actions' which are common to many commands.
This file contains a number of 'actions' which are common to many commands.
ctl
container
Package container contains utilities for building image from services.
Package container contains utilities for building image from services.
fs
This is quite a simple implementation of this, for a more complete one see: https://github.com/moby/moby/blob/master/daemon/graphdriver/copy/copy.go
This is quite a simple implementation of this, for a more complete one see: https://github.com/moby/moby/blob/master/daemon/graphdriver/copy/copy.go
git
internal
handler
Package handler defines a variety of handlers which are used to implement runtime interfaces for different environments.
Package handler defines a variety of handlers which are used to implement runtime interfaces for different environments.
supervisor
Package subprocess offers a simple way to manage a subprocess.
Package subprocess offers a simple way to manage a subprocess.
sdks

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL