Instructions to deploy Eurydice manually are available below.
-
compose.yml
allows for launching a local development environment-
docker compose up -d
-
-
compose.prod.yml
allows for launching the origin or destination production stack- Configure the environment variables (more details below)
- Create the directories configured in the environment variables
- Set permissions to allow read/write access to these directories for the UID configured in the environment variables
If you don't need elk logging:
-
Configure the database by applying the migrations:
- Origin:
docker compose -f compose.prod.yml --profile origin run --rm db-migrations-origin
- Destination (on another machine):
docker compose -f compose.prod.yml --profile destination run --rm db-migrations-destination
- Origin:
-
Launch the stack:
- Origin:
docker compose -f compose.prod.yml --profile origin up -d
- Destination (on another machine):
docker compose -f compose.prod.yml --profile destination up -d
- Origin:
If you want elk logging:
-
Configure the database by applying the migrations:
- Origin:
docker compose -f compose.prod.yml --profile origin-with-elk-logging run --rm db-migrations-origin-with-elk
- Destination (on another machine):
docker compose -f compose.prod.yml --profile destination-with-elk-logging run --rm db-migrations-destination-with-elk
- Origin:
-
Launch the stack:
- Origin:
docker compose -f compose.prod.yml --profile origin-with-elk-logging up -d
- Destination (on another machine):
docker compose -f compose.prod.yml --profile destination-with-elk-logging up -d
- Note: Additional environment variables are needed: see the list below. You will need an API key: more details below.
- Origin:
Optional admin user
- (optional) Create an administrator user for accessing the admin interface at
/admin
(default credentials are admin/admin)- Origin:
docker compose -f compose.prod.yml exec backend-origin make superuser
- Destination (on another machine):
docker compose -f compose.prod.yml exec backend-destination make superuser
- Origin:
The .env
file should be placed in the directory from which you are running docker compose
(usually next to the compose.yml
file).
You can also name the file as you wish and point compose to it using the --env-file
flag.
The following environment variables should be configured for the deployment (variables without a default value are mandatory):
Variable | Default value | Description |
---|---|---|
EURYDICE_VERSION |
latest |
Tag for the Eurydice docker image (list of tags) |
LIDI_VERSION |
latest |
Tag for the lidis/r docker images (list of tags) |
LOCAL_DOCKER_REGISTRY |
Docker image registry: hostname of the registry that hosts Docker images for eurydice and lidi | |
REMOTE_DOCKER_REGISTRY |
docker.io |
Docker image registry: hostname for other docker images (e.g. https://hub.docker.com/) |
PUID |
1000 |
Numeric identifier to the user under which the services of will run |
PGID |
1000 |
Numeric identifier for the group under which the services will run |
GUNICORN_CONFIGURATION |
"" |
Gunicorn commandline arguments |
EURYDICE_IPV4_SUBNET |
172.18.0.0/24 |
Range of IP addresses that will be assigned to containers within the eurydice network |
BACKEND_HOSTNAMES |
localhost |
Hostname(s) for the backend API separated by a comma: , |
CSRF_TRUSTED_ORIGINS |
"" |
Additionnal origin(s) for CSRF validation, separated by a comma: , . SEE Django documentation Must include scheme ("http://", "https://") . May be left empty. |
FRONTEND_HOSTNAMES |
localhost |
Hostname(s) for the frontend UI separated by a space: |
KIBANA_HOSTNAME |
localhost |
Hostname for the Kibana UI. |
LIDIR_HOST |
0.0.0.0 (lidir) |
Lidir hostname |
LIDIR_PORT |
11011 |
Lidir port number |
LIDI_UDP_MTU |
1500 |
Value for lidi option --from_udp_mtu (see https://github.com/ANSSI-FR/lidi/blob/master/doc/parameters.rst#block-and-packet-sizes) |
LIDI_ENCODING_BLOCK_SIZE |
60000 |
Value for lidi option --encoding_block_size (see https://github.com/ANSSI-FR/lidi/blob/master/doc/parameters.rst#block-and-packet-sizes) |
LIDI_REPAIR_BLOCK_SIZE |
6000 |
Value for lidi option --repair_block_size (see https://github.com/ANSSI-FR/lidi/blob/master/doc/parameters.rst#block-and-packet-sizes) |
LIDIS_DOCKER_HOST |
0.0.0.0 (lidis), host-gateway (sender) |
Host interface on which lidis will listen and to which the sender will connect |
MINIO_ENABLED |
true |
Enables usage of minio. If minio is disabled, eurydice will store transferable data on the filesystem. See TRANSFERABLE_STORAGE_DIR and MINIO_ENDPOINT . Disabling minio and using the filesystem is only supported on the destination side. |
TRANSFERABLE_STORAGE_DIR |
Host path to the directory containing transferable data, if minio is disabled data | |
MINIO_ENDPOINT |
minio:9000 |
Hostname and port of the s3 storage server. By default, uses the minio container embedded in the compose stack |
MINIO_DATA_DIR |
Host path to the directory containing minio data | |
MINIO_CONF_DIR |
Host path to the directory containing the minio configuration | |
DB_DATA_DIR |
Host path to the directory containing the database's data | |
LOG_LEVEL |
INFO |
Django and Eurydice Log Level |
LOG_TO_FILE |
true |
If true, python processes will configure their logger to log into json files. See PYTHON_LOGS_DIR . |
PYTHON_LOGS_DIR |
Host path to the directory containing python logs. Each service will write into their own sub-directory, as such: ${PYTHON_LOGS_DIR}/sender-logs/log.json |
|
RUST_LOG |
See compose.prod.yml | Rust log level (i.e. Lidi log level) |
DB_LOGS_DIR |
Host path to the directory containing the database's logs | |
ELK_VERSION |
7.17.11 |
Version of Filebeat service. Should match the version of the targeted elastic service. |
FILEBEAT_CONFIG_PATH |
Host path to the filebeat config. Set this variable if you use the filebeat service (--profile *-with-elk-logging ). |
|
FILEBEAT_LOGS_DIR |
Host path to the directory containing logs created by filebeat . Set this variable if you use the filebeat service (--profile *-with-elk-logging ). |
|
FILEBEAT_DATA_DIR |
Host path to the directory containing filebeat's persistent data files . Set this variable if you use the filebeat service (--profile *-with-elk-logging ). |
|
ELASTICSEARCH_API_KEY |
"" |
API key used by filebeat to publish logs to elasticsearch. Set this variable if you use the filebeat service (--profile *-with-elk-logging ). |
ELASTICSEARCH_HOSTS |
Elasticsearch URL. Set this variable if you use the filebeat service (--profile *-with-elk-logging ). Should start with https. |
|
ELASTICSEARCH_CERT_PATH |
/etc/ssl/certs/ca-certificates.crt |
Absolute path to certificate that should be used to connect to elastic search. Set this variable if you use the filebeat service (--profile *-with-elk-logging ). |
MINIO_SECRET_KEY |
Secret key for Minio's S3 API | |
MINIO_EXPIRATION_DAYS |
8 |
Expiration delay for Minio objects, in days, after which they will automatically be deleted on the origin side. Default is 8. (On the destination side, this expiration delay is automatically computed to be S3REMOVER_EXPIRE_TRANSFERABLES_AFTER + 1 day, rounded down a day.) |
EURYDICE_TRANSFERABLE_MAX_SIZE |
54975581388800 |
File upload size limit on the origin side. Should be less than your storage capacity. Default is 50TiB, the maximum size that Minio can handle. |
DJANGO_SECRET_KEY |
Django secret key django | |
DB_PASSWORD |
PostgreSQL database password d'Eurydice | |
USER_ASSOCIATION_TOKEN_SECRET_KEY |
Secret key for generating association tokens (must be the same for the origin and destination APIs) | |
S3REMOVER_RUN_EVERY |
1min |
Run frequency for the S3Remover (service which removes minio objects and sets Transferable to EXPIRED on the destination side) |
S3REMOVER_EXPIRE_TRANSFERABLES_AFTER |
7days |
Duration before which files received on the destination side are marked as EXPIRED . |
S3REMOVER_POLL_EVERY |
200ms |
Maximum acceptable duration between the S3Remover receiving a SIGINT signal and the process' termination |
DBTRIMMER_RUN_EVERY |
6h |
Launch frequency for the DBTrimmer (service which removes old transferables from the database) |
DBTRIMMER_TRIM_TRANSFERABLES_AFTER |
7days |
Availability duration for a transferable's metadata once it has been sent, received, or if either have failed (after this duration, a transferable will 404 if request) |
DBTRIMMER_POLL_EVERY |
200ms |
Maximum acceptable duration between the DBTrimmer receiving a SIGINT signal and the process' termination |
SENDER_RANGE_FILLER_CLASS |
UserRotatingTransferableRangeFiller |
Changes the Sender's Transferable fetch strategy. Available choices are UserRotatingTransferableRangeFiller (default, attempts to fairly distribute bandwidth for Transferables among Users) or FIFOTransferableRangeFiller (faster implementation that ignores User priority; good for single-user usages). |
REMOTE_USER_HEADER_AUTHENTICATION_ENABLED |
False |
Enable authentication through the HTTP header set by HTTP_X_REMOTE_USER |
REMOTE_USER_HEADER |
HTTP_X_REMOTE_USER |
Select the remote user authentication method, note the HTTP_ prefix for HTTP header based authentication |
THROTTLE_RATE |
30/second |
File upload rate limiting |
RECEIVER_BUFFER_MAX_ITEMS |
4 |
Maximum amount of incoming transferables awaiting processing that the receiver can hold before dropping incoming data. Should roughly match (MEM_LIMIT_RECEIVER / 2 * TRANSFERABLE_RANGE_SIZE ) |
CPUS_BACKEND |
See compose.prod.yml | CPU docker limit for each backend service |
CPUS_DATABASE |
See compose.prod.yml | CPU docker limit for database service |
CPUS_<CONTAINER_NAME> |
See compose.prod.yml | CPU docker limit |
MEM_LIMIT_BACKEND |
See compose.prod.yml | Memory docker limit for each backend service |
MEM_LIMIT_DATABASE |
See compose.prod.yml | Memory docker limit for database service |
MEM_LIMIT_<CONTAINER_NAME> |
See compose.prod.yml | Memory docker limit |
SHM_SIZE_DATABASE |
See compose.prod.yml | Shared memory docker limit for the database container |
EURYDICE_CONTACT |
See compose.prod.yml | Contact information, useful to report bugs for example. It is displayed in the API documentation. |
EURYDICE_CONTACT_FR |
See compose.prod.yml | Contact information in French. It is displayed in the frontend. |
UI_BADGE_CONTENT |
See compose.prod.yml | Configurable banner to be displayed on the front page in the frontend. |
UI_BADGE_COLOR |
See compose.prod.yml | Color for the configurable frontpage banner. List of available colors: https://vuetifyjs.com/en/styles/colors/#material-colors |
METRICS_SLIDING_WINDOW |
See compose.prod.yml | Duration used to compute metrics for /metrics endpoints. |
USER_ASSOCIATION_TOKEN_EXPIRES_AFTER |
See compose.prod.yml | Expiration delay of user association token. |
TRANSFERABLE_HISTORY_DURATION |
Duration of the history. | |
TRANSFERABLE_HISTORY_SEND_EVERY |
Frequency of the history. | |
HTTP_SERVICES_BIND_HOST |
127.0.0.1 | TCP bind address for docker services. |
Warning: make sure that DBTRIMMER_TRIM_TRANSFERABLES_AFTER
is greater than TRANSFERABLE_HISTORY_DURATION
.
If DBTRIMMER_TRIM_TRANSFERABLES_AFTER
is less than TRANSFERABLE_HISTORY_DURATION
, the DBTrimmer on the destination side will remove transferables that the history from the origin will recreate.
This will lead to previously deleted transferables being marked as ERROR
on the destination side.
In some cases, the origin-side database may end up holding millions of Transferable entries. Combined with a long history duration, this may lead to the sender generating enormous quantities of data, just to send the history.
If that happens, you may want to consider using a much smaller history duration, while keeping the same DBTRIMMER_TRIM_TRANSFERABLES_AFTER
. This will allow you to manually ask the sender to send a complete history only when needed, with the following command:
docker compose -f compose.prod.yml exec sender python manage.py send_history --duration 7days
The PUID
and PGID
variables must have read/write permissions on the directories defined in the other variables.
If MINIO_ENABLED
is false, Eurydice will attempt to use the filesystem as storage, instead of a remote s3 storage server. TRANSFERABLE_STORAGE_DIR
should be set to the path to a directory.
If LOG_TO_FILE
is true, Eurydice will write additional logs at ${PYTHON_LOGS_DIR}/<service>-logs/log.json
. This is useful when using a -with-elk-logging
profile, so that filebeat may read, process and share applicative logs to a remote elk server.
Eurydice needs to be setup behind a reverse proxy to work securely and optimally. Setting up a reverse proxy will also enable authentication at the reverse proxy level rather than relying on the application's authentication mechanism.
The application's services are exposed on localhost
by the compose.prod.yml
.
It is advised to route them like so:
- Web UI at
http://localhost:8888
- Should handle requests who don't match the rules for the services below
- API at
http://localhost:8080
- Should handle requests whose path is prefixed by
/api
/admin
/static
- Should handle requests whose path is prefixed by
- Minio at
http://localhost:9000
- Should handle requests whose path is prefixed by
/minio
(the/minio
prefix should be removed by the reverse proxy)
- Should handle requests whose path is prefixed by
- pgadmin at
http://localhost:5050
- Should handle requests whose path is prefixed by
/pgadmin
(the/pgadmin
prefix should be removed by the reverse proxy) - The reverse proxy should only allow authenticated users on this endpoint as all pgadmin authentication is disabled
- Should handle requests whose path is prefixed by
The reverse proxy should also serve all endpoints over TLS.
It should also set the X-Forwarded-Proto
, X-Forwarded-For
and X-Forwarded-Host
headers to forward information from the original request to the services.
Warning: django normalizes HTTP headers. So it is important to make sure that a user cannot forge an authentication HTTP header that would be considered safe by the reverse proxy, but would in fact be normalized by Django into a valid authentication header
This risk can be mitigated by configuring which header is used for authenticating the header with the REMOTE_USER_HEADER
variable.
This environment variable could for example be set to a purely alphanumeric value (not affected by normalization) which could not easily be guessed by the user.
In such a scenario, one would still need to make sure that the reverse proxy correctly prevents users from submitting their own authentication header.
Warning: Basic HTTP authentication passes your credentials over the network as clear text. As such, it is NOT the recommended method of authentication. If you need to run Eurydice using basic auth, at least use HTTPS.
In case you are unable to setup a reverse proxy and remote user authentication, Eurydice may support Basic HTTP Authentication.
Basic HTTP Authentication is enabled when the REMOTE_USER_HEADER_AUTHENTICATION_ENABLED
variable is set to false
.
If REMOTE_USER_HEADER_AUTHENTICATION_ENABLED
is set to false
the app won't use kerberos. Kerberos and basic auth cannot be used simultaneously.
To send applicative logs into an ELK you need an API key for a user with following role restrictions:
{
"filebeat_writer": {
"cluster": ["monitor", "read_ilm", "read_pipeline"],
"index": [
{
"names": ["eurydice-*"],
"privileges": ["view_index_metadata", "create_doc", "auto_configure"]
}
]
}
}