- TypeScript 44.6%
- Go 31.4%
- CSS 22.8%
- Dockerfile 0.8%
- HTML 0.4%
| .forgejo/workflows | ||
| backend | ||
| frontend | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.dev.yml | ||
| docker-compose.prod.yml | ||
| logo.png | ||
| README.md | ||
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
- Docker and Docker Compose
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