Skip to content

Commit 0b0e1c2

Browse files
committed
Merge branch 'docker-compose' into 'enterprise'
feat: Deploy using docker compose (PR 1/n) See merge request dkinternal/observability/dataops-observability!54
2 parents 87fefc9 + 4e9321d commit 0b0e1c2

8 files changed

Lines changed: 231 additions & 12 deletions

File tree

common/kubernetes/readiness_probe.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
import time
1515
from argparse import ArgumentParser, Namespace
1616
from contextlib import contextmanager
17+
from pathlib import Path
1718
from typing import NoReturn
1819
from collections.abc import Generator
1920
from collections.abc import Callable
2021

2122
LOG = logging.getLogger(__name__)
2223

23-
FILE_NAME = "observability_readyz"
24+
FILE_NAME = "{service}_readyz"
2425
"""Name of the file that will be created into the temp dir to mark the service as ready."""
2526

2627
POLLING_SLEEP_SECONDS = 0.1
@@ -34,19 +35,26 @@ class NotReadyException(Exception):
3435
"""Raised when the service shouldn't be marked as ready."""
3536

3637

37-
def _get_mark_file_path() -> str:
38-
return os.path.join(tempfile.gettempdir(), FILE_NAME)
38+
def _get_mark_file_path() -> Path:
39+
file_name = FILE_NAME.format(service=os.getenv("SUPERVISOR_PROCESS_NAME", "observability"))
40+
return Path(tempfile.gettempdir()) / file_name
3941

4042

4143
def set_ready() -> None:
4244
"""Mark the service as ready by adding a PID file to the temp dir."""
43-
with open(_get_mark_file_path(), "w") as mark_file:
44-
mark_file.write(str(os.getpid()))
45+
mark_file_path = _get_mark_file_path()
46+
mark_file_path.parent.mkdir(parents=True, exist_ok=True)
47+
mark_file_path.write_text(str(os.getpid()))
4548

4649

4750
def is_ready() -> bool:
4851
"""Checks the existence of the readiness mark file."""
49-
return os.path.exists(_get_mark_file_path())
52+
try:
53+
os.kill(int(_get_mark_file_path().read_text().strip()), 0)
54+
except (FileNotFoundError, ProcessLookupError, ValueError):
55+
return False
56+
else:
57+
return True
5058

5159

5260
@contextmanager

common/tests/unit/kubernetes/test_readiness_probe.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import os
12
from itertools import count
3+
from pathlib import Path
24
from unittest.mock import patch
35

46
import pytest
@@ -18,8 +20,16 @@ def set_ready_mock():
1820

1921
@pytest.mark.unit
2022
@patch.object(readiness_probe.tempfile, "gettempdir", return_value="/xpto")
21-
def test_get_filename(temp_dir_mock):
22-
assert readiness_probe._get_mark_file_path() == "/xpto/observability_readyz"
23+
@pytest.mark.parametrize(
24+
"env, expected",
25+
(
26+
({}, Path("/xpto/observability_readyz")),
27+
({"SUPERVISOR_PROCESS_NAME": "a_service"}, Path("/xpto/a_service_readyz")),
28+
),
29+
)
30+
def test_get_filename(temp_dir_mock, env, expected):
31+
with patch.dict(os.environ, env):
32+
assert readiness_probe._get_mark_file_path() == expected
2333
temp_dir_mock.assert_called_once()
2434

2535

conf/defaults.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
RULE_REFRESH_SECONDS: int = 30
22
"""Number of seconds to cache rules in rules engine"""
33

4-
54
MIGRATIONS_SRC_PATH = "/dk/lib/migrations"
65
"""Yoyo migrations source folder."""
76

