Skip to content

Commit

Permalink
Rename to kamal-proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmcconnell committed May 28, 2024
1 parent b7df241 commit 95a2ef8
Show file tree
Hide file tree
Showing 16 changed files with 54 additions and 54 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ RUN make

FROM ubuntu as base
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=build /app/bin/parachute /usr/local/bin/
COPY --from=build /app/bin/kamal-proxy /usr/local/bin/
EXPOSE 80 443

CMD [ "parachute", "run" ]
CMD [ "kamal-proxy", "run" ]
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ bench:
go test -bench=. -benchmem -run=^# ./...

docker:
docker build -t parachute .
docker build -t kamal-proxy .

release:
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag basecamp/parachute:latest \
--label "org.opencontainers.image.title=parachute" \
--tag basecamp/kamal-proxy:latest \
--label "org.opencontainers.image.title=kamal-proxy" \
--push .
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
# parachute - A minimal HTTP proxy for zero-downtime deployments 🪂
# kamal-proxy - A minimal HTTP proxy for zero-downtime deployments 🪂

## What it does

`parachute` is a tiny HTTP proxy, designed to make it easy to coordinate
zero-downtime deployments. By running a web application behind `parachute` you can
`kamal-proxy` is a tiny HTTP proxy, designed to make it easy to coordinate
zero-downtime deployments. By running a web application behind `kamal-proxy` you can
deploy changes to it without interruping any of the traffic that's in progress.
No particular cooperation from the application is required for this to work.


## A quick overview

To run an instance of the proxy, use the `parachute run` command. There's no
To run an instance of the proxy, use the `kamal-proxy run` command. There's no
configuration file, but there are some options you can specify if the defaults
aren't right for your application.

For example, to run the proxy on a port other than 80 (the default) you could:

parachute run --http-port 8080
kamal-proxy run --http-port 8080

Run `parachute help run` to see the full list of options.
Run `kamal-proxy help run` to see the full list of options.

To route traffic through the proxy to a web application, you `deploy` instances
of the application to the proxy. Deploying an instance makes it available to the
Expand All @@ -28,7 +28,7 @@ Use the format `hostname:port` when specifying the instance to deploy.

For example:

parachute deploy service1 --target web-1:3000
kamal-proxy deploy service1 --target web-1:3000

