alyx-local 3.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ *.pyc
2
+ *__pycache__*
3
+ *.asv
4
+ *.pkl
5
+ *.patch
6
+ *.sql
7
+ *.html.py
8
+ *.orig
9
+ .venv*
10
+ .idea/*
11
+ .vscode/
12
+ .DS_Store
13
+ .pdm-python
14
+ .pdm-build/
15
+ .python-version
16
+ /compose.yaml
17
+ __pypackages__*
18
+ /src/alyx/data/management/commands/*ibl*
19
+ /src/alyx/templates/ibl_reports
20
+ /src/alyx/alyx/settings_secret.py
21
+ /src/alyx/alyx/settings_lab.py
22
+
23
+ /config
24
+ /data
25
+ /legacy
26
+
27
+ *secrets*
@@ -0,0 +1,47 @@
1
+ Metadata-Version: 2.4
2
+ Name: alyx-local
3
+ Version: 3.1.2
4
+ Summary: Local database for experimental neuroscience laboratories
5
+ Project-URL: source, https://github.com/JostTim/alyx-local
6
+ Project-URL: documentation, https://josttim.github.io/alyx-local/
7
+ Author-email: JostTim <timothe.jost-mousseau@pasteur.fr>
8
+ License: MIT
9
+ Requires-Python: <3.13,>=3.12
10
+ Requires-Dist: alyx-connector>=2.1.10
11
+ Requires-Dist: colorlog>=6.9.0
12
+ Requires-Dist: django-admin-list-filter-dropdown>=1.0.3
13
+ Requires-Dist: django-admin-rangefilter>=0.13.2
14
+ Requires-Dist: django-autocomplete-light>=3.11.0
15
+ Requires-Dist: django-cleanup>=9.0.0
16
+ Requires-Dist: django-crispy-forms>=2.3
17
+ Requires-Dist: django-dbbackup>=4.2.1
18
+ Requires-Dist: django-debug-toolbar>=6.0.0
19
+ Requires-Dist: django-filter>=24.3
20
+ Requires-Dist: django-jsoneditor>=0.2.4
21
+ Requires-Dist: django-markdownx>=4.0.7
22
+ Requires-Dist: django-mptt>=0.16.0
23
+ Requires-Dist: django-password-eye>=1.1.4
24
+ Requires-Dist: django-polymorphic>=3.1.0
25
+ Requires-Dist: django-reversion>=5.1.0
26
+ Requires-Dist: django-storages>=1.14.4
27
+ Requires-Dist: django-structlog>=8.1.0
28
+ Requires-Dist: django-stubs>=5.2.8
29
+ Requires-Dist: django-test-without-migrations>=0.6
30
+ Requires-Dist: django>=5.1.3
31
+ Requires-Dist: djangorestframework>=3.15.2
32
+ Requires-Dist: docutils>=0.21.2
33
+ Requires-Dist: drf-spectacular[sidecar]>=0.27.2
34
+ Requires-Dist: gunicorn>=23.0.0
35
+ Requires-Dist: inotify>=0.2.10
36
+ Requires-Dist: matplotlib>=3.9.2
37
+ Requires-Dist: platformdirs>=4.3.8
38
+ Requires-Dist: processing-pypelines[celery]>=0.0.66
39
+ Requires-Dist: psycopg2-binary>=2.9.10
40
+ Requires-Dist: pynwb>=3.1.2
41
+ Requires-Dist: rich-click>=1.8.9
42
+ Requires-Dist: structlog>=24.4.0
43
+ Requires-Dist: tzlocal>=5.2
44
+ Provides-Extra: celery
45
+ Requires-Dist: celery>=5.4.0; extra == 'celery'
46
+ Provides-Extra: docs
47
+ Requires-Dist: mkdocs-material>=9.6.11; extra == 'docs'
@@ -0,0 +1,121 @@
1
+ [project]
2
+ name = "alyx-local"
3
+ description = "Local database for experimental neuroscience laboratories"
4
+ requires-python = ">=3.12,<3.13"
5
+ dependencies = [
6
+ "django>=5.1.3",
7
+ "django-admin-list-filter-dropdown>=1.0.3",
8
+ "django-admin-rangefilter>=0.13.2",
9
+ "django-autocomplete-light>=3.11.0",
10
+ "django-cleanup>=9.0.0",
11
+ "django-filter>=24.3",
12
+ "django-jsoneditor>=0.2.4",
13
+ "django-markdownx>=4.0.7",
14
+ "django-password-eye>=1.1.4",
15
+ "django-mptt>=0.16.0",
16
+ "django-polymorphic>=3.1.0",
17
+ "django-reversion>=5.1.0",
18
+ "django-storages>=1.14.4",
19
+ "django-structlog>=8.1.0",
20
+ "django-test-without-migrations>=0.6",
21
+ "djangorestframework>=3.15.2",
22
+ "drf-spectacular[sidecar]>=0.27.2",
23
+ "django-dbbackup>=4.2.1",
24
+ "django-crispy-forms>=2.3",
25
+ "docutils>=0.21.2",
26
+ "gunicorn>=23.0.0",
27
+ "inotify>=0.2.10",
28
+ "tzlocal>=5.2",
29
+ "colorlog>=6.9.0",
30
+ "processing-pypelines[celery]>=0.0.66",
31
+ "structlog>=24.4.0",
32
+ "psycopg2-binary>=2.9.10",
33
+ "matplotlib>=3.9.2",
34
+ "alyx-connector>=2.1.10",
35
+ "rich-click>=1.8.9",
36
+ "platformdirs>=4.3.8",
37
+ "django-debug-toolbar>=6.0.0",
38
+ "pynwb>=3.1.2",
39
+ "django-stubs>=5.2.8",
40
+ ]
41
+ dynamic = ["version"]
42
+
43
+ [project.urls]
44
+ "source" = "https://github.com/JostTim/alyx-local"
45
+ "documentation" = "https://josttim.github.io/alyx-local/"
46
+
47
+ [project.license]
48
+ text = "MIT"
49
+
50
+ [[project.authors]]
51
+ name = "JostTim"
52
+ email = "timothe.jost-mousseau@pasteur.fr"
53
+
54
+ [project.optional-dependencies] # For actual installations
55
+ celery = ["celery>=5.4.0"]
56
+ docs = ["mkdocs-material>=9.6.11"]
57
+
58
+ [dependency-groups] # to use with CLI tools (for dev/CI only) https://packaging.python.org/en/latest/specifications/dependency-groups/
59
+ docs = ["mkdocs-material>=9.6.11"]
60
+ celery = ["celery>=5.4.0"]
61
+
62
+ [build-system]
63
+ requires = ["hatchling"]
64
+ build-backend = "hatchling.build"
65
+
66
+ [tool.hatch.version]
67
+ path = "src/alyx/__init__.py"
68
+ variable = "__version__"
69
+
70
+ [tool.hatch.build.targets.wheel]
71
+ packages = ["src/alyx"]
72
+
73
+ [tool.hatch.build]
74
+ include = ["src/alyx/ressources/*"]
75
+
76
+ [tool.wheel]
77
+ universal = true
78
+
79
+ [tool.flake8]
80
+ ignore = [
81
+ "E203",
82
+ "E117",
83
+ "E265",
84
+ "E266",
85
+ "E401",
86
+ "E704",
87
+ "E712",
88
+ "E731",
89
+ "E741",
90
+ "E722",
91
+ "F401",
92
+ "F403",
93
+ "F841",
94
+ "W504",
95
+ "W503",
96
+ "W605",
97
+ ]
98
+ max-line-length = 99
99
+ exclude = ["migrations"]
100
+
101
+ [tool.black]
102
+ preview = true
103
+ line-length = 99
104
+
105
+ [tool.coverage.run]
106
+ branch = false
107
+ source = ["src/alyx"]
108
+ omit = []
109
+
110
+ [tool.coverage.report]
111
+ exclude_lines = [
112
+ "pragma: no cover",
113
+ "raise AssertionError",
114
+ "raise NotImplementedError",
115
+ "pass",
116
+ "return$",
117
+ ]
118
+ show_missing = true
119
+
120
+ [project.scripts]
121
+ alyx = "alyx.installation.cli:alyx"
@@ -0,0 +1,12 @@
1
+ FROM python:3.12-slim AS base
2
+
3
+ # install uv for installing other python packages faster
4
+ RUN pip install uv
5
+
6
+ # Install flower and celery with uv (faster than pip) at system level (no venv)
7
+ RUN uv pip install flower pyamqp --system
8
+
9
+ CMD ["sh", \
10
+ "-c", \
11
+ "celery --broker=pyamqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672// \
12
+ flower --port=5001 --address=0.0.0.0 --basic_auth=${FLOWER_USER}:${FLOWER_PASSWORD} --url_prefix=services/celery"]
@@ -0,0 +1,4 @@
1
+ RABBITMQ_USER=%%RABBITMQ_USER%%
2
+ RABBITMQ_PASSWORD=%%RABBITMQ_PASSWORD%%
3
+ FLOWER_USER=%%RABBITMQ_USER%%
4
+ FLOWER_PASSWORD=%%RABBITMQ_PASSWORD%%
@@ -0,0 +1,115 @@
1
+ services:
2
+
3
+ django_server:
4
+ restart: on-failure:5
5
+ build:
6
+ context: .
7
+ dockerfile: ./django_server/Dockerfile
8
+ image: alyx_django_server:latest
9
+ container_name: django_server
10
+ hostname: 'django_server'
11
+ volumes :
12
+ - uploaded-data:/app/uploaded
13
+ - ./postgres_db/db-secure-password:/run/secrets/db-secure-password:ro
14
+ - "%%ALYX_SRC_PATH%%:/app/src/alyx:rw"
15
+ - "%%DJANGO_DATA_PATH%%:/app/data:rw"
16
+ environment :
17
+ - POSTGRES_PASSWORD_FILE=/run/secrets/db-secure-password
18
+ expose:
19
+ - 8000 # this is redirected through nginx, it is not directly exposed outside the docker network
20
+ cap_add:
21
+ - SYS_ADMIN
22
+ - DAC_READ_SEARCH
23
+ - CAP_DAC_READ_SEARCH
24
+ depends_on:
25
+ nginx_server:
26
+ condition: service_started
27
+ db:
28
+ condition: service_healthy
29
+
30
+
31
+ nginx_server:
32
+ image: nginx:latest
33
+ container_name: nginx_server
34
+ hostname: 'nginx_server'
35
+ ports:
36
+ - "0.0.0.0:%%NGINX_OUT_PORT%%:80"
37
+ volumes:
38
+ - uploaded-data:/app/uploaded
39
+ - ./nginx_server/nginx.conf:/etc/nginx/nginx.conf:ro
40
+ - ./nginx_server/502.html:/etc/nginx/errorpages/502.html:ro
41
+
42
+
43
+ db:
44
+ image: postgres:17
45
+ container_name: postgres_db
46
+ hostname: 'postgres_db'
47
+ restart: unless-stopped
48
+ user: postgres
49
+ volumes:
50
+ - db-data:/var/lib/postgresql/data
51
+ - ./postgres_db/db-secure-password:/run/secrets/db-secure-password:ro
52
+ environment:
53
+ - POSTGRES_DB=alyx
54
+ - POSTGRES_PASSWORD_FILE=/run/secrets/db-secure-password
55
+ expose:
56
+ - 5432 # this is for the access to postgres by django service, it is not exposed outside the docker network
57
+ healthcheck:
58
+ test: [ "CMD", "pg_isready" ]
59
+ interval: 10s
60
+ timeout: 5s
61
+ retries: 5
62
+
63
+ pgadmin:
64
+ image: dpage/pgadmin4
65
+ container_name: pgadmin
66
+ hostname: 'pgadmin'
67
+ environment:
68
+ - SCRIPT_NAME=/services/pgadmin
69
+ - PGADMIN_SERVER_JSON_FILE=/pgadmin4/servers.json
70
+ env_file:
71
+ - ./pgadmin/pgadmin.env
72
+ expose:
73
+ - 80 # this is for the management web interface of pgadmin to nginx, it is not exposed outside the docker network
74
+ volumes:
75
+ - pgadmin-data:/var/lib/pgadmin
76
+ - ./pgadmin/servers.json:/pgadmin4/servers.json:ro
77
+ depends_on:
78
+ db:
79
+ condition: service_healthy
80
+
81
+ rabbitmq:
82
+ image: rabbitmq:4-management
83
+ container_name: rabbitmq
84
+ hostname: 'rabbitmq'
85
+ ports:
86
+ - "0.0.0.0:%%RABBITMQ_OUT_PORT%%:5672"
87
+ expose :
88
+ - 15672 # this is for the management web interface of rabbitmq to nginx, it is not exposed outside the docker network
89
+ environment:
90
+ - RABBITMQ_MANAGEMENT_PATH_PREFIX=/services/rabbitmq
91
+ volumes:
92
+ - rabbitmq-data:/var/lib/rabbitmq
93
+ - ./rabbitmq/rabbitmq.conf:/etc/rabbitmq/rabbitmq.conf
94
+
95
+ celery_server:
96
+ build:
97
+ context: .
98
+ dockerfile: ./celery_server/Dockerfile
99
+ image: celery_flower:latest
100
+ container_name: celery_server
101
+ hostname: 'celery_server'
102
+ expose:
103
+ - 5001 # this is for the management web interface of celery to nginx, it is not exposed outside the docker network
104
+ - 5555 # this is for the management web interface of flower to nginx, it is not exposed outside the docker network
105
+ env_file:
106
+ - ./celery_server/celery.env
107
+ depends_on:
108
+ - rabbitmq
109
+
110
+
111
+ volumes:
112
+ pgadmin-data:
113
+ db-data:
114
+ rabbitmq-data:
115
+ uploaded-data:
@@ -0,0 +1,113 @@
1
+ # syntax=docker/dockerfile:1
2
+ ARG PYTHON_VERSION=3.12.3
3
+ ARG DEGUG=0
4
+ FROM python:${PYTHON_VERSION}-slim AS base
5
+
6
+ ARG APP_USER=%%PERMISIONED_USERNAME%%
7
+ ARG UID=%%PERMISSIONED_UID%%
8
+ ARG GID=%%PERMISSIONED_GID%%
9
+ ARG APP_GROUP=%%PERMISSIONED_GROUPNAME%%
10
+
11
+ RUN echo "Building the Docker image..."
12
+
13
+ # Prevents Python from writing pyc files.
14
+ ENV PYTHONDONTWRITEBYTECODE=${DEBUG}
15
+
16
+ # Keeps Python from buffering stdout and stderr to avoid situations where
17
+ # the application crashes without emitting any logs due to buffering.
18
+ ENV PYTHONUNBUFFERED=1
19
+
20
+ #########################################
21
+ # Create a non-root user to run the app #
22
+ RUN if ! getent group "${APP_GROUP}"; then \
23
+ addgroup --gid "${GID}" "${APP_GROUP}"; fi
24
+
25
+ RUN adduser \
26
+ --disabled-password \
27
+ --gecos "" \
28
+ --shell "/sbin/nologin" \
29
+ --home "/${APP_USER}" \
30
+ --uid "${UID}" \
31
+ --ingroup "${APP_GROUP}" \
32
+ "${APP_USER}"
33
+
34
+
35
+ # get pg_restore and other database tools #
36
+ #
37
+ RUN apt-get update && \
38
+ apt-get install -y --no-install-recommends \
39
+ # The list of packages that we install here :
40
+ ca-certificates wget gnupg2 lsb-release sudo iputils-ping curl dos2unix cifs-utils && \
41
+ # End of the list of packages
42
+ apt-get clean && \
43
+ rm -rf /var/lib/apt/lists/*
44
+
45
+ # Add postgresql repos to the keyring (to be able to install postgresql client connector with the right stable version)
46
+ RUN install -d -m 0755 /etc/apt/keyrings
47
+
48
+ RUN cat /etc/os-release >&2
49
+ RUN set -eux; . /etc/os-release; echo "ID=$ID VERSION_CODENAME=$VERSION_CODENAME" >&2
50
+
51
+ RUN wget -qO /etc/apt/keyrings/postgresql.asc https://www.postgresql.org/media/keys/ACCC4CF8.asc; \
52
+ echo "deb [signed-by=/etc/apt/keyrings/postgresql.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" \
53
+ > /etc/apt/sources.list.d/pgdg.list
54
+
55
+ RUN rm -rf /var/lib/apt/lists/* && apt-get update
56
+
57
+ RUN apt-get install -y --no-install-recommends \
58
+ postgresql-client-17 \
59
+ && apt-get clean \
60
+ && rm -rf /var/lib/apt/lists/*
61
+
62
+ ########################################################
63
+ # Install UV that will manage the python dependancies #
64
+ RUN pip install uv
65
+
66
+ #################################################################
67
+ ## Copy the django application source code into the container. ##
68
+ RUN mkdir -p /app/uploaded/static && \
69
+ mkdir -p /app/uploaded/media && \
70
+ mkdir -p /mnt/external_data
71
+
72
+ COPY ./pyproject.toml /app/pyproject.toml
73
+ COPY ./uv.lock /app/uv.lock
74
+ # copying uv.lock is to ensure that while we install dependancies, they are not updated
75
+ # (if the version pinning is "loose") compared to the lockfile, to avoid potential code break
76
+ # when using these dependancies in alyx's implementation
77
+
78
+ ################################################
79
+ ## ENSURE WE ACCESS THE ENTRYPOINT CORRECTLY ##
80
+ COPY ./django_server/entrypoint.sh /app/entrypoint.sh
81
+ COPY ./django_server/gunicorn.conf.py /app/gunicorn.conf.py
82
+
83
+ #############################################################################
84
+ ## ENSURE WE COPY CONFIG FILES GENERATED WITH INSTALL, IN PROPER LOCATIONS ##
85
+ COPY ./django_server/custom_settings.py /app/extra_configuration/custom_settings.py
86
+
87
+ ##################################################################
88
+ ## SET USER PERMISSIONS ON THE APP FOLDER AND ENTRYPOINT SCRIPT ##
89
+ RUN chown -R ${APP_USER}:${APP_GROUP} /app/
90
+
91
+ RUN dos2unix -o /app/entrypoint.sh
92
+ RUN chown ${APP_USER}:${APP_GROUP} /app/entrypoint.sh
93
+ RUN chmod +x /app/entrypoint.sh
94
+
95
+ ##########################################################################
96
+ ## Permissions to access the external_data folder on the mount location ##
97
+ RUN chown -R ${APP_USER}:${APP_GROUP} /mnt/external_data
98
+ RUN chmod -R 700 /mnt/external_data
99
+
100
+ #############################################################
101
+ RUN echo "${APP_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
102
+
103
+ #############################################################
104
+ # Switch to the non-privileged user to run the application. #
105
+ USER ${APP_USER}
106
+
107
+ WORKDIR /app
108
+
109
+ # Expose the port that the application listens on.
110
+ EXPOSE 80
111
+
112
+ RUN echo "Launching the entrypoint script..."
113
+ CMD ["./entrypoint.sh"]
@@ -0,0 +1,17 @@
1
+ ALLOWED_HOSTS = [%%MACHINE_ALLOWED_HOSTS%%]
2
+
3
+ CSRF_TRUSTED_ORIGINS = [%%MACHINE_CSRF_TRUSTED_ORIGINS%%]
4
+
5
+ DEFAULT_LAB_NAME = "defaultlab"
6
+
7
+ SECRET_KEY = "%%DJANGO_SECRET_KEY%%"
8
+
9
+ NARRATIVE_TEMPLATES = {}
10
+
11
+ DBBACKUP_HOSTNAME = "%%DB_BACKUP_HOSTNAME%%"
12
+
13
+ TIME_ZONE = "%%TIMEZONE%%"
14
+
15
+ DEBUG = %%DJANGO_DEBUG_MODE%%
16
+
17
+ AUTO_RESTORE_ON_STARTUP = %%AUTORESTORE_DJANGO_ON_STARTUP%%
@@ -0,0 +1,19 @@
1
+ #!/bin/bash
2
+ echo -n "Django version: " && echo -n $(uv run python -m django --version) && echo " is installed"
3
+
4
+ # pdm install --prod --frozen-lockfile
5
+ uv sync --all-groups
6
+
7
+ # Collect static files
8
+ echo "Collecting static files..."
9
+ uv run alyx manage collectstatic --noinput --clear --verbosity 0
10
+
11
+ uv run alyx manage auto_restore --use_settings --migrate_new_db
12
+
13
+ # Restore mounts
14
+ echo "Restoring all mounts if any"
15
+ uv run alyx manage mounts
16
+
17
+ # Start Gunicorn
18
+ echo "Starting Gunicorn to serve django alyx..."
19
+ uv run gunicorn 'alyx.base.wsgi' --config '/app/gunicorn.conf.py'
@@ -0,0 +1,7 @@
1
+ from pathlib import Path
2
+
3
+ bind = "0.0.0.0:8000"
4
+ workers = 3
5
+ reload = True
6
+ reload_engine = "inotify"
7
+ reload_extra_file = [str(dir / file) for dir, folders, files in Path("/app/src").walk() for file in files]
@@ -0,0 +1,79 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Service Unavailable</title>
5
+ <style>
6
+ @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap');
7
+ *:focus {
8
+ outline: none;
9
+ }
10
+ h1 {
11
+ text-align: center;
12
+ font-family: 'Roboto', sans-serif;
13
+ color: rgb(0, 164, 109);
14
+ }
15
+ h2 {
16
+ text-align: center;
17
+ font-family: 'Roboto', sans-serif;
18
+ font-weight: 600;
19
+ }
20
+ p {
21
+ text-align: center;
22
+ font-family: 'Roboto', sans-serif;
23
+ }
24
+ .icon {
25
+ display: block;
26
+ margin: 0 auto;
27
+ width: 50px;
28
+ height: 50px;
29
+ animation: spin 2s linear infinite;
30
+ color:rgb(0, 164, 109);
31
+ margin-top: 50px;
32
+ }
33
+ .block {
34
+ max-width:50vw;
35
+ box-shadow: 0px 0px 5px 5px rgba(185, 185, 185, 0.422);
36
+ border-radius: 5px;
37
+ padding : 50px;
38
+ padding-top: 30px;
39
+ cursor: pointer;
40
+ }
41
+ .block:active {
42
+ box-shadow: 0px 0px 4px 4px rgba(218, 218, 218, 0.422);
43
+ background-color: rgb(248, 248, 248);
44
+ }
45
+ body {
46
+ /* rest of your CSS */
47
+ display: flex;
48
+ justify-content: center;
49
+ align-items: center;
50
+ min-height: 100vh;
51
+ margin: 0;
52
+ }
53
+ @keyframes spin {
54
+ 0% { transform: rotate(0deg); }
55
+ 100% { transform: rotate(360deg); }
56
+ }
57
+ </style>
58
+ </head>
59
+ <body>
60
+ <div class="block" onclick="location.reload();">
61
+ <h2 >Error 502</h2>
62
+ <h1 >Alyx's Django server container is not yet fully started</h1>
63
+ <p>Please wait a bit and refresh this page, or look at logs or console to see if an error is preventing django's correct launch.</p>
64
+ <svg class="icon" fill="#007850" height="200px" width="200px" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 235.319 235.319" xmlns:xlink="http://www.w3.org/1999/xlink">
65
+ <g id="SVGRepo_bgCarrier" stroke-width="0"></g>
66
+ <g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g>
67
+ <g id="SVGRepo_iconCarrier">
68
+ <g>
69
+ <path d="m201.094,29.997c2.649-0.623 4.623-2.996 4.623-5.835v-18.162c0-3.313-2.687-6-6-6h-164.114c-3.313,0-6,2.687-6,6v18.163c0,2.839 1.974,5.212 4.623,5.835 1.812,32.314 18.594,61.928 45.682,80.076l11.324,7.586-11.324,7.586c-27.089,18.147-43.871,47.762-45.682,80.076-2.649,0.623-4.623,2.996-4.623,5.835v18.163c0,3.313 2.687,6 6,6h164.114c3.313,0 6-2.687 6-6v-18.163c0-2.839-1.974-5.212-4.623-5.835-1.812-32.314-18.594-61.928-45.683-80.076l-11.324-7.586 11.324-7.586c27.089-18.148 43.871-47.763 45.683-80.077zm-159.491-17.997h152.114v6.163h-152.114v-6.163zm152.114,211.319h-152.114v-6.163h152.114v6.163zm-63.749-110.644c-1.663,1.114-2.661,2.983-2.661,4.985s0.998,3.871 2.661,4.985l18.765,12.571c23.71,15.883 38.49,41.705 40.333,69.941h-142.812c1.843-28.235 16.623-54.057 40.333-69.941l18.765-12.571c1.663-1.114 2.661-2.983 2.661-4.985s-0.998-3.871-2.661-4.985l-18.765-12.571c-23.71-15.884-38.49-41.706-40.333-69.941h142.812c-1.843,28.236-16.623,54.057-40.333,69.941l-18.765,12.571z"></path>
70
+ <path d="m133.307,82.66h-31.295c-2.487,0-4.717,1.535-5.605,3.858-0.888,2.324-0.25,4.955 1.604,6.613l15.647,14c1.139,1.019 2.57,1.528 4,1.528s2.862-0.509 4-1.528l15.647-14c1.854-1.659 2.492-4.29 1.604-6.613-0.885-2.323-3.115-3.858-5.602-3.858z"></path>
71
+ <path d="m117.414,140.581l-15.218,9.775c-13.306,8.914-21.292,23.876-21.292,39.892h76.511c0-16.016-7.986-30.978-21.292-39.892l-15.218-9.775c-1.074-0.644-2.416-0.644-3.491,0z"></path>
72
+ </g>
73
+ </g>
74
+ </svg>
75
+ </div>
76
+ </body>
77
+ </html>
78
+
79
+
@@ -0,0 +1,95 @@
1
+ events {
2
+ }
3
+
4
+
5
+ http {
6
+ include /etc/nginx/mime.types;
7
+ # include /etc/nginx/conf.d/default.conf;
8
+ default_type application/octet-stream;
9
+
10
+ resolver 127.0.0.11 valid=30s; # Docker's internal DNS server
11
+
12
+ server {
13
+ listen %%NGINX_OUT_PORT%%;
14
+ listen [::]:%%NGINX_OUT_PORT%%;
15
+ server_name nginx_server;
16
+
17
+ location /static/ {
18
+ alias /app/uploaded/static/;
19
+ expires 30d;
20
+ }
21
+
22
+ location /media/ {
23
+ alias /app/uploaded/media/;
24
+ expires 30d;
25
+ }
26
+
27
+ location / {
28
+ set $upstream_django http://django_server:8000;
29
+ proxy_pass $upstream_django;
30
+ proxy_set_header Host $host;
31
+ proxy_set_header X-Real-IP $remote_addr;
32
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
33
+ proxy_set_header X-Forwarded-Proto $scheme;
34
+ }
35
+
36
+ error_page 502 /502.html;
37
+ location = /502.html {
38
+ root /etc/nginx/errorpages;
39
+ internal;
40
+ }
41
+
42
+ location /services/celery/ {
43
+
44
+ # using set variable allows this to make route to upstream_celery optional,
45
+ # and work even if it is not available at config time, but later on.
46
+ set $upstream_celery http://celery_server:5001/services/celery/;
47
+ rewrite ^/services/celery(.*) $1 break;
48
+ proxy_pass $upstream_celery;
49
+ proxy_set_header Host $host;
50
+ proxy_set_header X-Real-IP $remote_addr;
51
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
52
+ proxy_set_header X-Forwarded-Proto $scheme;
53
+
54
+ proxy_redirect / /services/celery/;
55
+
56
+ sub_filter_once off;
57
+ sub_filter_types text/html application/javascript;
58
+ sub_filter 'href="/' 'href="/services/celery/';
59
+ sub_filter 'src="/' 'src="/services/celery/';
60
+ sub_filter 'action="/' 'action="/services/celery/';
61
+ sub_filter 'url: "/' 'url: "/services/celery/';
62
+
63
+ }
64
+
65
+ location /services/rabbitmq/ {
66
+ set $upstream_rabbitmq http://rabbitmq:15672;
67
+ # rewrite ^/services/rabbitmq(.*) $1 break;
68
+ proxy_pass $upstream_rabbitmq;
69
+ proxy_set_header Host $host;
70
+ # proxy_set_header X-Forwarded-Prefix /services/rabbitmq;
71
+ # proxy_set_header X-Real-IP $remote_addr;
72
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
73
+ # proxy_set_header X-Script-Name /services/rabbitmq;
74
+ proxy_set_header X-Forwarded-Proto $scheme;
75
+
76
+ # proxy_redirect / /services/rabbitmq/;
77
+
78
+ # sub_filter_once off;
79
+ # sub_filter_types text/html application/javascript;
80
+ # sub_filter 'href="/' 'href="/services/rabbitmq/';
81
+ # sub_filter 'src="/' 'src="/services/rabbitmq/';
82
+ # sub_filter 'action="/' 'action="/services/rabbitmq/';
83
+ # sub_filter 'url: "/' 'url: "/services/rabbitmq/';
84
+ }
85
+
86
+ location /services/pgadmin/ {
87
+ set $upstream_rabbitmq http://pgadmin:80;
88
+ proxy_set_header X-Script-Name /services/pgadmin;
89
+ proxy_set_header Host $host;
90
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
91
+ proxy_pass $upstream_rabbitmq;
92
+ proxy_redirect off;
93
+ }
94
+ }
95
+ }
@@ -0,0 +1,2 @@
1
+ PGADMIN_DEFAULT_EMAIL=%%PGADMIN_DEFAULT_EMAIL%%
2
+ PGADMIN_DEFAULT_PASSWORD=%%PGADMIN_DEFAULT_PASSWORD%%
@@ -0,0 +1,13 @@
1
+ {
2
+ "Servers": {
3
+ "1": {
4
+ "Name": "PostgreSQL Database",
5
+ "Group": "Servers",
6
+ "Host": "postgres_db",
7
+ "Port": 5432,
8
+ "Username": "%%POSTGRES_DB_USERNAME%%",
9
+ "SSLMode": "prefer",
10
+ "MaintenanceDB": "alyx"
11
+ }
12
+ }
13
+ }