No description
  • TypeScript 44.6%
  • Go 31.4%
  • CSS 22.8%
  • Dockerfile 0.8%
  • HTML 0.4%
Find a file
Xantios Krugor 032cf04da6
All checks were successful
Build and Deploy Shipyard / build (push) Successful in 1m1s
Build and Deploy Shipyard / deploy (push) Successful in 1s
Remove variable and watchtower (which is deprecated)
2026-06-06 21:23:07 +02:00
.forgejo/workflows More Ci/Cd fixes 2026-06-06 21:15:29 +02:00
backend first commit 2026-06-06 21:11:10 +02:00
frontend first commit 2026-06-06 21:11:10 +02:00
.env.example first commit 2026-06-06 21:11:10 +02:00
.gitignore first commit 2026-06-06 21:11:10 +02:00
docker-compose.dev.yml first commit 2026-06-06 21:11:10 +02:00
docker-compose.prod.yml Remove variable and watchtower (which is deprecated) 2026-06-06 21:23:07 +02:00
logo.png first commit 2026-06-06 21:11:10 +02:00
README.md first commit 2026-06-06 21:11:10 +02:00

Shipyard

An open-source Trello alternative. Kanban boards with draggable cards, custom photo backgrounds, and JWT authentication.

Stack: Go · React · PostgreSQL · Docker


Features

  • Kanban boards with draggable cards (across columns)
  • Create, rename, and delete columns and cards
  • Card descriptions
  • Per-board photo backgrounds (Unsplash search)
  • Multiple boards per account
  • JWT authentication

Quick start

Prerequisites

1. Clone and configure

git clone <repo-url>
cd Shipyard

Open docker-compose.yml and set a strong JWT secret:

JWT_SECRET: "replace-this-with-a-long-random-string"

Generate a good one with:

openssl rand -hex 32

2. Start the stack

docker compose up --build

This starts:

Service URL
Frontend http://localhost:3000
Backend API http://localhost:8080/api
PostgreSQL localhost:5432

3. Create the first user

In a second terminal, while the stack is running:

docker compose exec backend ./createuser -email admin@example.com -password yourpassword

You can run this again at any time to change a user's password or add more users.

4. Sign in

Open http://localhost:3000 and sign in with the credentials you just created.


Photo backgrounds (Unsplash)

To enable the board background search, get a free API key from unsplash.com/developers (requires registration, takes ~2 minutes).

Set it in docker-compose.yml:

UNSPLASH_ACCESS_KEY: "your-key-here"

Then rebuild: docker compose up --build

The free tier allows 50 requests/hour, which is plenty for personal use.


Development without Docker

Backend

cd backend
go mod tidy
DATABASE_URL="postgres://kaartjes:kaartjes@localhost:5432/kaartjes?sslmode=disable" \
JWT_SECRET="dev-secret" \
go run .

Frontend

cd frontend
npm install
npm run dev     # http://localhost:5173 — proxies /api to localhost:8080

Configuration

All configuration is via environment variables.

Variable Required Default Description
DATABASE_URL No postgres://kaartjes:kaartjes@localhost:5432/kaartjes?sslmode=disable PostgreSQL connection string
JWT_SECRET Yes Secret for signing JWT tokens. Must be set or the server refuses to start.
PORT No 8080 HTTP port for the backend
UNSPLASH_ACCESS_KEY No Enables photo background search

API reference

All endpoints except /api/auth/login require an Authorization: Bearer <token> header.

Auth

Method Path Body Description
POST /api/auth/login {email, password} Returns {token, user}

Boards

Method Path Description
GET /api/boards List all boards
POST /api/boards Create board — body: {title}
GET /api/boards/:id Get board with columns and cards
PUT /api/boards/:id/background Set background — body: {background_url}

Columns

Method Path Description
POST /api/boards/:id/columns Create column — body: {title}
PUT /api/columns/:id Rename — body: {title}
DELETE /api/columns/:id Delete column and all its cards

Cards

Method Path Description
POST /api/columns/:id/cards Create card — body: {title}
PUT /api/cards/:id Update — body: {title, description}
DELETE /api/cards/:id Delete card
PUT /api/cards/:id/move Move — body: {column_id, position}

Images

Method Path Description
GET /api/images/search?q=... Search Unsplash photos

Data

PostgreSQL data is stored in a Docker volume (pgdata) and persists across restarts. To reset everything:

docker compose down -v   # -v removes the volume
docker compose up --build