The database suites (lagoon, lagoon/attach, cabana, beachcomber, lighthouse, bouncer, conga, docs/examples/blog) pass against postgres:15 from a HEAD export with the test image retargeted.
127 lines
5.2 KiB
Markdown
127 lines
5.2 KiB
Markdown
---
|
|
title: Installation
|
|
description: Install the Go toolchain, PostgreSQL and the summer CLI, then build, configure, migrate and serve your first SummerCMS application.
|
|
section: setup
|
|
order: 20
|
|
---
|
|
# Installation
|
|
|
|
SummerCMS is a Go module. An application requires it, lists its plugins in a `summer.yaml` manifest and builds everything into one binary with the `summer` CLI. This page installs the tool, then builds and runs `examples/hello`, the small reference application in the framework repository.
|
|
|
|
## Requirements
|
|
|
|
- Go 1.27.
|
|
- PostgreSQL 15 or newer for any application that uses the data layer.
|
|
- Docker, only for the integration tests that start PostgreSQL or Mailpit containers.
|
|
|
|
You do not need Node.js to build an application or these docs. It is needed only when you work on the admin SPA itself.
|
|
|
|
## Install the summer CLI
|
|
|
|
Clone the framework repository, then install the `summer` tool from its root:
|
|
|
|
```sh
|
|
go install ./cmd/summer
|
|
summer --help
|
|
```
|
|
|
|
The tool builds and watches applications, scaffolds plugins, models, migrations and admin controllers, and builds this documentation. Check that the framework compiles and its unit tests pass:
|
|
|
|
```sh
|
|
go vet ./...
|
|
go test -short ./...
|
|
```
|
|
|
|
`go test -short` skips the tests that need Docker. Run `go test ./...` without `-short` when Docker is available.
|
|
|
|
## Check your install
|
|
|
|
Console commands in SummerCMS are plain `bonfire.Command` values: a name in `namespace:verb` form, its arguments and flags, and a run function that reads input and writes output. The `summer` tool and every application binary are built from such values, and `bonfire.Call` runs one in-process, which is how tests call commands. This example comes from the framework's own tests, so it compiles and runs whenever you run `go test ./...`:
|
|
|
|
```go src=modules/bonfire/example_test.go#ExampleCall
|
|
commands := []bonfire.Command{{
|
|
Name: "acme:greet",
|
|
Description: "Greet someone by name",
|
|
Args: []bonfire.Arg{{Name: "name", Required: true}},
|
|
Run: func(ctx context.Context, in bonfire.Input, out bonfire.Output) error {
|
|
name, _ := in.Argument("name")
|
|
out.Printf("Hello, %s\n", name)
|
|
return nil
|
|
},
|
|
}}
|
|
|
|
if err := bonfire.Call(context.Background(), commands, "acme:greet", []string{"blog"}, os.Stdout); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
// Output: Hello, blog
|
|
```
|
|
|
|
If the tests above pass, this example ran and printed `Hello, blog`. See the [bonfire](../../modules/bonfire/README.md) reference for flags, prompts and styled output.
|
|
|
|
## Build the example application
|
|
|
|
`examples/hello` has three compiled plugins. From the framework root, build it with `summer build`, which generates `plugins.gen.go` and `main.go` from `summer.yaml` and writes the binary to `bin/hello`:
|
|
|
|
```sh
|
|
cd examples/hello
|
|
summer build
|
|
./bin/hello --help
|
|
./bin/hello greeter:hello
|
|
./bin/hello key:generate
|
|
```
|
|
|
|
`greeter:hello` prints the example's layered configuration and `key:generate` prints a fresh application key. Neither needs a database.
|
|
|
|
## Create the database
|
|
|
|
The commands that touch data open PostgreSQL. Create a database for the example:
|
|
|
|
```sql
|
|
CREATE DATABASE hello;
|
|
```
|
|
|
|
## Configure the application
|
|
|
|
Configuration comes from YAML files in `config/`. Any key can be overridden with a `SUMMER_` environment variable, in which a double underscore separates path segments: `SUMMER_DATABASE__DSN` sets `database.dsn`. [Configuration](configuration.md) explains the layers.
|
|
|
|
`serve` and `route:list` need request body limits, and surf reads them as numbers, which the string-valued environment overlay cannot supply. Create `config/http.yaml` in `examples/hello`:
|
|
|
|
```yaml
|
|
body_limits:
|
|
default_bytes: 1048576
|
|
upload_bytes: 10485760
|
|
```
|
|
|
|
Then point the binary at the database, give it the application key and an uploads bucket. Replace the `<secret>` markers with your own values, and never commit them:
|
|
|
|
```sh
|
|
export SUMMER_DATABASE__DSN='postgres://acme:<secret>@127.0.0.1:5432/hello?sslmode=disable'
|
|
export SUMMER_APP__KEY='<value printed by key:generate>'
|
|
export SUMMER_STORAGE__UPLOADS__BUCKET_URL='mem://'
|
|
```
|
|
|
|
## Migrate and serve
|
|
|
|
Run the migrations, list the routes and start the server on the loopback address:
|
|
|
|
```sh
|
|
./bin/hello migrate
|
|
./bin/hello route:list
|
|
./bin/hello serve --addr 127.0.0.1:8080
|
|
curl http://127.0.0.1:8080/items/1
|
|
```
|
|
|
|
From the application directory, `summer migrate`, `summer migrate:status` and `summer serve` run the same commands through the built binary, building it first when it is missing.
|
|
|
|
> [!WARNING]
|
|
> Known issues in the current framework:
|
|
>
|
|
> - `examples/hello` ships no `http.body_limits` configuration, so `serve` and `route:list` fail with `surf: config http.body_limits.default_bytes is required` until you add `config/http.yaml` as shown above. The same gap makes the example's `TestTypedItemRoute` fail.
|
|
> - The committed `examples/hello/main.go` is older than what `summer build` generates now, so building the example leaves that file modified. Restore it with `git checkout -- examples/hello/main.go` if you do not intend to commit it.
|
|
|
|
## Next steps
|
|
|
|
- Read [Coming from WinterCMS](coming-from-wintercms.md) if you are porting a WinterCMS plugin.
|
|
- Read the [Architecture introduction](../architecture/introduction.md) to see how the pieces fit.
|
|
- Scaffold your own plugin with `summer make:plugin` as described in [Plugin registration](../plugins/registration.md).
|