Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
# HTTP server (godeployd)
GODEPLOY_ADDR=:8081

# SQLite database path (godeployd + godeploy-tui)
# SQLite database path (godeployd + godeploy-proxy + godeploy-tui)
GODEPLOY_DB=godeploy.db

# Host-based reverse proxy listen address (godeploy-proxy)
GODEPLOY_PROXY_ADDR=:8080

# Docker network name used for managed containers
GODEPLOY_NETWORK=godeploy

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/security-schedule.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: security-scheduled

# Weekly vulnerability scan (plan_go.md ETAPA 5 — optional scheduled audit).
# Weekly vulnerability scan for newly disclosed Go dependency issues.
on:
schedule:
- cron: "0 6 * * 1"
Expand Down
13 changes: 13 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ builds:
goarch:
- amd64
- arm64
- id: godeploy-proxy
main: ./cmd/godeploy-proxy
binary: godeploy-proxy
env:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
goarch:
- amd64
- arm64
- id: godeploy-logtail
main: ./cmd/godeploy-logtail
binary: godeploy-logtail
Expand All @@ -49,6 +61,7 @@ archives:
ids:
- godeployd
- godeploy-tui
- godeploy-proxy
- godeploy-logtail
formats:
- tar.gz
Expand Down
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Runnable `godeploy-proxy` command, included in local builds and release archives.
- Explicit product-maturity and known-limitations documentation for production evaluation.
- Stage 4 (quality): tests in `internal/pipeline`, `internal/platform/iox`, `internal/platform/sqlpool`; `ExampleParser_Parse_githubPing` in `internal/webhook`; stable `test-cover-check` coverage floor (≥29% with `go test -short`).

### Changed

- Canonical Go module path `github.com/enoquesousa/godeploy-platform`, enabling direct `go install` commands.
- Removed internal planning notes and stray local coverage/error artifacts from the public source tree.
- A+ documentation: README (Makefile table aligned with `fmt`/goimports, `validate-full`, `test-cover-check`, `docs/` index), CONTRIBUTING (Conventional Commits), SECURITY (`Cache-Control` header), new `docs/deployment.md` and expanded `docs/architecture.md` / `docs/api.md` / `docs/setup.md`.
- `internal/proxy`: reuse one `http.Transport` per proxy instance; `Makefile` `test-cover-check` uses a safer flag order for shells.
- `.golangci.yml`: linter set aligned with the plan (with exclusions documented in `PLAN_PROGRESS.md`).
- `.golangci.yml`: linter set aligned with the documented local and CI validation policy.
- Project copy and operator-facing strings internationalised to English (`README`, `docs/`, errors, logs).

### Fixed
Expand Down
12 changes: 9 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
.PHONY: help fmt vet test test-short test-race test-cover test-cover-check install-hooks tidy build build-daemon build-tui build-logtail clean vulncheck sec lint all validate validate-full generate docker-build run
.PHONY: help fmt vet test test-short test-race test-cover test-cover-check install-hooks tidy build build-daemon build-proxy build-tui build-logtail clean vulncheck sec lint all validate validate-full generate docker-build run

GO ?= go

BIN_DIR := bin
DAEMON := $(BIN_DIR)/godeployd
TUI := $(BIN_DIR)/godeploy-tui
LOGTAIL := $(BIN_DIR)/godeploy-logtail
PROXY := $(BIN_DIR)/godeploy-proxy
COVERAGE_FILE := coverage.txt
# Minimum total statement coverage for `make test-cover-check` (see PLAN_PROGRESS.md, stage 4).
# Minimum total statement coverage for `make test-cover-check`.
COVER_MIN ?= 29
DOCKER_IMAGE ?= godeployd:local

Expand Down Expand Up @@ -65,13 +66,18 @@ validate: fmt vet lint test build
validate-full: fmt vet lint test-short test-cover-check build

## build: Build all binaries
build: build-daemon build-tui build-logtail
build: build-daemon build-proxy build-tui build-logtail

## build-daemon: Build godeployd
build-daemon:
@mkdir -p $(BIN_DIR)
$(GO) build -o $(DAEMON) ./cmd/godeployd

## build-proxy: Build the Host-based reverse proxy
build-proxy:
@mkdir -p $(BIN_DIR)
$(GO) build -o $(PROXY) ./cmd/godeploy-proxy

## build-tui: Build godeploy-tui
build-tui:
@mkdir -p $(BIN_DIR)
Expand Down
63 changes: 0 additions & 63 deletions PLAN_PROGRESS.md

