mirror of
https://github.com/suitenumerique/docs.git
synced 2026-08-25 17:02:31 +02:00
We rename the docs folder into documentation, we think this new name is more relevant and less confusing.
263 lines
10 KiB
Markdown
263 lines
10 KiB
Markdown
# Deployment on Scalingo
|
|
|
|
This guide explains how to deploy Docs on [Scalingo](https://scalingo.com/) using a custom buildpack.
|
|
|
|
## Overview
|
|
|
|
Scalingo is a Platform-as-a-Service (PaaS) that simplifies application deployment. This setup uses a custom buildpack to handle both the frontend (Next.js static export) and backend (Django) builds, serving them through Nginx. The collaboration server (y-provider) runs alongside the Django backend.
|
|
|
|
## Prerequisites
|
|
|
|
- A Scalingo account
|
|
- Scalingo CLI installed (optional but recommended)
|
|
- A PostgreSQL database Scalingo addon
|
|
- A Redis Scalingo addon (for caching and sessions)
|
|
- An external Identity Provider that supports OpenID Connect protocol
|
|
- An external Object Storage that implements S3 API
|
|
|
|
## Step 1: Create Your App
|
|
|
|
Create a new app on Scalingo using `scalingo` CLI or using the [Scalingo dashboard](https://dashboard.scalingo.com/).
|
|
|
|
## Step 2: Provision Addons
|
|
|
|
Add the required PostgreSQL and Redis services.
|
|
|
|
This will set the following environment variables automatically:
|
|
- `SCALINGO_POSTGRESQL_URL` - Database connection string
|
|
- `SCALINGO_REDIS_URL` - Redis connection string
|
|
|
|
## Step 3: Configure Environment Variables
|
|
|
|
Set the following environment variables in your Scalingo app:
|
|
|
|
### Buildpack Configuration
|
|
|
|
```bash
|
|
scalingo env-set BUILDPACK_URL="https://github.com/suitenumerique/buildpack#main"
|
|
scalingo env-set LASUITE_APP_NAME="docs"
|
|
scalingo env-set LASUITE_BACKEND_DIR="src/backend/"
|
|
scalingo env-set LASUITE_FRONTEND_DIR="src/frontend/"
|
|
scalingo env-set LASUITE_NGINX_DIR="."
|
|
scalingo env-set LASUITE_SCRIPT_POSTCOMPILE="bin/buildpack_postcompile.sh"
|
|
scalingo env-set LASUITE_SCRIPT_POSTFRONTEND="bin/buildpack_postfrontend.sh"
|
|
```
|
|
|
|
### Database and Cache
|
|
|
|
```bash
|
|
scalingo env-set DATABASE_URL="\$SCALINGO_POSTGRESQL_URL"
|
|
scalingo env-set REDIS_URL="\$SCALINGO_REDIS_URL"
|
|
```
|
|
|
|
### Django Settings
|
|
|
|
```bash
|
|
scalingo env-set DJANGO_SETTINGS_MODULE="impress.settings"
|
|
scalingo env-set DJANGO_CONFIGURATION="Production"
|
|
scalingo env-set DJANGO_SECRET_KEY="<generate-a-secure-secret-key>"
|
|
scalingo env-set DJANGO_ALLOWED_HOSTS="my-docs-app.osc-fr1.scalingo.io"
|
|
```
|
|
|
|
### OIDC Authentication
|
|
|
|
Configure your OIDC provider (e.g., Keycloak, Authentik):
|
|
|
|
```bash
|
|
scalingo env-set OIDC_RP_CLIENT_ID="docs-client-id"
|
|
scalingo env-set OIDC_RP_CLIENT_SECRET="<your-client-secret>"
|
|
scalingo env-set OIDC_RP_SIGN_ALGO="RS256"
|
|
scalingo env-set OIDC_OP_BASE_URL="https://auth.yourdomain.com/realms/docs"
|
|
```
|
|
|
|
Or configure individual endpoints if your provider doesn't support discovery:
|
|
|
|
```bash
|
|
scalingo env-set OIDC_OP_AUTHORIZATION_ENDPOINT="https://auth.yourdomain.com/authorize"
|
|
scalingo env-set OIDC_OP_TOKEN_ENDPOINT="https://auth.yourdomain.com/token"
|
|
scalingo env-set OIDC_OP_USER_ENDPOINT="https://auth.yourdomain.com/userinfo"
|
|
scalingo env-set OIDC_OP_JWKS_ENDPOINT="https://auth.yourdomain.com/.well-known/jwks.json"
|
|
scalingo env-set OIDC_OP_LOGOUT_ENDPOINT="https://auth.yourdomain.com/logout"
|
|
```
|
|
|
|
### S3 Media Storage
|
|
|
|
To store uploaded media files in an S3-compatible object storage:
|
|
|
|
```bash
|
|
scalingo env-set AWS_S3_ENDPOINT_URL="https://s3.amazonaws.com"
|
|
scalingo env-set AWS_S3_ACCESS_KEY_ID="<your-access-key>"
|
|
scalingo env-set AWS_S3_SECRET_ACCESS_KEY="<your-secret-key>"
|
|
scalingo env-set AWS_STORAGE_BUCKET_NAME="docs-media"
|
|
scalingo env-set AWS_S3_REGION_NAME="eu-west-1"
|
|
```
|
|
|
|
### Email Configuration (Optional)
|
|
|
|
For email notifications see [https://doc.scalingo.com/platform/app/sending-emails](https://doc.scalingo.com/platform/app/sending-emails):
|
|
|
|
```bash
|
|
scalingo env-set DJANGO_EMAIL_HOST="smtp.example.org"
|
|
scalingo env-set DJANGO_EMAIL_PORT="587"
|
|
scalingo env-set DJANGO_EMAIL_HOST_USER="<smtp-user>"
|
|
scalingo env-set DJANGO_EMAIL_HOST_PASSWORD="<smtp-password>"
|
|
scalingo env-set DJANGO_EMAIL_USE_TLS="True"
|
|
scalingo env-set DJANGO_EMAIL_FROM="docs@yourdomain.com"
|
|
```
|
|
|
|
## Step 4: Deploy
|
|
|
|
Deploy your application:
|
|
|
|
```bash
|
|
git push scalingo main
|
|
```
|
|
|
|
The buildpack will automatically:
|
|
1. Build the frontend (Next.js static export)
|
|
2. Build the backend (Django)
|
|
3. Run the post-compile script (cleanup unused files to reduce slug size)
|
|
4. Run the post-frontend script (move assets, inject theme, prepare for deployment)
|
|
5. Start uvicorn, the y-provider collaboration server, and Nginx
|
|
6. Run Django migrations
|
|
|
|
## Step 5: Create superuser
|
|
|
|
After the first deployment, create an admin user:
|
|
|
|
```bash
|
|
scalingo run python manage.py createsuperuser
|
|
```
|
|
|
|
## Custom Domain (Optional)
|
|
|
|
To use a custom domain:
|
|
|
|
1. Add the domain in Scalingo dashboard
|
|
2. Update `DJANGO_ALLOWED_HOSTS` with your custom domain
|
|
3. Configure your DNS to point to Scalingo
|
|
|
|
```bash
|
|
scalingo domains-add docs.yourdomain.com
|
|
scalingo env-set DJANGO_ALLOWED_HOSTS="docs.yourdomain.com,my-docs-app.osc-fr1.scalingo.io"
|
|
```
|
|
|
|
## Theme Customization
|
|
|
|
Docs supports theme customization via environment variables. The theme controls the appearance of the header, footer, waffle (La Suite services widget), favicon, and more.
|
|
|
|
### Custom Logo (Optional)
|
|
|
|
To replace the default Docs logo with your own, set the `THEME_CUSTOMIZATION_LOGO_URL` environment variable with an HTTPS URL pointing to an SVG file (max 5MB):
|
|
|
|
```bash
|
|
scalingo env-set THEME_CUSTOMIZATION_LOGO_URL="https://cdn.yourdomain.com/logo.svg"
|
|
```
|
|
|
|
The logo is validated during build:
|
|
- Must use HTTPS
|
|
- Must be a valid SVG file
|
|
- Must not exceed 5MB
|
|
- SSRF protection is applied
|
|
|
|
### Custom Theme (Optional)
|
|
|
|
To customize the theme (footer links, waffle, translations, etc.), set the `THEME_CUSTOMIZATION_JSON` environment variable with a JSON object. The buildpack merges your custom JSON with the default theme, so you only need to specify the parts you want to override.
|
|
|
|
> **Important:** The `THEME_CUSTOMIZATION_JSON` value must be valid JSON. Ensure it is properly escaped when setting as an environment variable.
|
|
|
|
```bash
|
|
scalingo env-set THEME_CUSTOMIZATION_JSON='{"footer":{"default":{"externalLinks":[{"label":"GitHub","href":"https://github.com/your-org/"},{"label":"Your Org","href":"https://yourdomain.com"}],"legalLinks":[{"label":"Legal Notice","href":"https://docs.yourdomain.com/legal/"},{"label":"Privacy Policy","href":"https://docs.yourdomain.com/privacy/"}],"bottomInformation":{"label":"Unless otherwise stated, all content on this site is under","link":{"label":"licence etalab-2.0","href":"https://github.com/etalab/licence-ouverte/blob/master/LO.md"}}},"en":{"bottomInformation":{"label":"Unless otherwise stated, all content on this site is under","link":{"label":"licence MIT","href":"https://github.com/your-org/license"}}},"fr":{"bottomInformation":{"label":"Sauf mention contraire, tout le contenu de ce site est sous","link":{"label":"licence etalab-2.0","href":"https://github.com/etalab/licence-ouverte/blob/master/LO.md"}}}},"waffle":{"apiUrl":"https://your-api.example.com/api/v1.0/lagaufre/services/","widgetPath":"https://static.example.com/widgets/"},"header":{"logo":{},"icon":{"src":"/assets/icon-docs.svg","style":{"width":"32px","height":"auto"},"alt":"Your Org Logo","withTitle":true}},"home":{"with-proconnect":false,"icon-banner":{"src":"/assets/icon-docs.svg","style":{"width":"64px","height":"auto"},"alt":"Your Org Logo"}},"favicon":{"light":{"href":"/assets/favicon-light.png","type":"image/png"},"dark":{"href":"/assets/favicon-dark.png","type":"image/png"}}}'
|
|
```
|
|
|
|
#### Available Theme Sections and Configuration
|
|
|
|
For detailed information on all available theme sections, waffle configuration modes, and customization options, see the [Customization Guide](../customization.md).
|
|
|
|
#### Theme Cache
|
|
|
|
The theme is cached in Redis for 24 hours by default. If you update `THEME_CUSTOMIZATION_JSON` and don't see changes, clear the Redis cache:
|
|
|
|
```bash
|
|
scalingo run python -c "from django.core.cache import cache; cache.clear()"
|
|
```
|
|
|
|
Or set `THEME_CUSTOMIZATION_CACHE_TIMEOUT` to a shorter duration:
|
|
|
|
```bash
|
|
scalingo env-set THEME_CUSTOMIZATION_CACHE_TIMEOUT=60
|
|
```
|
|
|
|
> **Note:** Changing `THEME_CUSTOMIZATION_CACHE_TIMEOUT` does not clear existing cached values in Redis. After changing this setting, clear the cache manually: `scalingo run python -c "from django.core.cache import cache; cache.clear()"`
|
|
|
|
## Troubleshooting
|
|
|
|
### Check Logs
|
|
|
|
```bash
|
|
scalingo logs --tail
|
|
```
|
|
|
|
### Common Issues
|
|
|
|
1. **Build fails**: Check that all required environment variables are set
|
|
2. **Database connection error**: Verify `DATABASE_URL` is correctly set to `$SCALINGO_POSTGRESQL_URL`
|
|
3. **Static files not served**: Ensure the buildpack post-frontend script ran successfully
|
|
4. **OIDC errors**: Verify your OIDC provider configuration and callback URLs
|
|
5. **Theme not updating**: Clear Redis cache with `scalingo run python -c "from django.core.cache import cache; cache.clear()"`
|
|
6. **Collaboration not working**: Verify the y-provider server is running and the WebSocket URL is configured
|
|
|
|
### Useful Commands
|
|
|
|
```bash
|
|
# Open a console
|
|
scalingo run bash
|
|
|
|
# Restart the app
|
|
scalingo restart
|
|
|
|
# Scale containers
|
|
scalingo scale web:2
|
|
|
|
# One-off command
|
|
scalingo run python manage.py shell
|
|
|
|
# Check environment variables
|
|
scalingo env
|
|
|
|
# View app status
|
|
scalingo status
|
|
```
|
|
|
|
## Architecture
|
|
|
|
On Scalingo, the application runs as follows:
|
|
|
|
### Build Phase
|
|
|
|
1. The buildpack compiles the frontend (Next.js static export)
|
|
2. The buildpack compiles the backend (Python dependencies)
|
|
3. `bin/buildpack_postcompile.sh` runs to clean up unused files and reduce slug size
|
|
4. `bin/buildpack_postfrontend.sh` moves the frontend build to `build/frontend-out`, downloads custom logos, injects the custom theme, and prepares the deployment structure
|
|
|
|
### Runtime
|
|
|
|
The `bin/buildpack_start.sh` script starts three processes:
|
|
|
|
- **Nginx** serves static files and proxies requests to the backend
|
|
- **uvicorn** runs the Django ASGI application on port 8000
|
|
- **y-provider** runs the collaboration WebSocket server on port 4444
|
|
|
|
Nginx routes:
|
|
- `/api/` and `/admin/` → Django backend (port 8000)
|
|
- `/collaboration/api/` and `/collaboration/ws/` → y-provider (port 4444)
|
|
- `/media/` → S3 object storage (with auth proxy)
|
|
- `/` → Static frontend files
|
|
|
|
## Additional Resources
|
|
|
|
- [Scalingo Documentation](https://doc.scalingo.com/)
|
|
- [Docs Environment Variables](../env.md)
|
|
- [Theme Customization](../customization.md)
|
|
- [Django Configurations Documentation](https://django-configurations.readthedocs.io/)
|