Skip to content

Commit e76b346

Browse files
✨(infra) Enhanced Docker configuration, added a Makefile, README updated
1 parent d515c63 commit e76b346

File tree

20 files changed

+1236
-565
lines changed

20 files changed

+1236
-565
lines changed

Makefile

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
.PHONY: help setup up down restart logs keycloak-wait init-db clean
2+
3+
# Default values
4+
COMPOSE_FILE := docker-compose-dev.yml
5+
KEYCLOAK_URL := http://localhost:8080
6+
INITIAL_USER_EMAIL ?= user.test@anct.gouv.fr
7+
INITIAL_USER_PASSWORD ?= password
8+
INITIAL_USER_USERNAME ?= test.user
9+
INITIAL_USER_FIRST_NAME ?= Test
10+
INITIAL_USER_LAST_NAME ?= User
11+
12+
help: ## Show this help message
13+
@echo "Available targets:"
14+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
15+
16+
bootstrap: ## Complete setup: start services and initialize database
17+
@echo "🚀 Starting complete setup..."
18+
@$(MAKE) up
19+
@echo "⏳ Waiting for services to be ready..."
20+
@sleep 10
21+
@$(MAKE) keycloak-wait
22+
@$(MAKE) init-db
23+
@echo "✅ Setup complete! Application is ready at http://localhost:3000"
24+
@echo " Keycloak Admin Console: http://localhost:8080 (admin/admin)"
25+
@echo " Keycloak realm is auto-imported from realm-export.json"
26+
27+
up: ## Start all Docker services
28+
@echo "🐳 Starting Docker services..."
29+
docker-compose -f $(COMPOSE_FILE) up -d
30+
@echo "✅ Services started. Use 'make logs' to view logs."
31+
32+
down: ## Stop all Docker services
33+
@echo "🛑 Stopping Docker services..."
34+
docker-compose -f $(COMPOSE_FILE) down
35+
@echo "✅ Services stopped."
36+
37+
restart: ## Restart all Docker services
38+
@echo "🔄 Restarting Docker services..."
39+
$(MAKE) down
40+
$(MAKE) up
41+
42+
logs: ## Show logs from all services
43+
docker-compose -f $(COMPOSE_FILE) logs -f
44+
45+
logs-server: ## Show logs from server only
46+
docker-compose -f $(COMPOSE_FILE) logs -f server
47+
48+
logs-keycloak: ## Show logs from Keycloak only
49+
docker-compose -f $(COMPOSE_FILE) logs -f keycloak
50+
51+
keycloak-wait: ## Wait for Keycloak to be ready
52+
@echo "⏳ Waiting for Keycloak to be ready..."
53+
@timeout=60; \
54+
while [ $$timeout -gt 0 ]; do \
55+
if curl -s -f $(KEYCLOAK_URL)/realms/master/.well-known/openid-configuration > /dev/null 2>&1; then \
56+
echo "✅ Keycloak is ready!"; \
57+
break; \
58+
fi; \
59+
echo " Waiting... ($$timeout seconds remaining)"; \
60+
sleep 2; \
61+
timeout=$$((timeout - 2)); \
62+
done; \
63+
if [ $$timeout -le 0 ]; then \
64+
echo "❌ Timeout waiting for Keycloak"; \
65+
exit 1; \
66+
fi
67+
68+
init-db: ## Initialize the database (migrations and seeds)
69+
@echo "🗄️ Initializing database..."
70+
@echo " Waiting for postgres to be ready..."
71+
@timeout=60; \
72+
while [ $$timeout -gt 0 ]; do \
73+
if docker-compose -f $(COMPOSE_FILE) exec -T postgres pg_isready -U user -d projets > /dev/null 2>&1; then \
74+
break; \
75+
fi; \
76+
sleep 2; \
77+
timeout=$$((timeout - 2)); \
78+
done
79+
@echo " Running database migrations and seeds..."
80+
docker-compose -f $(COMPOSE_FILE) run --rm \
81+
-e DATABASE_URL=postgresql://user:password@postgres:5432/projets \
82+
-e DEFAULT_ADMIN_EMAIL=$(INITIAL_USER_EMAIL) \
83+
-e DEFAULT_ADMIN_PASSWORD=$(INITIAL_USER_PASSWORD) \
84+
-e DEFAULT_ADMIN_NAME="$(INITIAL_USER_FIRST_NAME) $(INITIAL_USER_LAST_NAME)" \
85+
-e DEFAULT_ADMIN_USERNAME=$(INITIAL_USER_USERNAME) \
86+
server npm run db:init
87+
@echo "✅ Database initialized successfully!"
88+
89+
clean: ## Stop services and remove volumes (WARNING: deletes all data)
90+
@echo "⚠️ WARNING: This will delete all data including databases!"
91+
@read -p "Are you sure? [y/N] " -n 1 -r; \
92+
echo; \
93+
if [[ $$REPLY =~ ^[Yy]$$ ]]; then \
94+
docker-compose -f $(COMPOSE_FILE) down -v; \
95+
echo "✅ Cleanup complete. All volumes removed."; \
96+
else \
97+
echo "❌ Cleanup cancelled."; \
98+
fi
99+
100+
ps: ## Show status of all services
101+
docker-compose -f $(COMPOSE_FILE) ps
102+
103+
shell-server: ## Open a shell in the server container
104+
docker-compose -f $(COMPOSE_FILE) exec server sh
105+
106+
shell-keycloak: ## Open a shell in the Keycloak container
107+
docker-compose -f $(COMPOSE_FILE) exec keycloak /bin/bash
108+
109+
shell-postgres: ## Open a psql shell in the postgres container
110+
docker-compose -f $(COMPOSE_FILE) exec postgres psql -U user -d projets