This file was deleted.

66 changes: 21 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<p>Mini PaaS in Go: detects app type, builds a Docker image, and deploys with domain-based proxy routing and Git webhooks.</p>

<img src="assets/github-go.png" alt="gochangelog-gen Banner" width="600px">
<img src="assets/github-go.png" alt="godeploy-platform architecture banner" width="600px">

<br>

Expand All @@ -19,7 +19,9 @@

---

**godeploy-platform** is an HTTP daemon (`godeployd`) that receives push webhooks (GitHub or GitLab), clones the repository, detects the runtime (Go, Node, Python, static, or a supplied Dockerfile), generates or reuses a Dockerfile, builds via the Docker Engine API, runs a container with CPU/RAM limits, and updates routes in SQLite for an optional reverse proxy. It also includes a TUI for inspection and a WebSocket log client. The Go module is named `godeploy-platform` (repository root); the badges above assume the canonical repo `github.com/enoquesousa/godeploy-platform`.
**godeploy-platform** is an HTTP daemon (`godeployd`) that receives push webhooks (GitHub or GitLab), clones the repository, detects the runtime (Go, Node, Python, static, or a supplied Dockerfile), generates or reuses a Dockerfile, builds via the Docker Engine API, runs a container with CPU/RAM limits, and updates routes in SQLite for the bundled reverse proxy. It also includes a TUI for inspection and a WebSocket log client. The canonical Go module is `github.com/enoquesousa/godeploy-platform`.

