diff --git a/CHANGELOG.md b/CHANGELOG.md index ac0055d9d..3dbcee6f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to ### Added - ✨(frontend) add customization for translations #857 +- (doc) add documentation to install with compose #855 ### Changed diff --git a/docker/files/production/etc/nginx/conf.d/default.conf.template b/docker/files/production/etc/nginx/conf.d/default.conf.template new file mode 100644 index 000000000..43544bb0d --- /dev/null +++ b/docker/files/production/etc/nginx/conf.d/default.conf.template @@ -0,0 +1,112 @@ +upstream docs_backend { + server ${BACKEND_HOST}:8000 fail_timeout=0; +} + +upstream docs_frontend { + server ${FRONTEND_HOST}:3000 fail_timeout=0; +} + +server { + listen 8083; + server_name localhost; + charset utf-8; + + # Disables server version feedback on pages and in headers + server_tokens off; + + proxy_ssl_server_name on; + + location @proxy_to_docs_backend { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_redirect off; + proxy_pass http://docs_backend; + } + + location @proxy_to_docs_frontend { + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_redirect off; + proxy_pass http://docs_frontend; + } + + location / { + try_files $uri @proxy_to_docs_frontend; + } + + location /api { + try_files $uri @proxy_to_docs_backend; + } + + location /admin { + try_files $uri @proxy_to_docs_backend; + } + + location /static { + try_files $uri @proxy_to_docs_backend; + } + + # Proxy auth for collaboration server + location /collaboration/ws/ { + # Ensure WebSocket upgrade + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + + # Collaboration server + proxy_pass http://${YPROVIDER_HOST}:4444; + + # Set appropriate timeout for WebSocket + proxy_read_timeout 86400; + proxy_send_timeout 86400; + + # Preserve original host and additional headers + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Origin $http_origin; + proxy_set_header Host $host; + } + + location /collaboration/api/ { + # Collaboration server + proxy_pass http://${YPROVIDER_HOST}:4444; + proxy_set_header Host $host; + } + + # Proxy auth for media + location /media/ { + # Auth request configuration + auth_request /media-auth; + auth_request_set $authHeader $upstream_http_authorization; + auth_request_set $authDate $upstream_http_x_amz_date; + auth_request_set $authContentSha256 $upstream_http_x_amz_content_sha256; + + # Pass specific headers from the auth response + proxy_set_header Authorization $authHeader; + proxy_set_header X-Amz-Date $authDate; + proxy_set_header X-Amz-Content-SHA256 $authContentSha256; + + # Get resource from Minio + proxy_pass https://${S3_HOST}/${BUCKET_NAME}/; + proxy_set_header Host ${S3_HOST}; + + proxy_ssl_name ${S3_HOST}; + + add_header Content-Security-Policy "default-src 'none'" always; + } + + location /media-auth { + proxy_pass http://docs_backend/api/v1.0/documents/media-auth/; + proxy_set_header X-Forwarded-Proto https; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Original-URL $request_uri; + + # Prevent the body from being passed + proxy_pass_request_body off; + proxy_set_header Content-Length ""; + proxy_set_header X-Original-Method $request_method; + } +} \ No newline at end of file diff --git a/docs/examples/compose/compose.yaml b/docs/examples/compose/compose.yaml new file mode 100644 index 000000000..597cf1e0f --- /dev/null +++ b/docs/examples/compose/compose.yaml @@ -0,0 +1,78 @@ +services: + postgresql: + image: postgres:16 + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 1s + timeout: 2s + retries: 300 + env_file: + - env.d/postgresql + - env.d/common + environment: + - PGDATA=/var/lib/postgresql/data/pgdata + volumes: + - ./data/databases/backend:/var/lib/postgresql/data/pgdata + + redis: + image: redis:5 + + backend: + image: lasuite/impress-backend:latest + user: ${DOCKER_USER:-1000} + restart: always + environment: + - DJANGO_CONFIGURATION=Production + env_file: + - env.d/common + - env.d/backend + - env.d/yprovider + - env.d/postgresql + healthcheck: + test: ["CMD", "python", "manage.py", "check"] + interval: 15s + timeout: 30s + retries: 20 + start_period: 10s + depends_on: + postgresql: + condition: service_healthy + restart: true + redis: + condition: service_started + + y-provider: + image: lasuite/impress-y-provider:latest + user: ${DOCKER_USER:-1000} + env_file: + - env.d/common + - env.d/yprovider + + frontend: + image: lasuite/impress-frontend:latest + user: "101" + entrypoint: + - /docker-entrypoint.sh + command: ["nginx", "-g", "daemon off;"] + env_file: + - env.d/common + # Uncomment and set your values if using our nginx proxy example + #environment: + # - VIRTUAL_HOST=${DOCS_HOST} # used by nginx proxy + # - VIRTUAL_PORT=8083 # used by nginx proxy + # - LETSENCRYPT_HOST=${DOCS_HOST} # used by lets encrypt to generate TLS certificate + volumes: + - ./default.conf.template:/etc/nginx/templates/docs.conf.template + depends_on: + backend: + condition: service_healthy + +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier +# - default + +# Uncomment if using our nginx proxy example +#networks: +# proxy-tier: +# external: true diff --git a/docs/examples/compose/keycloak/README.md b/docs/examples/compose/keycloak/README.md new file mode 100644 index 000000000..b33186bb2 --- /dev/null +++ b/docs/examples/compose/keycloak/README.md @@ -0,0 +1,88 @@ +# Deploy and Configure Keycloak for Docs + +## Installation + +> \[!CAUTION\] +> We provide those instructions as an example, for production environments, you should follow the [official documentation](https://www.keycloak.org/documentation). + +### Step 1: Prepare your working environment: + +```bash +mkdir keycloak +curl -o compose.yaml https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/examples/compose/keycloak/compose.yaml +curl -o env.d/kc_postgresql https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production/kc_postgresql +curl -o env.d/keycloak https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production/keycloak +``` + +### Step 2:. Update `env.d/` files + +The following variables need to be updated with your own values, others can be left as is: + +```env +POSTGRES_PASSWORD= +KC_HOSTNAME=https://id.yourdomain.tld # Change with your own URL +KC_BOOTSTRAP_ADMIN_PASSWORD= +``` + +### Step 3: Expose keycloak instance on https + +> \[!NOTE\] +> You can skip this section if you already have your own setup. + +To access your Keycloak instance on the public network, it needs to be exposed on a domain with SSL termination. You can use our [example with nginx proxy and Let's Encrypt companion](../nginx-proxy/README.md) for automated creation/renewal of certificates using [acme.sh](http://acme.sh). + +If following our example, uncomment the environment and network sections in compose file and update it with your values. + +```yaml +version: '3' +services: + keycloak: + ... + # Uncomment and set your values if using our nginx proxy example + # environment: + # - VIRTUAL_HOST=id.yourdomain.tld # used by nginx proxy + # - VIRTUAL_PORT=8080 # used by nginx proxy + # - LETSENCRYPT_HOST=id.yourdomain.tld # used by lets encrypt to generate TLS certificate + ... +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier +# - default + +# Uncomment if using our nginx proxy example +#networks: +# proxy-tier: +# external: true +``` + +### Step 4: Start the service + +```bash +`docker compose up -d` +``` + +Your keycloak instance is now available on https://doc.yourdomain.tld + +## Creating an OIDC Client for Docs Application + +### Step 1: Create a New Realm + +1. Log in to the Keycloak administration console. +2. Navigate to the realm tab and click on the "Create realm" button. +3. Enter the name of the realm - `docs`. +4. Click "Create". + +#### Step 2: Create a New Client + +1. Navigate to the "Clients" tab. +2. Click on the "Create client" button. +3. Enter the client ID - e.g. `docs`. +4. Enable "Client authentication" option. +6. Set the "Valid redirect URIs" to the URL of your docs application suffixed with `/*` - e.g., "https://docs.example.com/*". +1. Set the "Web Origins" to the URL of your docs application - e.g. `https://docs.example.com`. +1. Click "Save". + +#### Step 3: Get Client Credentials + +1. Go to the "Credentials" tab. +2. Copy the client ID (`docs` in this example) and the client secret. \ No newline at end of file diff --git a/docs/examples/compose/keycloak/compose.yaml b/docs/examples/compose/keycloak/compose.yaml new file mode 100644 index 000000000..86ece3cec --- /dev/null +++ b/docs/examples/compose/keycloak/compose.yaml @@ -0,0 +1,36 @@ +services: + kc_postgresql: + image: postgres:16 + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + interval: 1s + timeout: 2s + retries: 300 + env_file: + - env.d/kc_postgresql + volumes: + - ./data/keycloak:/var/lib/postgresql/data/pgdata + + keycloak: + image: quay.io/keycloak/keycloak:26.1.3 + command: ["start"] + env_file: + - env.d/kc_postgresql + - env.d/keycloak + # Uncomment and set your values if using our nginx proxy example + # environment: + # - VIRTUAL_HOST=id.yourdomain.tld # used by nginx proxy + # - VIRTUAL_PORT=8080 # used by nginx proxy + # - LETSENCRYPT_HOST=id.yourdomain.tld # used by lets encrypt to generate TLS certificate + depends_on: + kc_postgresql:: + condition: service_healthy + restart: true +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier +# - default +# +#networks: +# proxy-tier: +# external: true \ No newline at end of file diff --git a/docs/examples/compose/minio/README.md b/docs/examples/compose/minio/README.md new file mode 100644 index 000000000..e2db985f2 --- /dev/null +++ b/docs/examples/compose/minio/README.md @@ -0,0 +1,103 @@ +# Deploy and Configure Minio for Docs + +## Installation + +> \[!CAUTION\] +> We provide those instructions as an example, it should not be run in production. For production environments, deploy MinIO [in a Multi-Node Multi-Drive (Distributed)](https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html#minio-mnmd) topology + +### Step 1: Prepare your working environment: + +```bash +mkdir minio +curl -o compose.yaml https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/examples/compose/minio/compose.yaml +``` + +### Step 2:. Update compose file with your own values + +```yaml +version: '3' +services: + minio: + ... + environment: + - MINIO_ROOT_USER= + - MINIO_ROOT_PASSWORD= +``` + +### Step 3: Expose MinIO instance + +#### Option 1: Internal network + +You may not need to expose your MinIO instance to the public if only services hosted on the same private network need to access to your MinIO instance. + +You should create a docker network that will be shared between those services + +```bash +docker network create storage-tier +``` + +#### Option 2: Public network + +If you want to expose your MinIO instance to the public, it needs to be exposed on a domain with SSL termination. You can use our [example](../nginx-proxy/README.md) with an nginx proxy and Let's Encrypt companion for automated creation/renewal of Let's Encrypt certificates using [acme.sh](http://acme.sh). + +If following our example, uncomment the environment and network sections in compose file and update it with your values. + +```yaml +version: '3' +services: + docs: + ... + minio: + ... + environment: + ... + # - VIRTUAL_HOST=storage.yourdomain.tld # used by nginx proxy + # - VIRTUAL_PORT=9000 # used by nginx proxy + # - LETSENCRYPT_HOST=storage.yourdomain.tld # used by lets encrypt to generate TLS certificate + ... +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier +# - default + +# Uncomment if using our nginx proxy example +#networks: +# proxy-tier: +# external: true +``` + +In this example we are only exposing MinIO API service. Follow the official documentation to configure Minio WebUI. + +### Step 4: Start the service + +```bash +`docker compose up -d` +``` + +Your minio instance is now available on https://storage.yourdomain.tld + +## Creating a user and bucket for your Docs instance + +### Installing mc + +Follow the [official documentation](https://min.io/docs/minio/linux/reference/minio-mc.html#install-mc) to install mc + +### Step 1: Configure `mc` to connect to your MinIO Server with your root user + +```shellscript +mc alias set minio +``` + +Replace the values with those you have set in the previous steps + +### Step 2: Create a new bucket with versioning enabled + +```shellscript +mc mb --with-versioning minio/ +``` + +Replace `your-bucket-name` with the desired name for your bucket e.g. `docs-media-storage` + +### Additional notes: + +For increased security you should create a dedicated user with `readwrite` access to the Bucket. In the following example we will use MinIO root user. diff --git a/docs/examples/compose/minio/compose.yaml b/docs/examples/compose/minio/compose.yaml new file mode 100644 index 000000000..edf157866 --- /dev/null +++ b/docs/examples/compose/minio/compose.yaml @@ -0,0 +1,27 @@ +services: + minio: + image: minio/minio + environment: + - MINIO_ROOT_USER= + - MINIO_ROOT_PASSWORD= + # Uncomment and set your values if using our nginx proxy example + # - VIRTUAL_HOST=storage.yourdomain.tld # used by nginx proxy + # - VIRTUAL_PORT=9000 # used by nginx proxy + # - LETSENCRYPT_HOST=storage.yourdomain.tld # used by lets encrypt to generate TLS certificate + healthcheck: + test: ["CMD", "mc", "ready", "local"] + interval: 1s + timeout: 20s + retries: 300 + entrypoint: "" + command: minio server /data + volumes: + - ./data/minio:/data +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier + +# Uncomment if using our nginx proxy example +#networks: +# proxy-tier: +# external: true \ No newline at end of file diff --git a/docs/examples/compose/nginx-proxy/README.md b/docs/examples/compose/nginx-proxy/README.md new file mode 100644 index 000000000..3d04e84a9 --- /dev/null +++ b/docs/examples/compose/nginx-proxy/README.md @@ -0,0 +1,39 @@ +# Nginx proxy with automatic SSL certificates + +> \[!CAUTION\] +> We provide those instructions as an example, for extended development or production environments, you should follow the [official documentation](https://github.com/nginx-proxy/acme-companion/tree/main/docs). + +Nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped. + +Acme-companion is a lightweight companion container for nginx-proxy. It handles the automated creation, renewal and use of SSL certificates for proxied Docker containers through the ACME protocol. + +## Installation + +### Step 1: Prepare your working environment: + +```bash +mkdir nginx-proxy +curl -o compose.yaml https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/examples/compose/nginx-proxy/compose.yaml +``` + +### Step 2: Edit `DEFAULT_EMAIL` in the compose file. + +Albeit optional, it is recommended to provide a valid default email address through the `DEFAULT_EMAIL` environment variable, so that Let's Encrypt can warn you about expiring certificates and allow you to recover your account. + +### Step 3: Create docker network + +Containers need share the same network for auto-discovery. + +```bash +docker network create proxy-tier +``` + +### Step 4: Start service + +```bash +docker compose up -d +``` + +## Usage + +Once both nginx-proxy and acme-companion containers are up and running, start any container you want proxied with environment variables `VIRTUAL_HOST` and `LETSENCRYPT_HOST` both set to the domain(s) your proxied container is going to use. diff --git a/docs/examples/compose/nginx-proxy/compose.yaml b/docs/examples/compose/nginx-proxy/compose.yaml new file mode 100644 index 000000000..f582f1450 --- /dev/null +++ b/docs/examples/compose/nginx-proxy/compose.yaml @@ -0,0 +1,36 @@ +services: + nginx-proxy: + image: nginxproxy/nginx-proxy + container_name: nginx-proxy + ports: + - "80:80" + - "443:443" + volumes: + - html:/usr/share/nginx/html + - certs:/etc/nginx/certs:ro + - /var/run/docker.sock:/tmp/docker.sock:ro + networks: + - proxy-tier + + acme-companion: + image: nginxproxy/acme-companion + container_name: nginx-proxy-acme + environment: + - DEFAULT_EMAIL=mail@yourdomain.tld + volumes_from: + - nginx-proxy + volumes: + - certs:/etc/nginx/certs:rw + - acme:/etc/acme.sh + - /var/run/docker.sock:/var/run/docker.sock:ro + networks: + - proxy-tier + +networks: + proxy-tier: + external: true + +volumes: + html: + certs: + acme: diff --git a/docs/examples/impress.values.yaml b/docs/examples/helm/impress.values.yaml similarity index 100% rename from docs/examples/impress.values.yaml rename to docs/examples/helm/impress.values.yaml diff --git a/docs/examples/keycloak.values.yaml b/docs/examples/helm/keycloak.values.yaml similarity index 100% rename from docs/examples/keycloak.values.yaml rename to docs/examples/helm/keycloak.values.yaml diff --git a/docs/examples/minio.values.yaml b/docs/examples/helm/minio.values.yaml similarity index 100% rename from docs/examples/minio.values.yaml rename to docs/examples/helm/minio.values.yaml diff --git a/docs/examples/postgresql.values.yaml b/docs/examples/helm/postgresql.values.yaml similarity index 100% rename from docs/examples/postgresql.values.yaml rename to docs/examples/helm/postgresql.values.yaml diff --git a/docs/examples/redis.values.yaml b/docs/examples/helm/redis.values.yaml similarity index 100% rename from docs/examples/redis.values.yaml rename to docs/examples/helm/redis.values.yaml diff --git a/docs/installation/compose.md b/docs/installation/compose.md new file mode 100644 index 000000000..87f04124e --- /dev/null +++ b/docs/installation/compose.md @@ -0,0 +1,226 @@ +# Installation with docker compose + +We provide a sample configuration for running Docs using Docker Compose. Please note that this configuration is experimental, and the official way to deploy Docs in production is to use [k8s](../installation/k8s.md) + +## Requirements + +- A modern version of Docker and its Compose plugin. +- A domain name and DNS configured to your server. +- An Identity Provider that supports OpenID Connect protocol - we provide [an example to deploy Keycloak](../examples/compose/keycloak/README.md). +- An Object Storage that implements S3 API - we provide [an example to deploy Minio](../examples/compose/minio/README.md). +- A Postgresql database - we provide [an example in the compose file](../examples/compose/compose.yaml). +- A Redis database - we provide [an example in the compose file](../examples/compose/compose.yaml). + +## Software Requirements + +Ensure you have Docker Compose(v2) installed on your host server. Follow the official guidelines for a reliable setup: + +Docker Compose is included with Docker Engine: + +- **Docker Engine:** We suggest adhering to the instructions provided by Docker + for [installing Docker Engine](https://docs.docker.com/engine/install/). + +For older versions of Docker Engine that do not include Docker Compose: + +- **Docker Compose:** Install it as per the [official documentation](https://docs.docker.com/compose/install/). + +> [!NOTE] +> `docker-compose` may not be supported. You are advised to use `docker compose` instead. + +## Step 1: Prepare your working environment: + +```bash +mkdir -p docs/env.d +curl -o compose.yaml https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/examples/compose/compose.yaml +curl -o env.d/common https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production.dist/common +curl -o env.d/backend https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production.dist/backend +curl -o env.d/yprovider https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production.dist/yprovider +curl -o env.d/common https://raw.githubusercontent.com/suitenumerique/docs/refs/heads/main/docs/env.d/production.dist/postgresql +``` + +## Step 2: Configuration + +Docs configuration is achieved through environment variables. We provide a [detailed description of all variables](../env.md). + +In this example, we assume the following services: + +- OIDC provider on https://id.yourdomain.tld +- Object Storage on https://storage.yourdomain.tld +- Docs on https://docs.yourdomain.tld +- Bucket name is docs-media-storage + +**Set your own values in `env.d/common`** + +### OIDC + +Authentication in Docs is managed through Open ID Connect protocol. A functional Identity Provider implementing this protocol is required. + +For guidance, refer to our [Keycloak deployment example](../examples/compose/keycloak/README.md). + +If using Keycloak as your Identity Provider, set `OIDC_RP_CLIENT_ID` and `OIDC_RP_CLIENT_SECRET` variables with those of the OIDC client created for Docs. By default we have set `docs` as the realm name, if you have named your realm differently, update the value `REALM_NAME` in `env.d/common` + +For others OIDC providers, update the variables in `env.d/backend`. + +### Object Storage + +Files and media are stored in an Object Store that supports the S3 API. + +For guidance, refer to our [Minio deployment example](../examples/compose/minio/README.md). + +Set `AWS_S3_ACCESS_KEY_ID` and `AWS_S3_SECRET_ACCESS_KEY` with the credentials of a user with `readwrite` access to the bucket created for Docs. + +### Postgresql + +Docs uses PostgreSQL as its database. Although an external PostgreSQL can be used, our example provides a deployment method. + +If you are using the example provided, you need to generate a secure key for `DB_PASSWORD` and set it in `env.d/postgresql`. + +If you are using an external service or not using our default values, you should update the variables in `env.d/postgresql` + +### Redis + +Docs uses Redis for caching. While an external Redis can be used, our example provides a deployment method. + +If you are using an external service, you need to set `REDIS_URL` environment variable in `env.d/backend`. + +### Y Provider + +The Y provider service enables collaboration through websockets. + +Generates a secure key for `Y_PROVIDER_API_KEY` and `COLLABORATION_SERVER_SECRET` in ``env.d/yprovider``. + +### Docs + +The Docs backend is built on the Django Framework. + +Generates a secure key for `DJANGO_SECRET_KEY` in `env.d/backend`. + +### Logging + +Update the following variables in `env.d/backend` if you want to change the logging levels: +```env +LOGGING_LEVEL_HANDLERS_CONSOLE=DEBUG +LOGGING_LEVEL_LOGGERS_ROOT=DEBUG +LOGGING_LEVEL_LOGGERS_APP=DEBUG +``` + +### Mail + +The following environment variables are required in `env.d/backend` for the mail service to send invitations : + +```env +DJANGO_EMAIL_HOST= +DJANGO_EMAIL_HOST_USER= +DJANGO_EMAIL_HOST_PASSWORD= +DJANGO_EMAIL_PORT= +DJANGO_EMAIL_FROM= + +#DJANGO_EMAIL_USE_TLS=true # A flag to enable or disable TLS for email sending. +#DJANGO_EMAIL_USE_SSL=true # A flag to enable or disable SSL for email sending. + + +DJANGO_EMAIL_BRAND_NAME= # e.g. "La Suite Numérique" +DJANGO_EMAIL_LOGO_IMG= # e.g. "https://docs.yourdomain.tld/assets/logo-suite-numerique.png" +``` + +### AI + +Built-in AI actions let users generate, summarize, translate, and correct content. + +AI is disabled by default. To enable it, the following environment variables must be set in in `env.d/backend`: + +```env +AI_FEATURE_ENABLED=true # is false by default +AI_BASE_URL=https://openaiendpoint.com +AI_API_KEY= +AI_MODEL= e.g. llama +``` + +### Frontend theme + +You can [customize your Docs instance](../theming.md) with your own theme and custom css. + +The following environment variables must be set in `env.d/backend`: + +```env +FRONTEND_THEME=default # name of your theme built with cuningham +FRONTEND_CSS_URL=https://storage.yourdomain.tld/themes/custom.css # custom css +``` + +## Step 3: Reverse proxy and SSL/TLS + +> [!WARNING] +> In a production environment, configure SSL/TLS termination to run your instance on https. + +If you have your own certificates and proxy setup, you can skip this part. + +You can follow our [nginx proxy example](../examples/compose/nginx-proxy/README.md) with automatic generation and renewal of certificate with Let's Encrypt. + +You will need to uncomment the environment and network sections in compose file and update it with your values. + +```yaml + frontend: + ... + # Uncomment and set your values if using our nginx proxy example + #environment: + # - VIRTUAL_HOST=${DOCS_HOST} # used by nginx proxy + # - VIRTUAL_PORT=8083 # used by nginx proxy + # - LETSENCRYPT_HOST=${DOCS_HOST} # used by lets encrypt to generate TLS certificate + ... +# Uncomment if using our nginx proxy example +# networks: +# - proxy-tier +# +#networks: +# proxy-tier: +# external: true +``` + +## Step 4: Start Docs + +You are ready to start your Docs application ! + +```bash +docker compose up -d +``` +> [!NOTE] +> Version of the images are set to latest, you should pin it to the desired version to avoid unwanted upgrades when pulling latest image. + +## Step 5: Run the database migration and create Django admin user + +```bash +docker compose run --rm backend python manage.py migrate +docker compose run --rm backend python manage.py createsuperuser --email --password +``` + +Replace `` with the email of your admin user and generate a secure password. + +Your docs instance is now available on the domain you defined, https://docs.yourdomain.tld. + +THe admin interface is available on https://docs.yourdomain.tld/admin with the admin user you just created. + +## How to upgrade your Docs application + +Before running an upgrade you must check the [Upgrade document](../../UPGRADE.md) for specific procedures that might be needed. + +You can also check the [Changelog](../../CHANGELOG.md) for brief summary of the changes. + +### Step 1: Edit the images tag with the desired version + +### Step 2: Pull the images + +```bash +docker compose pull +``` + +### Step 3: Restart your containers + +```bash +docker compose restart +``` + +### Step 4: Run the database migration +Your database schema may need to be updated, run: +```bash +docker compose run --rm backend python manage.py migrate +``` diff --git a/docs/installation.md b/docs/installation/kubernetes.md similarity index 100% rename from docs/installation.md rename to docs/installation/kubernetes.md diff --git a/env.d/production.dist/backend b/env.d/production.dist/backend new file mode 100644 index 000000000..e70f2c110 --- /dev/null +++ b/env.d/production.dist/backend @@ -0,0 +1,65 @@ +## Django +DJANGO_ALLOWED_HOSTS=${DOCS_HOST} +DJANGO_SECRET_KEY= +DJANGO_SETTINGS_MODULE=impress.settings +DJANGO_CONFIGURATION=Production + +# Logging +# Set to DEBUG level for dev only +LOGGING_LEVEL_HANDLERS_CONSOLE=ERROR +LOGGING_LEVEL_LOGGERS_ROOT=INFO +LOGGING_LEVEL_LOGGERS_APP=INFO + +# Python +PYTHONPATH=/app + +# Mail +DJANGO_EMAIL_HOST= +DJANGO_EMAIL_HOST_USER= +DJANGO_EMAIL_HOST_PASSWORD= +DJANGO_EMAIL_PORT= +DJANGO_EMAIL_FROM= + +#DJANGO_EMAIL_USE_TLS=true # A flag to enable or disable TLS for email sending. +#DJANGO_EMAIL_USE_SSL=true # A flag to enable or disable SSL for email sending. + +DJANGO_EMAIL_BRAND_NAME="La Suite Numérique" +DJANGO_EMAIL_LOGO_IMG="https://${DOCS_HOST}/assets/logo-suite-numerique.png" + +# Media +AWS_S3_ENDPOINT_URL=https://${S3_HOST} +AWS_S3_ACCESS_KEY_ID= +AWS_S3_SECRET_ACCESS_KEY= +AWS_STORAGE_BUCKET_NAME=${BUCKET_NAME} +MEDIA_BASE_URL=https://${DOCS_HOST} + +# OIDC +OIDC_OP_JWKS_ENDPOINT=https://${KEYCLOAK_HOST}/realms/${REALM_NAME}/protocol/openid-connect/certs +OIDC_OP_AUTHORIZATION_ENDPOINT=https://${KEYCLOAK_HOST}/realms/${REALM_NAME}/protocol/openid-connect/auth +OIDC_OP_TOKEN_ENDPOINT=https://${KEYCLOAK_HOST}/realms/${REALM_NAME}/protocol/openid-connect/token +OIDC_OP_USER_ENDPOINT=https://${KEYCLOAK_HOST}/realms/${REALM_NAME}/protocol/openid-connect/userinfo +OIDC_OP_LOGOUT_ENDPOINT=https://${KEYCLOAK_HOST}/realms/${REALM_NAME}/protocol/openid-connect/logout +OIDC_RP_CLIENT_ID= +OIDC_RP_CLIENT_SECRET= +OIDC_RP_SIGN_ALGO=RS256 +OIDC_RP_SCOPES="openid email" +#USER_OIDC_FIELD_TO_SHORTNAME +#USER_OIDC_FIELDS_TO_FULLNAME + +LOGIN_REDIRECT_URL=https://${DOCS_HOST} +LOGIN_REDIRECT_URL_FAILURE=https://${DOCS_HOST} +LOGOUT_REDIRECT_URL=https://${DOCS_HOST} + +OIDC_REDIRECT_ALLOWED_HOSTS=["https://${DOCS_HOST}"] + +# AI +#AI_FEATURE_ENABLED=true # is false by default +#AI_BASE_URL=https://openaiendpoint.com +#AI_API_KEY= +#AI_MODEL= e.g. llama + +# Frontend +#FRONTEND_THEME=mytheme +#FRONTEND_CSS_URL=https://storage.yourdomain.tld/themes/custom.css +#FRONTEND_FOOTER_FEATURE_ENABLED=true +#FRONTEND_URL_JSON_FOOTER=https://docs.domain.tld/contents/footer-demo.json \ No newline at end of file diff --git a/env.d/production.dist/common b/env.d/production.dist/common new file mode 100644 index 000000000..bb289de71 --- /dev/null +++ b/env.d/production.dist/common @@ -0,0 +1,9 @@ +DOCS_HOST=docs.domain.tld +KEYCLOAK_HOST=id.domain.tld +S3_HOST=storage.domain.tld +BACKEND_HOST=backend +FRONTEND_HOST=frontend +YPROVIDER_HOST=y-provider +BUCKET_NAME=docs-media-storage +REALM_NAME=docs +#COLLABORATION_WS_URL=wss://${DOCS_HOST}/collaboration/ws/ \ No newline at end of file diff --git a/env.d/production.dist/kc_postgresql b/env.d/production.dist/kc_postgresql new file mode 100644 index 000000000..7fa5a2b31 --- /dev/null +++ b/env.d/production.dist/kc_postgresql @@ -0,0 +1,13 @@ +# Postgresql db container configuration +POSTGRES_DB=keycloak +POSTGRES_USER=keycloak +POSTGRES_PASSWORD= +PGDATA=/var/lib/postgresql/data/pgdata + +# Keycloak postgresql configuration +KC_DB=postgres +KC_DB_SCHEMA=public +KC_DB_HOST=postgresql +KC_DB_NAME=${POSTGRES_DB} +KC_DB_USER=${POSTGRES_USER} +KC_DB_PASSWORD=${POSTGRES_PASSWORD} \ No newline at end of file diff --git a/env.d/production.dist/keycloak b/env.d/production.dist/keycloak new file mode 100644 index 000000000..18814b4a8 --- /dev/null +++ b/env.d/production.dist/keycloak @@ -0,0 +1,8 @@ +# Keycloak admin user +KC_BOOTSTRAP_ADMIN_USERNAME=admin +KC_BOOTSTRAP_ADMIN_PASSWORD= + +# Keycloak configuration +KC_HOSTNAME=https://id.yourdomain.tld # Change with your own URL +KC_PROXY_HEADERS=xforwarded # in this example we are running behind an nginx proxy +KC_HTTP_ENABLED=true # in this example we are running behind an nginx proxy diff --git a/env.d/production.dist/postgresql b/env.d/production.dist/postgresql new file mode 100644 index 000000000..9d096aed1 --- /dev/null +++ b/env.d/production.dist/postgresql @@ -0,0 +1,11 @@ +# App database configuration +DB_HOST=postgresql +DB_NAME=docs +DB_USER=docs +DB_PASSWORD= +DB_PORT=5432 + +# Postgresql db container configuration +POSTGRES_DB=docs +POSTGRES_USER=docs +POSTGRES_PASSWORD=${DB_PASSWORD} diff --git a/env.d/production.dist/yprovider b/env.d/production.dist/yprovider new file mode 100644 index 000000000..31cb138b6 --- /dev/null +++ b/env.d/production.dist/yprovider @@ -0,0 +1,7 @@ +Y_PROVIDER_API_BASE_URL=http://${YPROVIDER_HOST}:4444/api +Y_PROVIDER_API_KEY= +COLLABORATION_SERVER_SECRET= +COLLABORATION_SERVER_ORIGIN=https://${DOCS_HOST} +COLLABORATION_API_URL=https://${DOCS_HOST}/collaboration/api/ +COLLABORATION_BACKEND_BASE_URL=https://${DOCS_HOST} +COLLABORATION_LOGGING=true \ No newline at end of file