deploy/conf/supervisord.conf

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
[supervisord]
2+
nodaemon=true
3+
user=observability
4+
logfile=/dev/stdout
5+
logfile_maxbytes = 0
6+
pidfile=/dk/var/supervisord.pid
7+
childlogdir=/dk/var/logs
8+
strip_ansi=false
9+
10+
; This section is only needed for the supervisorctl command to work
11+
[unix_http_server]
12+
file=/dk/var/supervisor.sock
13+
14+
; This section is only needed for the supervisorctl command to work
15+
[supervisorctl]
16+
serverurl=unix:///dk/var/supervisor.sock
17+
18+
; This section is only needed for the supervisorctl command to work
19+
[rpcinterface:supervisor]
20+
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
21+
22+
[program:scheduler]
23+
command=/dk/bin/scheduler
24+
directory=/dk
25+
autostart=true
26+
autorestart=true
27+
startsecs=2
28+
stopwaitsecs=30
29+
30+
[program:run_manager]
31+
command=/dk/bin/run-manager
32+
directory=/dk
33+
autostart=true
34+
autorestart=true
35+
startsecs=2
36+
stopwaitsecs=30
37+
38+
[program:rules_engine]
39+
command=/dk/bin/rules-engine
40+
directory=/dk
41+
autostart=true
42+
autorestart=true
43+
startsecs=2
44+
stopwaitsecs=30
45+
46+
[program:observability_api]
47+
command=/dk/bin/gunicorn -c /dk/gunicorn.conf.py --bind 0.0.0.0:5000 observability_api.app:app
48+
directory=/dk
49+
autostart=true
50+
autorestart=true
51+
startsecs=2
52+
stopwaitsecs=30
53+
54+
[program:event_api]
55+
command=/dk/bin/gunicorn -c /dk/gunicorn.conf.py --bind 0.0.0.0:5001 event_api.app:app
56+
directory=/dk
57+
autostart=true
58+
autorestart=true
59+
startsecs=2
60+
stopwaitsecs=30
61+
62+
[program:agent_api]
63+
command=/dk/bin/gunicorn -c /dk/gunicorn.conf.py --bind 0.0.0.0:5002 agent_api.app:app
64+
directory=/dk
65+
autostart=true
66+
autorestart=true
67+
startsecs=2
68+
stopwaitsecs=30
69+

deploy/docker-compose/compose.yaml

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
2+
x-database-config: &database_config
3+
MYSQL_USER: ${MYSQL_USER:-observability}
4+
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
5+
6+
x-database-client-config: &database_client_config
7+
MYSQL_SERVICE_HOST: ${MYSQL_HOST:-database}
8+
MYSQL_SERVICE_PORT: ${MYSQL_PORT:-3306}
9+
10+
services:
11+
broker:
12+
container_name: kafka
13+
image: apache/kafka:3.9.1
14+
restart: always
15+
expose: ["9092", "9093"]
16+
environment:
17+
# Core KRaft mode
18+
KAFKA_PROCESS_ROLES: broker,controller
19+
KAFKA_NODE_ID: 1
20+
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@broker:9093
21+
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
22+
# Networking
23+
KAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
24+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://broker:9092
25+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
26+
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
27+
KAFKA_LOG4J_LOGGER_kafka_server_DefaultAutoTopicCreationManager: WARN
28+
# Transactions
29+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
30+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
31+
# Other
32+
KAFKA_LOG4J_LOGGERS: "kafka=WARN,org.apache.kafka=WARN"
33+
volumes:
34+
- /var/lib/kafka/data
35+
healthcheck:
36+
test: [ "CMD", "/opt/kafka/bin/kafka-topics.sh", "--bootstrap-server", "localhost:9092", "--list" ]
37+
interval: 10s
38+
timeout: 5s
39+
retries: 5
40+
41+
database:
42+
container_name: mysql
43+
image: mysql:8.4
44+
restart: always
45+
expose: ["3306"]
46+
environment:
47+
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
48+
MYSQL_DATABASE: datakitchen
49+
<<: *database_config
50+
healthcheck:
51+
test: [ "CMD", "mysqladmin", "ping", "-h", "localhost" ]
52+
interval: 5s
53+
retries: 5
54+
55+
observability_data_init:
56+
container_name: data-init
57+
image: datakitchen/dataops-observability-be
58+
pull_policy: never
59+
restart: on-failure
60+
depends_on:
61+
database:
62+
condition: service_healthy
63+
broker:
64+
condition: service_healthy
65+
environment:
66+
OBSERVABILITY_CONFIG: minikube
67+
<<: [*database_config, *database_client_config]
68+
entrypoint: /bin/sh -c '/dk/bin/cli migrate'
69+
70+
observability_backend:
71+
container_name: back-end
72+
image: datakitchen/dataops-observability-be
73+
pull_policy: never
74+
restart: always
75+
depends_on:
76+
observability_data_init:
77+
condition: service_completed_successfully
78+
expose: ["5000", "5001", "5002"]
79+
environment:
80+
OBSERVABILITY_CONFIG: minikube
81+
KAFKA_SERVICE_HOST: ${KAFKA_HOST:-broker}
82+
KAFKA_SERVICE_PORT: ${KAFKA_PORT:-9092}
83+
<<: [*database_config, *database_client_config]
84+
healthcheck:
85+
test: [ "CMD", "/bin/sh", "-c", "supervisorctl -c /dk/supervisord.conf status | grep -q RUNNING" ]
86+
interval: 5s
87+
retries: 10
88+
volumes:
89+
- type: bind
90+
source: ../conf/supervisord.conf
91+
target: /dk/supervisord.conf
92+
93+
observability_ui:
94+
container_name: user-interface
95+
image: datakitchen/dataops-observability-ui
96+
pull_policy: never
97+
restart: always
98+
depends_on:
99+
observability_backend:
100+
condition: service_healthy
101+
environment:
102+
OBSERVABILITY_API_HOSTNAME: ${OBSERVABILITY_API_HOSTNAME}
103+
OBSERVABILITY_CSP_EXTRA: ${observability_csp_extra}
104+
links:
105+
- "observability_backend:observability-api"
106+
- "observability_backend:event-api"
107+
- "observability_backend:agent-api"
108+
ports:
109+
- "8080:8082"
110+
111+
networks:
112+
datakitchen:
113+
name: datakitchen-network
114+
external: true