This will instruct the proxy to register `web-1:3000` to receive traffic under
the service name `service1. It will immediately begin running HTTP health checks
Expand All @@ -40,7 +40,7 @@ command will stop the deployment and return a non-zero exit code, so that
deployment scripts can handle the failure appropriately.

Each deployment takes over traffic from the previously deployed instance. As
soon as parachute determines that the new instance is healthy, it will route all
soon as kamal-proxy determines that the new instance is healthy, it will route all
new traffic to that instance.

The `deploy` command will wait for traffic to drain from the old instance before
Expand All @@ -54,36 +54,36 @@ with zero downtime.
### Host-based routing

Host-based routing allows you to run multiple applications on the same server,
using a single instance of `parachute` to route traffic to all of them.
using a single instance of `kamal-proxy` to route traffic to all of them.

When deploying an instance, you can specify a host that it should serve traffic
for:

parachute deploy service1 --target web-1:3000 --host app1.example.com
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com

When deployed in this way, the instance will only receive traffic for the
specified host. By deploying multiple instances, each with their own host, you
can run multiple applications on the same server without port conflicts.

Only one service at a time can route a specific host:

parachute deploy service1 --target web-1:3000 --host app1.example.com
parachute deploy service2 --target web-2:3000 --host app1.example.com # returns "Error: host is used by another service"
parachute remove service1
parachute deploy service2 --target web-2:3000 --host app1.example.com # suceeds
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com
kamal-proxy deploy service2 --target web-2:3000 --host app1.example.com # returns "Error: host is used by another service"
kamal-proxy remove service1
kamal-proxy deploy service2 --target web-2:3000 --host app1.example.com # suceeds


### Automatic TLS

`parachute` can automatically obtain and renew TLS certificates for your
`kamal-proxy` can automatically obtain and renew TLS certificates for your
applications. To enable this, add the `--tls` flag when deploying an instance:

parachute deploy service1 --target web-1:3000 --host app1.example.com --tls
kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com --tls


## Building

To build `parachute` locally, if you have a working Go environment you can:
To build `kamal-proxy` locally, if you have a working Go environment you can:

make

Expand All @@ -101,7 +101,7 @@ You can start up a sample environment to try it out using Docker Compose:
This will start the proxy, and 4 instances of a simple web server. You can run
proxy commands with `docker compose exec proxy ...`, for example:

docker compose exec proxy parachute deploy service1 --target parachute-web-1:3000
docker compose exec proxy kamal-proxy deploy service1 --target kamal-proxy-web-1:3000

And then access the proxy from a browser at http://localhost/.

Expand All @@ -110,17 +110,17 @@ And then access the proxy from a browser at http://localhost/.
In some environments, like when running a Docker container, it can be convenient
to specify `run` options using environment variables. This avoids having to
update the `CMD` in the Dockerfile to change the options. To support this,
`parachute run` will read each of its options from environment variables if they
`kamal-proxy run` will read each of its options from environment variables if they
are set. For example, setting the HTTP port can be done with either:

parachute run --http-port 8080
kamal-proxy run --http-port 8080

or:

HTTP_PORT=8080 parachute run
HTTP_PORT=8080 kamal-proxy run

If any of the environment variables conflict with something else in your
environment, you can prefix them with `PARACHUTE_` to disambiguate them. For
environment, you can prefix them with `KAMAL_PROXY_` to disambiguate them. For
example:

PARACHUTE_HTTP_PORT=8080 parachute run
KAMAL_PROXY_HTTP_PORT=8080 kamal-proxy run
7 changes: 7 additions & 0 deletions cmd/kamal-proxy/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "github.com/basecamp/kamal-proxy/internal/cmd"

func main() {
cmd.Execute()
}
7 changes: 0 additions & 7 deletions cmd/parachute/main.go

This file was deleted.

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/basecamp/parachute
module github.com/basecamp/kamal-proxy

go 1.22.1

Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type deployCommand struct {
Expand Down Expand Up @@ -63,6 +63,6 @@ func (c *deployCommand) deploy(cmd *cobra.Command, args []string) error {
return withRPCClient(globalConfig.SocketPath(), func(client *rpc.Client) error {
var response bool

return client.Call("parachute.Deploy", c.args, &response)
return client.Call("kamal-proxy.Deploy", c.args, &response)
})
}
4 changes: 2 additions & 2 deletions internal/cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type listCommand struct {
Expand All @@ -30,7 +30,7 @@ func (c *listCommand) run(cmd *cobra.Command, args []string) error {
return withRPCClient(globalConfig.SocketPath(), func(client *rpc.Client) error {
var response server.ListResponse

err := client.Call("parachute.List", true, &response)
err := client.Call("kamal-proxy.List", true, &response)
if err != nil {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/pause.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type pauseCommand struct {
Expand Down Expand Up @@ -35,6 +35,6 @@ func (c *pauseCommand) run(cmd *cobra.Command, args []string) error {
c.args.Service = args[0]

return withRPCClient(globalConfig.SocketPath(), func(client *rpc.Client) error {
return client.Call("parachute.Pause", c.args, &response)
return client.Call("kamal-proxy.Pause", c.args, &response)
})
}
4 changes: 2 additions & 2 deletions internal/cmd/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type removeCommand struct {
Expand All @@ -32,6 +32,6 @@ func (c *removeCommand) run(cmd *cobra.Command, args []string) error {
c.args.Service = args[0]

return withRPCClient(globalConfig.SocketPath(), func(client *rpc.Client) error {
return client.Call("parachute.Remove", c.args, &response)
return client.Call("kamal-proxy.Remove", c.args, &response)
})
}
4 changes: 2 additions & 2 deletions internal/cmd/resume.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type resumeCommand struct {
Expand All @@ -32,6 +32,6 @@ func (c *resumeCommand) run(cmd *cobra.Command, args []string) error {
c.args.Service = args[0]

return withRPCClient(globalConfig.SocketPath(), func(client *rpc.Client) error {
return client.Call("parachute.Resume", c.args, &response)
return client.Call("kamal-proxy.Resume", c.args, &response)
})
}
6 changes: 3 additions & 3 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

var globalConfig server.Config

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "parachute",
Use: "kamal-proxy",
Short: "HTTP proxy for zero downtime deployments",
SilenceUsage: true,
}
Expand Down Expand Up @@ -42,7 +42,7 @@ func defaultConfigLocation() string {
home = os.TempDir()
}

folder := path.Join(home, "parachute")
folder := path.Join(home, "kamal-proxy")
err = os.MkdirAll(folder, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IXUSR)
if err != nil {
folder = os.TempDir()
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/spf13/cobra"

"github.com/basecamp/parachute/internal/server"
"github.com/basecamp/kamal-proxy/internal/server"
)

type runCommand struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
)

const (
ENV_PREFIX = "PARACHUTE_"
ENV_PREFIX = "KAMAL_PROXY_"
)

func withRPCClient(socketPath string, fn func(client *rpc.Client) error) error {
Expand Down
2 changes: 1 addition & 1 deletion internal/server/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func NewCommandHandler(router *Router) *CommandHandler {
func (h *CommandHandler) Start(socketPath string) error {
var err error
registered.Do(func() {
err = rpc.RegisterName("parachute", h)
err = rpc.RegisterName("kamal-proxy", h)
})
if err != nil {
slog.Error("Failed to register RPC handler", "error", err)
Expand Down
4 changes: 2 additions & 2 deletions internal/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ type Config struct {
}

func (c Config) SocketPath() string {
return path.Join(c.ConfigDir, "parachute.sock")
return path.Join(c.ConfigDir, "kamal-proxy.sock")
}

func (c Config) StatePath() string {
return path.Join(c.ConfigDir, "parachute.state")
return path.Join(c.ConfigDir, "kamal-proxy.state")
}

func (c Config) CertificatePath() string {
Expand Down

0 comments on commit 95a2ef8

Please sign in to comment.