README.md

Lines changed: 134 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,157 @@
1-
# Planka
2-
#### Elegant open source project tracking.
1+
# Projets
32

4-
![David (path)](https://img.shields.io/github/package-json/v/plankanban/planka) ![Docker Pulls](https://img.shields.io/badge/docker_pulls-5M%2B-%23066da5) ![GitHub](https://img.shields.io/github/license/plankanban/planka)
3+
Projets is the project management tool for [La Suite territoriale](https://suiteterritoriale.anct.gouv.fr/).
54

6-
![](https://raw.githubusercontent.com/plankanban/planka/master/demo.gif)
5+
Built on [Planka](https://github.com/plankanban/planka), it provides a customized Kanban-style interface designed specifically for teams managing territorial and digital transformation projects.
76

8-
[**Client demo**](https://plankanban.github.io/planka) (without server features).
7+
![Node](https://img.shields.io/badge/node-22-green)
8+
![License]()
99

10-
## Features
10+
[![Deploy to Scalingo](https://cdn.scalingo.com/deploy/button.svg)](https://my.scalingo.com/deploy?source=https://github.com/suitenumerique/st-projects)
1111

12-
- Create projects, boards, lists, cards, labels and tasks
13-
- Add card members, track time, set due dates, add attachments, write comments
14-
- Markdown support in card description and comments
15-
- Filter by members and labels
16-
- Customize project backgrounds
17-
- Real-time updates
18-
- Internal notifications
19-
- Multiple interface languages
20-
- Single sign-on via OpenID Connect
12+
## 🎯 Features
2113

22-
## How to deploy Planka
14+
- **Project Management**: Create projects, boards, lists, cards, labels, and tasks
15+
- **Collaboration**: Add card members, track time, set due dates, add attachments, write comments
16+
- **Rich Content**: Markdown support in card descriptions and comments
17+
- **Filtering**: Filter by members and labels
18+
- **Real-time Updates**: Live synchronization across all clients
19+
- **Notifications**: Internal notification system
20+
- **Internationalization**: Multiple interface languages (French, English)
21+
- **Single Sign-On**: OpenID Connect (OIDC) authentication via Keycloak
22+
- **Modern UI**: Built with React and modern design components
2323

24-
There are many ways to install Planka, [check them out](https://docs.planka.cloud/docs/intro).
24+
## 🏗️ Architecture
2525

26-
For configuration, please see the [configuration section](https://docs.planka.cloud/docs/category/configuration).
26+
Projets is a full-stack application with the following components:
2727

28-
## Mobile app
28+
### Frontend (`client/`)
2929

30-
Here is the [mobile app repository](https://github.com/LouisHDev/planka_app) maintained by the community, where you can build an app for iOS and Android.
30+
- **Framework**: React 19 with Redux for state management
31+
- **UI Libraries**:
32+
- @gouvfr-lasuite/ui-kit
33+
- @openfun/cunningham-react
34+
- **Key Features**:
35+
- Redux-Saga for side effects
36+
- Redux-ORM for data modeling
37+
- React Router for navigation
38+
- Socket.io client for real-time updates
39+
- i18next for internationalization
3140

32-
Alternatively, you can download the [Android APK](https://github.com/LouisHDev/planka_app/releases/latest/download/app-release.apk) directly.
41+
### Backend (`server/`)
3342

34-
If you have an iOS device and would like to test the app, you can join [TestFlight](https://testflight.apple.com/join/Uwn41eY4) (limited to 200 participants).
43+
- **Framework**: Sails.js (Node.js MVC framework)
44+
- **Database**: PostgreSQL with Knex.js query builder
45+
- **Authentication**: OpenID Connect (OIDC) via Keycloak
46+
- **Real-time**: Socket.io for WebSocket connections
47+
- **File Storage**: AWS S3 compatible storage for attachments
3548

36-
## Contact
49+
### Infrastructure
3750

38-
- If you want to get a hosted version of Planka, you can contact us via email contact@planka.cloud
39-
- For any security issues, please do not create a public issue on GitHub, instead please write to security@planka.cloud
51+
- **Database**: PostgreSQL 16
52+
- **Authentication Server**: Keycloak (OIDC provider)
53+
- **Reverse Proxy**: Nginx
54+
- **Containerization**: Docker & Docker Compose
4055

41-
We do NOT offer any public support via email, please use GitHub.
56+
## 📋 Prerequisites
4257

43-
## Development
58+
Before you begin, ensure you have the following installed:
4459

45-
See the [development section](https://docs.planka.cloud/docs/Development).
60+
- **Docker** (version 20.10 or later)
61+
- **Docker Compose** (version 2.0 or later)
62+
- **Node.js** 22 (for local development without Docker)
63+
- **npm** or **yarn** (for local development)
4664

47-
## Tech stack
65+
## 🚀 Quick Start
4866

49-
- React, Redux, Redux-Saga, Redux-ORM, Semantic UI React, react-beautiful-dnd
50-
- Sails.js, Knex.js
51-
- PostgreSQL
67+
### Using Docker (Recommended)
5268

53-
## License
69+
The easiest way to get started is using the provided Makefile:
5470

55-
Planka is [AGPL-3.0 licensed](https://github.com/plankanban/planka/blob/master/LICENSE).
71+
```bash
72+
make bootstrap
73+
```
5674

57-
## Contributors
75+
This will:
5876

59-
[![](https://contrib.rocks/image?repo=plankanban/planka)](https://github.com/plankanban/planka/graphs/contributors)
77+
1. Start all Docker services (PostgreSQL, Keycloak, Server, Client, Nginx)
78+
2. Wait for services to be ready
79+
3. Initialize the database with migrations and seeds
80+
4. Create a default admin user
81+
82+
After setup completes, access the application at:
83+
84+
- **Application**: http://localhost:3000
85+
- **Keycloak Admin Console**: http://localhost:8080 (admin/admin)
86+
87+
### Manual Docker Setup
88+
89+
If you prefer to use Docker Compose directly:
90+
91+
```bash
92+
# Start all services
93+
docker-compose -f docker-compose-dev.yml up -d
94+
95+
# Wait for services to be ready, then initialize database
96+
make keycloak-wait
97+
make init-db
98+
```
99+
100+
### Local Development (Without Docker)
101+
102+
For local development without Docker:
103+
104+
```bash
105+
# Install dependencies
106+
npm install
107+
108+
# Set up environment variables
109+
cp server/.env.sample server/.env
110+
# Edit server/.env with your configuration
111+
112+
# Initialize database
113+
npm run server:db:init
114+
115+
# Start development servers
116+
npm start
117+
```
118+
119+
This will start both the server (port 3000) and client (port 3001) concurrently.
120+
121+
## 🐳 Docker Services
122+
123+
The development environment includes:
124+
125+
- **postgres**: PostgreSQL 16 database (port 5433)
126+
- **keycloak-db**: PostgreSQL database for Keycloak
127+
- **keycloak**: Keycloak authentication server (port 8080)
128+
- **server**: Sails.js backend server
129+
- **client**: React development server
130+
- **proxy**: Nginx reverse proxy (port 3000)
131+
- **init-db**: One-time database initialization service
132+
133+
## 📚 Additional Resources
134+
135+
- [Planka Documentation](https://docs.planka.cloud/)
136+
- [Sails.js Documentation](https://sailsjs.com/documentation)
137+
- [React Documentation](https://react.dev/)
138+
- [Keycloak Documentation](https://www.keycloak.org/documentation)
139+
140+
## License 📝
141+
142+
This work is released under the MIT License (see [LICENSE](https://github.com/suitenumerique/messages/blob/main/LICENSE)).
143+
144+
While Projets is a public-driven initiative, our license choice is an invitation for private sector actors to use, sell and contribute to the project.
145+
146+
## 📧 Contact
147+
148+
For questions or issues:
149+
150+
- **GitHub Issues**: Use the repository's issue tracker
151+
- **Security Issues**: Please report security vulnerabilities privately
152+
153+
## Gov ❤️ open source
154+
155+
Projets is currently led by the French [ANCT](https://anct.gouv.fr/) for use in [La Suite territoriale](https://suiteterritoriale.anct.gouv.fr/).
156+
157+
We are welcoming new partners and contributors to join us in this effort! So please [get in touch](mailto:contact@suite.anct.gouv.fr) if you want to help!

client/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
]
2626
},
2727
"eslintConfig": {
28+
"root": true,
2829
"env": {
2930
"browser": true,
3031
"jest": true
@@ -59,7 +60,10 @@
5960
"prettier/prettier": [
6061
"error",
6162
{
62-
"endOfLine": "auto"
63+
"endOfLine": "auto",
64+
"singleQuote": true,
65+
"printWidth": 100,
66+
"trailingComma": "all"
6367
}
6468
]
6569
}

client/src/steps/BoardCreateStep/BoardCreateStep.jsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,22 @@ const BoardCreateStep = React.memo(
114114
{data.import ? data.import.file.name : t('action.import')}
115115
</Button> */}
116116
</div>
117-
<div className={styles.templatesWrapper}>
118-
<p>Ou choisissez un tableau pré-défini :</p>
119-
<div className={styles.templatesList}>
120-
{(templateBoards || []).map((board) => (
121-
<BoardListItem
122-
key={board.id}
123-
board={board}
124-
handleClick={() => handleTemplateClick(board.id)}
125-
showDescription
126-
editable={false}
127-
/>
128-
))}
117+
{templateBoards && templateBoards.length > 0 && (
118+
<div className={styles.templatesWrapper}>
119+
<p>Ou choisissez un tableau pré-défini :</p>
120+
<div className={styles.templatesList}>
121+
{(templateBoards || []).map((board) => (
122+
<BoardListItem
123+
key={board.id}
124+
board={board}
125+
handleClick={() => handleTemplateClick(board.id)}
126+
showDescription
127+
editable={false}
128+
/>
129+
))}
130+
</div>
129131
</div>
130-
</div>
132+
)}
131133
</form>
132134
</>
133135
);
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1-
FROM node:18-alpine AS server-dependencies
1+
FROM node:22-alpine
22

33
RUN apk -U upgrade \
44
&& apk add build-base python3 --no-cache
55

6+
# Install pnpm globally (faster than npm install pnpm)
7+
RUN npm install -g pnpm@9
8+
69
WORKDIR /app/client
710

8-
COPY package.json package-lock.json .
11+
# Copy package files first for better Docker layer caching
12+
COPY package.json package-lock.json ./
913

10-
RUN npm install npm --global \
11-
&& npm install pnpm@9 --global \
12-
&& pnpm import \
13-
&& pnpm install
14+
# Install client dependencies
15+
RUN pnpm import && pnpm install --frozen-lockfile
1416

1517
WORKDIR /app
1618

17-
COPY ../../package.json ../../package-lock.json .
19+
# Copy root package files and install root dependencies
20+
COPY package.json package-lock.json ./
1821

19-
RUN pnpm import \
20-
&& pnpm install
22+
RUN pnpm import && pnpm install --frozen-lockfile

config/development/Dockerfile.server

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:18-alpine AS server-dependencies
1+
FROM node:22-alpine
22

33
RUN apk -U upgrade \
44
&& apk add build-base python3 --no-cache

0 commit comments

Comments
 (0)