Skip to content

Commit c088f4e

Browse files
author
wanoo
committed
docs: Add Clever Cloud installation guide
Add comprehensive documentation for deploying AdventureLog on Clever Cloud: - Step-by-step setup for Python backend and Node.js frontend - PostgreSQL and FS Bucket add-on configuration - Custom domain setup (required for session cookies) - Email configuration with Mailpace - Environment variable mapping from add-ons
1 parent c008f0c commit c088f4e

File tree

2 files changed

+385
-0
lines changed

2 files changed

+385
-0
lines changed

documentation/.vitepress/config.mts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ export default defineConfig({
138138
link: "/docs/install/kustomize",
139139
},
140140
{ text: "Unraid 🧡", link: "/docs/install/unraid" },
141+
{ text: "Clever Cloud ☁️", link: "/docs/install/clever_cloud" },
141142
{
142143
text: "Dev Container + WSL 🧰",
143144
link: "/docs/install/dev_container_wsl",
Lines changed: 384 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,384 @@
1+
# Clever Cloud
2+
3+
Clever Cloud is a European PaaS (Platform as a Service) that allows you to deploy applications without managing servers. This guide walks you through deploying AdventureLog on Clever Cloud **without modifying the source code**.
4+
5+
## Prerequisites
6+
7+
- A [Clever Cloud](https://www.clever-cloud.com/) account
8+
- [Clever Cloud CLI](https://www.clever-cloud.com/doc/cli/) installed
9+
- Git installed
10+
- **A custom domain** (required - see note below)
11+
12+
Custom Domain Required
13+
14+
The default `*.cleverapps.io` domains **will not work**. The `cleverapps.io` domain is on the [Public Suffix List](https://publicsuffix.org/), which prevents session cookies from being shared between applications.
15+
16+
You must use a custom domain where both apps share a parent domain:
17+
- `adventurelog.your-domain.com` (frontend)
18+
- `api.adventurelog.your-domain.com` (backend)
19+
20+
## Architecture
21+
22+
| Component | Size | Description |
23+
|-----------|------|-------------|
24+
| Frontend | XS (runtime) / M (build) | SvelteKit application |
25+
| Backend | XS | Django REST API |
26+
| PostgreSQL | S | Database |
27+
| FS Bucket | - | Media storage (persistent) |
28+
| Mailpace | - | Transactional emails (optional) |
29+
30+
## Step 1: Clone the Repository
31+
32+
```bash
33+
git clone https://github.com/seanmorley15/AdventureLog.git
34+
cd AdventureLog
35+
```
36+
37+
## Step 2: Create the Applications
38+
39+
```bash
40+
# Python backend
41+
clever create --type python adventurelog-backend
42+
43+
# Node.js frontend
44+
clever create --type node adventurelog-frontend
45+
46+
# Link applications
47+
clever link adventurelog-backend --alias adventurelog-backend
48+
clever link adventurelog-frontend --alias adventurelog-frontend
49+
```
50+
51+
## Step 3: Create Add-ons
52+
53+
```bash
54+
# PostgreSQL
55+
clever addon create postgresql-addon adventurelog-postgres --plan s_sml --link adventurelog-backend
56+
57+
# FS Bucket for media files
58+
clever addon create fs-bucket adventurelog-media --link adventurelog-backend
59+
60+
# Mailpace for emails (optional)
61+
clever addon create mailpace adventurelog-email --link adventurelog-backend
62+
```
63+
64+
## Step 4: Configure Custom Domains
65+
66+
```bash
67+
# Replace with your domain
68+
clever domain add adventurelog.your-domain.com --alias adventurelog-frontend
69+
clever domain add api.adventurelog.your-domain.com --alias adventurelog-backend
70+
```
71+
72+
Configure CNAME DNS records with your domain registrar.
73+
74+
## Step 5: Configure Instance Sizes
75+
76+
```bash
77+
# Frontend: build on M, runtime on XS
78+
clever scale --alias adventurelog-frontend --flavor XS --build-flavor M
79+
80+
# Backend: XS is sufficient
81+
clever scale --alias adventurelog-backend --flavor XS
82+
```
83+
84+
## Step 6: Backend Environment Variables
85+
86+
### Clever Cloud Configuration
87+
88+
```bash
89+
clever env set --alias adventurelog-backend APP_FOLDER "backend/server"
90+
clever env set --alias adventurelog-backend CC_PYTHON_VERSION "3"
91+
clever env set --alias adventurelog-backend CC_PYTHON_MODULE "main.wsgi:application"
92+
clever env set --alias adventurelog-backend CC_PRE_RUN_HOOK "memcached -u nobody -m 64 -p 11211 -d"
93+
clever env set --alias adventurelog-backend CC_PYTHON_MANAGE_TASKS "collectstatic --noinput, migrate --noinput, download-countries --force"
94+
```
95+
96+
### Django Configuration
97+
98+
```bash
99+
clever env set --alias adventurelog-backend SECRET_KEY "$(openssl rand -base64 32)"
100+
clever env set --alias adventurelog-backend DEBUG "False"
101+
clever env set --alias adventurelog-backend DISABLE_REGISTRATION "False"
102+
103+
# URLs (replace your-domain.com with your domain)
104+
clever env set --alias adventurelog-backend PUBLIC_URL "https://api.your-domain.com"
105+
clever env set --alias adventurelog-backend FRONTEND_URL "https://your-domain.com"
106+
clever env set --alias adventurelog-backend CSRF_TRUSTED_ORIGINS "https://your-domain.com,https://api.your-domain.com"
107+
```
108+
109+
### Automatic Add-on Variable Mapping
110+
111+
These commands automatically retrieve values injected by Clever Cloud add-ons:
112+
113+
```bash
114+
# === PostgreSQL: map addon variables to PG* ===
115+
clever env set --alias adventurelog-backend PGHOST "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="POSTGRESQL_ADDON_HOST") | .value')"
116+
clever env set --alias adventurelog-backend PGDATABASE "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="POSTGRESQL_ADDON_DB") | .value')"
117+
clever env set --alias adventurelog-backend PGUSER "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="POSTGRESQL_ADDON_USER") | .value')"
118+
clever env set --alias adventurelog-backend PGPASSWORD "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="POSTGRESQL_ADDON_PASSWORD") | .value')"
119+
clever env set --alias adventurelog-backend PGPORT "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="POSTGRESQL_ADDON_PORT") | .value')"
120+
121+
# === FS Bucket: build CC_FS_BUCKET with BUCKET_HOST ===
122+
clever env set --alias adventurelog-backend CC_FS_BUCKET "backend/server/media:$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="BUCKET_HOST") | .value')"
123+
124+
# === Nginx serves media files directly ===
125+
clever env set --alias adventurelog-backend STATIC_FILES_PATH "backend/server/media"
126+
clever env set --alias adventurelog-backend STATIC_URL_PREFIX "/media"
127+
```
128+
129+
## Step 7: Frontend Environment Variables
130+
131+
```bash
132+
clever env set --alias adventurelog-frontend APP_FOLDER "frontend"
133+
clever env set --alias adventurelog-frontend CC_NODE_BUILD_TOOL "pnpm"
134+
clever env set --alias adventurelog-frontend CC_NODE_DEV_DEPENDENCIES "install"
135+
clever env set --alias adventurelog-frontend CC_POST_BUILD_HOOK "cd frontend && pnpm run build"
136+
clever env set --alias adventurelog-frontend CC_RUN_COMMAND "cd frontend && node build"
137+
138+
# Configuration (replace with your custom domain)
139+
clever env set --alias adventurelog-frontend ORIGIN "https://adventurelog.your-domain.com"
140+
clever env set --alias adventurelog-frontend PUBLIC_SERVER_URL "https://api.adventurelog.your-domain.com"
141+
clever env set --alias adventurelog-frontend BODY_SIZE_LIMIT "Infinity"
142+
```
143+
144+
## Step 8: Email Configuration (Optional)
145+
146+
If you created the Mailpace add-on:
147+
148+
```bash
149+
clever env set --alias adventurelog-backend EMAIL_BACKEND "email"
150+
clever env set --alias adventurelog-backend EMAIL_HOST "smtp.mailpace.com"
151+
clever env set --alias adventurelog-backend EMAIL_PORT "587"
152+
clever env set --alias adventurelog-backend EMAIL_USE_TLS "True"
153+
clever env set --alias adventurelog-backend EMAIL_USE_SSL "False"
154+
155+
# Automatically map Mailpace token
156+
clever env set --alias adventurelog-backend EMAIL_HOST_USER "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="MAILPACE_API_TOKEN") | .value')"
157+
clever env set --alias adventurelog-backend EMAIL_HOST_PASSWORD "$(clever env --alias adventurelog-backend --format json | jq -r '.env[] | select(.name=="MAILPACE_API_TOKEN") | .value')"
158+
159+
# Replace with your verified domain in Mailpace
160+
clever env set --alias adventurelog-backend DEFAULT_FROM_EMAIL "noreply@your-verified-domain.com"
161+
```
162+
163+
## Step 9: Deploy
164+
165+
```bash
166+
# Backend first
167+
clever deploy --alias adventurelog-backend
168+
169+
# Then frontend
170+
clever deploy --alias adventurelog-frontend
171+
```
172+
173+
## Step 10: Create Superuser
174+
175+
After the first deployment, manually create the admin account:
176+
177+
```bash
178+
clever ssh --alias adventurelog-backend
179+
cd backend/server
180+
python manage.py createsuperuser
181+
```
182+
183+
## Verification
184+
185+
```bash
186+
clever status --alias adventurelog-backend
187+
clever status --alias adventurelog-frontend
188+
```
189+
190+
## Accessing the Application
191+
192+
| URL | Description |
193+
|-----|-------------|
194+
| `https://adventurelog.your-domain.com` | Main application |
195+
| `https://api.adventurelog.your-domain.com/admin` | Django admin panel |
196+
197+
## Updating
198+
199+
To update AdventureLog:
200+
201+
```bash
202+
git pull origin main
203+
clever deploy --alias adventurelog-backend
204+
clever deploy --alias adventurelog-frontend
205+
```
206+
207+
No Git Conflicts
208+
209+
This configuration does not modify the AdventureLog source code. You can update without conflicts.
210+
211+
## Quick Reference - Environment Variables
212+
213+
Two Methods Available
214+
- **CLI (recommended)**: Use the `jq` commands from steps 6-8 to automatically map add-on variables.
215+
- **Web Interface**: Copy the blocks below and manually replace `REPLACE_*` values in the Clever Cloud console.
216+
217+
### Backend (Python)
218+
219+
```bash
220+
# ============================================
221+
# CLEVER CLOUD CONFIGURATION
222+
# ============================================
223+
224+
# Django application folder
225+
APP_FOLDER="backend/server"
226+
227+
# Python version
228+
CC_PYTHON_VERSION="3"
229+
230+
# Django WSGI module
231+
CC_PYTHON_MODULE="main.wsgi:application"
232+
233+
# Start memcached before the app (required by AdventureLog)
234+
CC_PRE_RUN_HOOK="memcached -u nobody -m 64 -p 11211 -d"
235+
236+
# Django commands executed on deployment
237+
CC_PYTHON_MANAGE_TASKS="collectstatic --noinput, migrate --noinput, download-countries"
238+
239+
# ============================================
240+
# MEDIA STORAGE (FS BUCKET)
241+
# ============================================
242+
243+
# Bucket mount for media files
244+
# REPLACE: bucket-xxxxx with your BUCKET_HOST (clever env | grep BUCKET_HOST)
245+
CC_FS_BUCKET="backend/server/media:REPLACE_BUCKET_HOST"
246+
247+
# Nginx serves media files directly (bypasses Django)
248+
STATIC_FILES_PATH="backend/server/media"
249+
STATIC_URL_PREFIX="/media"
250+
251+
# ============================================
252+
# POSTGRESQL DATABASE
253+
# ============================================
254+
255+
# REPLACE: with your PostgreSQL add-on values
256+
# (clever env | grep POSTGRESQL)
257+
PGHOST="REPLACE_HOST"
258+
PGDATABASE="REPLACE_DATABASE"
259+
PGUSER="REPLACE_USER"
260+
PGPASSWORD="REPLACE_PASSWORD"
261+
PGPORT="REPLACE_PORT"
262+
263+
# ============================================
264+
# DJANGO CONFIGURATION
265+
# ============================================
266+
267+
# Django secret key (generate with: openssl rand -base64 32)
268+
SECRET_KEY="REPLACE_GENERATE_SECRET_KEY"
269+
270+
# Debug mode disabled in production
271+
DEBUG="False"
272+
273+
# Allow registrations
274+
DISABLE_REGISTRATION="False"
275+
276+
# ============================================
277+
# URLs (REPLACE WITH YOUR DOMAIN)
278+
# ============================================
279+
280+
# Backend public URL
281+
PUBLIC_URL="https://api.REPLACE_DOMAIN.com"
282+
283+
# Frontend URL
284+
FRONTEND_URL="https://REPLACE_DOMAIN.com"
285+
286+
# Allowed CSRF origins
287+
CSRF_TRUSTED_ORIGINS="https://REPLACE_DOMAIN.com,https://api.REPLACE_DOMAIN.com"
288+
289+
# ============================================
290+
# EMAIL (OPTIONAL - Mailpace)
291+
# ============================================
292+
293+
# Uncomment and configure if using Mailpace
294+
# EMAIL_BACKEND="email"
295+
# EMAIL_HOST="smtp.mailpace.com"
296+
# EMAIL_PORT="587"
297+
# EMAIL_USE_TLS="True"
298+
# EMAIL_USE_SSL="False"
299+
# EMAIL_HOST_USER="REPLACE_MAILPACE_API_TOKEN"
300+
# EMAIL_HOST_PASSWORD="REPLACE_MAILPACE_API_TOKEN"
301+
# DEFAULT_FROM_EMAIL="noreply@REPLACE_VERIFIED_DOMAIN.com"
302+
```
303+
304+
### Frontend (Node.js)
305+
306+
```bash
307+
# ============================================
308+
# CLEVER CLOUD CONFIGURATION
309+
# ============================================
310+
311+
# Frontend application folder
312+
APP_FOLDER="frontend"
313+
314+
# Use pnpm as package manager
315+
CC_NODE_BUILD_TOOL="pnpm"
316+
317+
# Install dev dependencies
318+
CC_NODE_DEV_DEPENDENCIES="install"
319+
320+
# Build command (runs on M instance)
321+
CC_POST_BUILD_HOOK="cd frontend && pnpm run build"
322+
323+
# Start command (runs on XS instance)
324+
CC_RUN_COMMAND="cd frontend && node build"
325+
326+
# ============================================
327+
# SVELTEKIT CONFIGURATION
328+
# ============================================
329+
330+
# Frontend origin URL (REPLACE WITH YOUR DOMAIN)
331+
ORIGIN="https://REPLACE_DOMAIN.com"
332+
333+
# Backend API URL (REPLACE WITH YOUR DOMAIN)
334+
PUBLIC_SERVER_URL="https://api.REPLACE_DOMAIN.com"
335+
336+
# No size limit for uploads
337+
BODY_SIZE_LIMIT="Infinity"
338+
```
339+
340+
---
341+
342+
## Troubleshooting
343+
344+
### Login Not Working
345+
346+
**Cause:** You are using the default `*.cleverapps.io` domains.
347+
348+
**Solution:** Use a custom domain (required).
349+
350+
### Images/Media Not Loading
351+
352+
Verify these variables are set:
353+
```bash
354+
clever env --alias adventurelog-backend | grep -E "(STATIC_FILES_PATH|STATIC_URL_PREFIX|CC_FS_BUCKET)"
355+
```
356+
357+
### Memcached Error
358+
359+
Verify `CC_PRE_RUN_HOOK` is configured:
360+
```bash
361+
clever env --alias adventurelog-backend | grep CC_PRE_RUN_HOOK
362+
# Should display: CC_PRE_RUN_HOOK="memcached -u nobody -m 64 -p 11211 -d"
363+
```
364+
365+
### Missing Country Data
366+
367+
Redeploy to re-run `download-countries`:
368+
```bash
369+
clever restart --alias adventurelog-backend --without-cache
370+
```
371+
372+
## Cost Estimation
373+
374+
| Component | Size | Estimated Cost/Month |
375+
|-----------|------|----------------------|
376+
| Frontend (runtime) | XS | ~5€ |
377+
| Frontend (build) | M (temporary) | ~0.50€ |
378+
| Backend | XS | ~5€ |
379+
| PostgreSQL | S | ~10€ |
380+
| FS Bucket | - | ~2€ |
381+
| Mailpace | - | Free tier |
382+
| **Total** | | **~22.50€/month** |
383+
384+
*Prices are estimates. Check [Clever Cloud pricing](https://www.clever-cloud.com/pricing/) for current rates.*

0 commit comments

Comments
 (0)