Skip to content

Commit

Permalink
Introduce HTTPS support via mkcert
Browse files Browse the repository at this point in the history
  • Loading branch information
robertlemke committed Oct 15, 2020
1 parent ee2fbb0 commit 89d1049
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 12 deletions.
11 changes: 11 additions & 0 deletions .github/workflows/localbeach.rb.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,21 @@ class Localbeach < Formula

conflicts_with "flownative/flownative/beach-cli", because: "localbeach replaces beach-cli"

depends_on "docker" => :build
depends_on "mkcert" => :run
depends_on "nss" => :run

def install
database_path = RUBY_PLATFORM.downcase.include?("darwin") ? "~/Library/Application Support/Flownative/Local Beach/MariaDB" : "~/.Flownative/Local Beach/MariaDB"

bin.install "beach" => "beach"
system "#{bin}/beach", "setup", "--docker-folder", "#{lib}/localbeach", "--database-folder", database_path
end

def caveats
<<~EOS
Local Beach is built on top of Docker and Docker Compose. You will need a working setup of both in order to use Local
Beach.
EOS
end
end
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,36 @@
Local Beach
-----------

Currently automatic installation via Homebrew (on a Mac) is supported. Manual installation on
Linux is *possible*, but requires some fiddling.

The setup instructions for Local Beach are currently located in our [knowledge base](https://support.flownative.com/help/en-us/14-local-beach/38-how-to-set-up-local-beach).

tldr;
```
brew tap flownative/flownative
brew install localbeach
beach version
```

Internals
---------

Some random notes about the internals of Local Beach:

- `beach setup` is automatically invoked by Homebrew when Local Beach is installed
- the default path for MariaDB is "~/Library/Application Support/Flownative/Local Beach/MariaDB" on MacOS and "~/.Flownative/Local Beach/MariaDB" on other systems (see .github/workflows/localbeach.rb.tpl)
- the default path for Nginx certificates is "~/Library/Application Support/Flownative/Local Beach/Nginx/Certificates" on MacOS and "~/.Flownative/Local Beach/Nginx/Certificates" on other systems (see .github/workflows/localbeach.rb.tpl)
- the Docker Compose configuration for the Nginx Proxy and MariaDB can be found at "/usr/local/lib/localbeach"

During install, Homebrew runs `beach setup` as follows:

```
beach setup \
--database-folder ~/Library/Application\ Support/Flownative/Local\ Beach/MariaDB \
--nginx-folder ~/Library/Application\ Support/Flownative/Local\ Beach/Nginx \
--docker-folder /usr/local/lib/localbeach
```

Build
-----
Expand All @@ -12,6 +42,6 @@ To build the binary, run `make`. It does this:
```bash
go generate -v
go install -v
go build -v -o beach
go build -v -ldflags "-X github.com/flownative/localbeach/pkg/version.Version=dev" -o beach
```

6 changes: 4 additions & 2 deletions assets/local-beach/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ networks:
name: local_beach

services:
nginx:
image: flownative/localbeach-nginx-proxy:0.1.2-2
webserver:
image: flownative/localbeach-nginx-proxy:0.2.0
container_name: local_beach_nginx
networks:
- local_beach
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- {{nginxFolder}}/Certificates:/etc/nginx/certs
environment:
- DEFAULT_HOST=hello.localbeach.net
database:
Expand Down
8 changes: 4 additions & 4 deletions cmd/beach/cmd/down.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
// downCmd represents the down command
var downCmd = &cobra.Command{
Use: "down",
Short: "Stop instances, database and webserver and remove containers",
Short: "Stop instances, reverse proxy and database server and remove containers",
Long: "",
Args: cobra.ExactArgs(0),
Run: handleDownRun,
Expand All @@ -40,7 +40,7 @@ func init() {
}

func handleDownRun(cmd *cobra.Command, args []string) {
instanceRoots, err := findInstancRoots()
instanceRoots, err := findInstanceRoots()
if err != nil {
log.Fatal(err)
return
Expand All @@ -60,7 +60,7 @@ func handleDownRun(cmd *cobra.Command, args []string) {
}
}

log.Info("Stopping database & nginx...")
log.Info("Stopping reverse proxy and database server ...")
commandArgs := []string{"-f", "/usr/local/lib/localbeach/docker-compose.yml", "rm", "--force", "--stop", "-v"}
output, err := exec.RunCommand("docker-compose", commandArgs)
if err != nil {
Expand All @@ -71,7 +71,7 @@ func handleDownRun(cmd *cobra.Command, args []string) {
return
}

func findInstancRoots() ([]string, error) {
func findInstanceRoots() ([]string, error) {
var configurationFiles []string

output, err := exec.RunCommand("docker", []string{"ps", "-q", "--filter", "name=_devkit"})
Expand Down
37 changes: 36 additions & 1 deletion cmd/beach/cmd/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package cmd

import (
"github.com/flownative/localbeach/pkg/exec"
"os"
"path/filepath"
"strings"
Expand All @@ -26,6 +27,7 @@ import (

var dockerFolder string
var databaseFolder string
var nginxFolder string

// setupCmd represents the setup command
var setupCmd = &cobra.Command{
Expand All @@ -38,6 +40,7 @@ var setupCmd = &cobra.Command{

func init() {
setupCmd.Flags().StringVar(&dockerFolder, "docker-folder", "", "Defines the folder used for docker metadata.")
setupCmd.Flags().StringVar(&nginxFolder, "nginx-folder", "", "Defines the folder used for Nginx configuration.")
setupCmd.Flags().StringVar(&databaseFolder, "database-folder", "", "Defines the folder used for the database server.")
rootCmd.AddCommand(setupCmd)
}
Expand All @@ -51,6 +54,10 @@ func handleSetupRun(cmd *cobra.Command, args []string) {
log.Fatal("docker-folder must be given.")
return
}
if len(nginxFolder) == 0 {
log.Fatal("nginx-folder must be given.")
return
}

err := os.MkdirAll(databaseFolder, os.ModePerm)
if err != nil {
Expand All @@ -60,16 +67,44 @@ func handleSetupRun(cmd *cobra.Command, args []string) {
if err != nil {
log.Error(err)
}
err = os.MkdirAll(nginxFolder, os.ModePerm)
if err != nil {
log.Error(err)
}
err = os.MkdirAll(nginxFolder + "/Certificates", os.ModePerm)
if err != nil {
log.Error(err)
}

composeFileContent := readFileFromAssets("local-beach/docker-compose.yml")
composeFileContent = strings.ReplaceAll(composeFileContent, "{{databaseFolder}}", databaseFolder)
composeFileContent = strings.ReplaceAll(composeFileContent, "{{nginxFolder}}", nginxFolder)

destination, err := os.Create(filepath.Join(dockerFolder, "docker-compose.yml"))
if err != nil {
log.Error(err)
}
defer destination.Close()
destination.WriteString(composeFileContent)

_, err = destination.WriteString(composeFileContent)
if err != nil {
log.Error(err)
}

commandArgs := []string{"-install"}
err = exec.RunInteractiveCommand("mkcert", commandArgs)
if err != nil {
log.Error(err)
return
}

commandArgs = []string{"-cert-file", nginxFolder + "/Certificates/default.crt", "-key-file", nginxFolder + "/Certificates/default.key", "*.localbeach.net"}
err = exec.RunInteractiveCommand("mkcert", commandArgs)
if err != nil {
log.Error(err)
return
}


return
}
8 changes: 4 additions & 4 deletions cmd/beach/cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,25 +95,25 @@ func startLocalBeach() error {
return errors.New("failed to check for running containers")
}
if len(output) == 0 {
log.Info("Starting nginx & database ...")
log.Info("Starting reverse proxy and database server ...")
commandArgs := []string{"-f", "/usr/local/lib/localbeach/docker-compose.yml", "up", "--remove-orphans", "-d"}
err = exec.RunInteractiveCommand("docker-compose", commandArgs)
if err != nil {
return errors.New("container startup failed")
}

log.Info("Waiting for database ...")
log.Info("Waiting for database server ...")
tries := 1
for {
output, err := exec.RunCommand("docker", []string{"inspect", "-f", "{{.State.Health.Status}}", "local_beach_database"})
if err != nil {
return errors.New("failed to check for database container health")
return errors.New("failed to check for database server container health")
}
if strings.TrimSpace(output) == "healthy" {
break
}
if tries == 10 {
return errors.New("timeout waiting for database to start")
return errors.New("timeout waiting for database server to start")
}
tries++
time.Sleep(3 * time.Second)
Expand Down

0 comments on commit 89d1049

Please sign in to comment.