> **Maturity:** active single-host prototype. The deployment pipeline, health-based route switch and rollback are implemented and tested, but the project is not yet a multi-tenant or highly available control plane. See [Known limitations](#known-limitations) before exposing it to untrusted networks.

## Demo (60-second smoke test)

Expand Down Expand Up @@ -103,14 +105,13 @@ go build -o bin/godeployd ./cmd/godeployd

### As a binary with `go install`

When the module is published under a `github.com/...` path aligned with `go.mod`, you can use:
Install the daemon, reverse proxy, TUI, or log client directly from the canonical module:

```bash
go install github.com/enoquesousa/godeploy-platform/cmd/godeployd@latest
go install github.com/enoquesousa/godeploy-platform/cmd/godeploy-proxy@latest
Comment on lines 111 to +112
```

While `go.mod` declares only `module godeploy-platform`, prefer `make build` from a clone.

### Docker Compose

```bash
Expand Down Expand Up @@ -342,45 +343,10 @@ err="new container \"broken-app-...\" did not reach running:

### Step 6 — reverse proxy by domain

`internal/proxy` is a library, not a binary. The quickest local test is a short wrapper sharing the same `GODEPLOY_DB` godeployd updated:
Start the bundled reverse proxy against the same SQLite database updated by `godeployd`:

```bash
mkdir -p cmd/godeploy-proxy-dev
cat > cmd/godeploy-proxy-dev/main.go <<'GO'
package main

import (
"context"
"database/sql"
"log"
"os"
"os/signal"
"syscall"
"time"

_ "modernc.org/sqlite"
"godeploy-platform/internal/proxy"
)

func main() {
db, err := sql.Open("sqlite", os.Getenv("GODEPLOY_DB"))
if err != nil {
log.Fatal(err)
}
defer db.Close()
p, err := proxy.New(proxy.Config{Addr: ":8090", DB: db, PollInterval: time.Second})
if err != nil {
log.Fatal(err)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
log.Println("proxy on :8090")
if err := p.Run(ctx); err != nil {
log.Fatal(err)
}
}
GO
GODEPLOY_DB=$(pwd)/godeploy.db go run ./cmd/godeploy-proxy-dev
GODEPLOY_DB=$(pwd)/godeploy.db GODEPLOY_PROXY_ADDR=:8090 ./bin/godeploy-proxy
```

In another terminal, hit it with the **Host header** (the proxy routes by domain):
Expand Down Expand Up @@ -426,7 +392,7 @@ Get-Process -Name godeployd -ErrorAction SilentlyContinue | Stop-Process -Force
| `test-cover` | Coverage and `coverage.html` |
| `test-cover-check` | `-short` plus coverage floor (`COVER_MIN`, default 29%) |
| `tidy` | `go mod tidy` |
| `build` | Build all three binaries into `bin/` |
| `build` | Build all four binaries into `bin/` |
| `build-daemon` | `godeployd` only |
| `build-tui` | `godeploy-tui` only |
| `build-logtail` | `godeploy-logtail` only |
Expand All @@ -445,6 +411,7 @@ Get-Process -Name godeployd -ErrorAction SilentlyContinue | Stop-Process -Force
## Architecture

- `cmd/godeployd` — HTTP server, `internal/pipeline` wiring, webhooks, observability.
- `cmd/godeploy-proxy` — runnable Host-based reverse proxy over the shared SQLite route table.
- `cmd/godeploy-tui` — terminal UI over Docker and SQLite.
- `cmd/godeploy-logtail` — WebSocket log client.
- `internal/pipeline` — orchestration: clone → build → deploy → health → route.
Expand Down Expand Up @@ -476,12 +443,21 @@ HTTP summary for `godeployd`:

Details and examples: [docs/api.md](docs/api.md). Package docs for `internal/` via `go doc` in a local clone (not a stable public API).

## Known limitations

- Single-host control plane backed by SQLite; no clustering or leader election.
- No tenant model, user authentication, authorization, quotas, or per-application secrets management.
- Docker socket access is highly privileged and must remain restricted to trusted operators.
- TLS termination and public DNS automation are intentionally delegated to external infrastructure.
- Rollback protects the route switch during deployment; disaster recovery and automated SQLite backups remain operator responsibilities.

## Configuration

| Variable | Type | Default | Description |
|----------|------|---------|-------------|
| `GODEPLOY_ADDR` | string | `:8081` | HTTP listen address |
| `GODEPLOY_DB` | path | `godeploy.db` | SQLite file |
| `GODEPLOY_PROXY_ADDR` | string | `:8080` | Host-based reverse proxy listen address |
| `GODEPLOY_NETWORK` | string | `godeploy` | Docker bridge network for apps |
| `GODEPLOY_IMAGE_PREFIX` | string | `godeploy` | Image name prefix |
| `GODEPLOY_HEALTH_PATH` | string | `/` | HTTP health-check path in the pipeline |
Expand Down Expand Up @@ -534,12 +510,12 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) and [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.

[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=flat&logo=linkedin&logoColor=white)](https://www.linkedin.com/in/enoque-sousa-bb89aa168/)
[![GitHub](https://img.shields.io/badge/GitHub-100000?style=flat&logo=github&logoColor=white)](https://github.com/enoquesousa)
[![Portfolio](https://img.shields.io/badge/Portfolio-FF5722?style=flat&logo=target&logoColor=white)](https://enoquesousa.vercel.app)
[![Portfolio](https://img.shields.io/badge/Portfolio-FF5722?style=flat&logo=target&logoColor=white)](https://enoquesousa.com/en)

**[⬆ Back to Top](#godeploy-platform)**

Made with ❤️ by [Enoque Sousa](https://github.com/enoquesousa)

**Project Status:** Study project
**Project Status:** Active single-host prototype

</div>
4 changes: 3 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Do not post working exploits or production credentials in public issues.

- **First acknowledgement**: best effort within **7 days** of a valid report via GitHub Security Advisories.
- **Status updates**: when a fix is planned or released, or if the report is declined as out of scope.
- This is a **study / side project**; timelines depend on maintainer availability and are not a commercial SLA.
- This is an **independently maintained prototype**; timelines depend on maintainer availability and are not a commercial SLA.

## Supported versions

Expand All @@ -25,6 +25,8 @@ The Go client `github.com/docker/docker` is kept on the **latest version compati

This repository uses the package **only as an HTTP client** for the Docker Engine API (images, containers, networks). Vectors described in those advisories target **daemon** components (AuthZ, plugins), not the `godeployd` binary. Still, run `govulncheck ./...` on each release and keep Docker Engine updated on the host.

GitHub Dependabot also reports Docker archive/`docker cp` advisories against the module manifest. This project does not call `CopyToContainer`, `CopyFromContainer`, `ContainerArchive`, or the `/containers/{id}/archive` endpoints. No patched module version is currently published; the alerts remain open for tracking and must be reassessed when Docker publishes one.

Mitigations in `godeployd` and related services:

- `/webhook`: **body limit** (`http.MaxBytesReader`), **rate limit** per IP (`GODEPLOY_WEBHOOK_RPS` / `GODEPLOY_WEBHOOK_BURST`), **no internal detail leakage** on 500 responses.
Expand Down
2 changes: 1 addition & 1 deletion cmd/godeploy-logtail/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

"github.com/gorilla/websocket"

"godeploy-platform/internal/platform/iox"
"github.com/enoquesousa/godeploy-platform/internal/platform/iox"
)

func main() {
Expand Down
Loading
Loading