deploy/docker-compose/config.env

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
MYSQL_ROOT_PASSWORD=mortadela
3+
# MYSQL_USER=observability
4+
MYSQL_PASSWORD=super-secret
5+
# MYSQL_HOST=
6+
# MYSQL_PORT=
7+
8+
# KAFKA_HOST=
9+
# KAFKA_PORT=
10+
11+
# OBSERVABILITY_API_HOSTNAME=
12+
# OBSERVABILITY_CSP_EXTRA=

deploy/docker/observability-be.dockerfile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,22 @@ RUN apk update && apk upgrade && apk add --no-cache librdkafka=2.10.0-r0
3838
# excess laying around in the final image.
3939
COPY --from=build-image /dk /dk
4040

41-
COPY --from=build-image /tmp/dk/deploy/conf/gunicorn.conf.py /tmp/dk/deploy/conf/yoyo.ini /dk/
41+
COPY --from=build-image \
42+
/tmp/dk/deploy/conf/gunicorn.conf.py \
43+
/tmp/dk/deploy/conf/yoyo.ini \
44+
/tmp/dk/deploy/conf/supervisord.conf \
45+
/dk/
46+
4247
COPY --from=build-image /tmp/dk/deploy/migrations/ /dk/lib/migrations/
4348

4449
ENV PYTHONPATH ${PYTHONPATH}:/dk/lib/python3.12/site-packages
4550
ENV PATH ${PATH}:/dk/bin
4651

4752
RUN addgroup -S observability && adduser -S observability -G observability
4853

49-
# gunicorn needs access to this folder
50-
RUN mkdir /dk/var
54+
RUN mkdir -p /dk/var/logs
5155
RUN chown -R observability:observability /dk/var
5256

5357
USER observability
58+
59+
ENTRYPOINT ["/dk/bin/supervisord", "-c", "/dk/supervisord.conf"]

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ dependencies = [
4343
"tomli==2.0.1",
4444
"WTForms==3.0.1",
4545
"yoyo-migrations==9.0.0",
46+
"supervisor==4.3.0",
4647
]
4748

4849
[project.optional-dependencies]

0 commit comments

Comments
 (0)