mirror of
https://github.com/coollabsio/coolify.git
synced 2026-03-11 08:55:47 +00:00
1737 lines
70 KiB
YAML
1737 lines
70 KiB
YAML
# documentation: https://posthog.com
|
|
# slogan: The single platform to analyze, test, observe, and deploy new features
|
|
# category: analytics
|
|
# tags: analytics, product, open-source, self-hosted, ab-testing, event-tracking
|
|
# logo: svgs/posthog.svg
|
|
# minversion: 4.0.0-beta.222
|
|
# port: 8000
|
|
|
|
services:
|
|
db:
|
|
image: postgres:15.12-alpine
|
|
environment:
|
|
- POSTGRES_USER=posthog
|
|
- POSTGRES_DB=posthog
|
|
- POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'pg_isready -U posthog']
|
|
interval: 5s
|
|
timeout: 30s
|
|
retries: 30
|
|
start_period: 10s
|
|
volumes:
|
|
- posthog-postgres-data:/var/lib/postgresql/data
|
|
|
|
redis:
|
|
image: redis:7.2-alpine
|
|
command: redis-server --maxmemory-policy allkeys-lru --maxmemory 500mb
|
|
healthcheck:
|
|
test: ['CMD', 'redis-cli', 'ping']
|
|
interval: 3s
|
|
timeout: 10s
|
|
retries: 10
|
|
volumes:
|
|
- posthog-redis-data:/data
|
|
|
|
zookeeper:
|
|
image: zookeeper:3.7.0
|
|
volumes:
|
|
- posthog-zookeeper-data:/data
|
|
- posthog-zookeeper-datalog:/datalog
|
|
- posthog-zookeeper-logs:/logs
|
|
|
|
clickhouse:
|
|
image: clickhouse/clickhouse-server:25.12.5.44
|
|
depends_on:
|
|
kafka:
|
|
condition: service_started
|
|
zookeeper:
|
|
condition: service_started
|
|
environment:
|
|
- CLICKHOUSE_SKIP_USER_SETUP=1
|
|
- KAFKA_HOSTS=kafka:9092
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1']
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 30
|
|
start_period: 30s
|
|
volumes:
|
|
- type: bind
|
|
source: ./clickhouse/config.xml
|
|
target: /etc/clickhouse-server/config.xml
|
|
read_only: true
|
|
content: |
|
|
<?xml version="1.0"?>
|
|
<!--
|
|
NOTE: User and query level settings are set up in "users.xml" file.
|
|
If you have accidentally specified user-level settings here, server won't start.
|
|
You can either move the settings to the right place inside "users.xml" file
|
|
or add <skip_check_for_incorrect_settings>1</skip_check_for_incorrect_settings> here.
|
|
-->
|
|
<clickhouse>
|
|
<logger>
|
|
<level>warning</level>
|
|
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
|
|
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
|
|
<size>1000M</size>
|
|
<count>10</count>
|
|
</logger>
|
|
|
|
<http_port>8123</http_port>
|
|
<mysql_port>9004</mysql_port>
|
|
<postgresql_port>9005</postgresql_port>
|
|
<https_port>8443</https_port>
|
|
<tcp_port_secure>9440</tcp_port_secure>
|
|
<interserver_http_port>9009</interserver_http_port>
|
|
<max_connections>4096</max_connections>
|
|
<keep_alive_timeout>3</keep_alive_timeout>
|
|
|
|
<openSSL>
|
|
<server>
|
|
<certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
|
|
<privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
|
|
<dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile>
|
|
<verificationMode>none</verificationMode>
|
|
<loadDefaultCAFile>true</loadDefaultCAFile>
|
|
<cacheSessions>true</cacheSessions>
|
|
<disableProtocols>sslv2,sslv3</disableProtocols>
|
|
<preferServerCiphers>true</preferServerCiphers>
|
|
</server>
|
|
|
|
<client>
|
|
<loadDefaultCAFile>true</loadDefaultCAFile>
|
|
<cacheSessions>true</cacheSessions>
|
|
<disableProtocols>sslv2,sslv3</disableProtocols>
|
|
<preferServerCiphers>true</preferServerCiphers>
|
|
<invalidCertificateHandler>
|
|
<name>RejectCertificateHandler</name>
|
|
</invalidCertificateHandler>
|
|
</client>
|
|
</openSSL>
|
|
|
|
<!-- Maximum number of concurrent queries. -->
|
|
<max_concurrent_queries>200</max_concurrent_queries>
|
|
|
|
<!-- Maximum memory usage (resident set size) for server process.
|
|
Zero value or unset means default. Default is "max_server_memory_usage_to_ram_ratio" of available
|
|
physical RAM.
|
|
If the value is larger than "max_server_memory_usage_to_ram_ratio" of available physical RAM, it
|
|
will be cut down.
|
|
|
|
The constraint is checked on query execution time.
|
|
If a query tries to allocate memory and the current memory usage plus allocation is greater
|
|
than specified threshold, exception will be thrown.
|
|
|
|
It is not practical to set this constraint to small values like just a few gigabytes,
|
|
because memory allocator will keep this amount of memory in caches and the server will deny service
|
|
of queries.
|
|
-->
|
|
<max_server_memory_usage>0</max_server_memory_usage>
|
|
|
|
<!-- Maximum number of threads in the Global thread pool.
|
|
This will default to a maximum of 10000 threads if not specified.
|
|
This setting will be useful in scenarios where there are a large number
|
|
of distributed queries that are running concurrently but are idling most
|
|
of the time, in which case a higher number of threads might be required.
|
|
-->
|
|
|
|
<background_message_broker_schedule_pool_size>10</background_message_broker_schedule_pool_size>
|
|
<max_thread_pool_size>10000</max_thread_pool_size>
|
|
|
|
<!-- how many threads merge files, default is 16 -->
|
|
<background_pool_size>4</background_pool_size>
|
|
|
|
<!-- Number of workers to recycle connections in background (see also drain_timeout).
|
|
If the pool is full, connection will be drained synchronously. -->
|
|
<!-- <max_threads_for_connection_collector>10</max_threads_for_connection_collector> -->
|
|
|
|
<!-- On memory constrained environments you may have to set this to value larger than 1.
|
|
-->
|
|
<max_server_memory_usage_to_ram_ratio>0.9</max_server_memory_usage_to_ram_ratio>
|
|
|
|
<!-- Simple server-wide memory profiler. Collect a stack trace at every peak allocation step (in
|
|
bytes).
|
|
Data will be stored in system.trace_log table with query_id = empty string.
|
|
Zero means disabled.
|
|
-->
|
|
<total_memory_profiler_step>4194304</total_memory_profiler_step>
|
|
|
|
<!-- Collect random allocations and deallocations and write them into system.trace_log with
|
|
'MemorySample' trace_type.
|
|
The probability is for every alloc/free regardless to the size of the allocation.
|
|
Note that sampling happens only when the amount of untracked memory exceeds the untracked memory
|
|
limit,
|
|
which is 4 MiB by default but can be lowered if 'total_memory_profiler_step' is lowered.
|
|
You may want to set 'total_memory_profiler_step' to 1 for extra fine grained sampling.
|
|
-->
|
|
<total_memory_tracker_sample_probability>0</total_memory_tracker_sample_probability>
|
|
|
|
<!-- Set limit on number of open files (default: maximum). This setting makes sense on Mac OS X
|
|
because getrlimit() fails to retrieve
|
|
correct maximum value. -->
|
|
<!-- <max_open_files>262144</max_open_files> -->
|
|
|
|
<!-- Size of cache of uncompressed blocks of data, used in tables of MergeTree family.
|
|
In bytes. Cache is single for server. Memory is allocated only on demand.
|
|
Cache is used when 'use_uncompressed_cache' user setting turned on (off by default).
|
|
Uncompressed cache is advantageous only for very short queries and in rare cases.
|
|
|
|
Note: uncompressed cache can be pointless for lz4, because memory bandwidth
|
|
is slower than multi-core decompression on some server configurations.
|
|
Enabling it can sometimes paradoxically make queries slower.
|
|
-->
|
|
<uncompressed_cache_size>8589934592</uncompressed_cache_size>
|
|
|
|
<!-- Approximate size of mark cache, used in tables of MergeTree family.
|
|
In bytes. Cache is single for server. Memory is allocated only on demand.
|
|
You should not lower this value.
|
|
-->
|
|
<mark_cache_size>5368709120</mark_cache_size>
|
|
|
|
<mmap_cache_size>1000</mmap_cache_size>
|
|
|
|
<!-- Cache size in bytes for compiled expressions.-->
|
|
<compiled_expression_cache_size>134217728</compiled_expression_cache_size>
|
|
|
|
<!-- Cache size in elements for compiled expressions.-->
|
|
<compiled_expression_cache_elements_size>10000</compiled_expression_cache_elements_size>
|
|
|
|
<!-- Path to data directory, with trailing slash. -->
|
|
<path>/var/lib/clickhouse/</path>
|
|
|
|
<!-- Path to temporary data for processing hard queries. -->
|
|
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
|
|
|
|
<!-- Directory with user provided files that are accessible by 'file' table function. -->
|
|
<user_files_path>/var/lib/clickhouse/user_files/</user_files_path>
|
|
|
|
<user_directories>
|
|
<users_xml>
|
|
<!-- Path to configuration file with predefined users. -->
|
|
<path>users.xml</path>
|
|
</users_xml>
|
|
<local_directory>
|
|
<!-- Path to folder where users created by SQL commands are stored. -->
|
|
<path>/var/lib/clickhouse/access/</path>
|
|
</local_directory>
|
|
|
|
</user_directories>
|
|
|
|
<default_profile>default</default_profile>
|
|
|
|
<custom_settings_prefixes></custom_settings_prefixes>
|
|
|
|
<default_database>default</default_database>
|
|
|
|
<mlock_executable>true</mlock_executable>
|
|
|
|
<!-- Reallocate memory for machine code ("text") using huge pages. Highly experimental. -->
|
|
<remap_executable>false</remap_executable>
|
|
|
|
<remote_url_allow_hosts>
|
|
<host_regexp>.*</host_regexp>
|
|
</remote_url_allow_hosts>
|
|
|
|
<zookeeper>
|
|
<node>
|
|
<host>zookeeper</host>
|
|
<port>2181</port>
|
|
</node>
|
|
</zookeeper>
|
|
|
|
<!-- Reloading interval for embedded dictionaries, in seconds. Default: 3600. -->
|
|
<builtin_dictionaries_reload_interval>3600</builtin_dictionaries_reload_interval>
|
|
|
|
<!-- Maximum session timeout, in seconds. Default: 3600. -->
|
|
<max_session_timeout>3600</max_session_timeout>
|
|
|
|
<!-- Default session timeout, in seconds. Default: 60. -->
|
|
<default_session_timeout>60</default_session_timeout>
|
|
|
|
<!-- Query log. Used only for queries with setting log_queries = 1. -->
|
|
<query_log>
|
|
<!-- What table to insert data. If table is not exist, it will be created.
|
|
When query log structure is changed after system update,
|
|
then old table will be renamed and new table will be created automatically.
|
|
-->
|
|
<database>system</database>
|
|
<table>query_log</table>
|
|
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
|
|
<!-- Interval of flushing data. -->
|
|
<flush_interval_milliseconds>500</flush_interval_milliseconds>
|
|
<!-- Maximal size in lines for the logs. When non-flushed logs amount reaches max_size, logs dumped to the disk. -->
|
|
<max_size_rows>8388608</max_size_rows>
|
|
<!-- Pre-allocated size in lines for the logs. -->
|
|
<reserved_size_rows>8192</reserved_size_rows>
|
|
<!-- Lines amount threshold, reaching it launches flushing logs to the disk in background. -->
|
|
<buffer_size_rows_flush_threshold>524288</buffer_size_rows_flush_threshold>
|
|
<!-- Indication whether logs should be dumped to the disk in case of a crash -->
|
|
<flush_on_crash>true</flush_on_crash>
|
|
|
|
<!-- example of using a different storage policy for a system table -->
|
|
<!-- storage_policy>local_ssd</storage_policy -->
|
|
|
|
<ttl>event_date + INTERVAL 12 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</query_log>
|
|
|
|
<!-- Query thread log. Has information about all threads participated in query execution.
|
|
Used only for queries with setting log_query_threads = 1. -->
|
|
<query_thread_log>
|
|
<database>system</database>
|
|
<table>query_thread_log</table>
|
|
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
<max_size_rows>8388608</max_size_rows>
|
|
<reserved_size_rows>8192</reserved_size_rows>
|
|
<buffer_size_rows_flush_threshold>524288</buffer_size_rows_flush_threshold>
|
|
<flush_on_crash>false</flush_on_crash>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</query_thread_log>
|
|
|
|
<!-- Query views log. Has information about all dependent views associated with a query.
|
|
Used only for queries with setting log_query_views = 1. -->
|
|
<query_views_log>
|
|
<database>system</database>
|
|
<table>query_views_log</table>
|
|
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</query_views_log>
|
|
|
|
|
|
<text_log>
|
|
<database>system</database>
|
|
<table>text_log</table>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
<level>trace</level>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</text_log>
|
|
|
|
<!-- Metric log contains rows with current values of ProfileEvents, CurrentMetrics collected
|
|
with "collect_interval_milliseconds" interval. -->
|
|
<metric_log>
|
|
<database>system</database>
|
|
<table>metric_log</table>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
<collect_interval_milliseconds>1000</collect_interval_milliseconds>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</metric_log>
|
|
|
|
<!--
|
|
Asynchronous metric log contains values of metrics from
|
|
system.asynchronous_metrics.
|
|
-->
|
|
<asynchronous_metric_log>
|
|
<database>system</database>
|
|
<table>asynchronous_metric_log</table>
|
|
<!--
|
|
Asynchronous metrics are updated once a minute, so there is
|
|
no need to flush more often.
|
|
-->
|
|
<flush_interval_milliseconds>7000</flush_interval_milliseconds>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</asynchronous_metric_log>
|
|
|
|
<!--
|
|
OpenTelemetry log contains OpenTelemetry trace spans.
|
|
-->
|
|
<opentelemetry_span_log>
|
|
<!--
|
|
The default table creation code is insufficient, this <engine> spec
|
|
is a workaround. There is no 'event_time' for this log, but two times,
|
|
start and finish. It is sorted by finish time, to avoid inserting
|
|
data too far away in the past (probably we can sometimes insert a span
|
|
that is seconds earlier than the last span in the table, due to a race
|
|
between several spans inserted in parallel). This gives the spans a
|
|
global order that we can use to e.g. retry insertion into some external
|
|
system.
|
|
-->
|
|
<engine>
|
|
engine MergeTree
|
|
partition by toYYYYMM(finish_date)
|
|
order by (finish_date, finish_time_us, trace_id)
|
|
</engine>
|
|
<database>system</database>
|
|
<table>opentelemetry_span_log</table>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
</opentelemetry_span_log>
|
|
|
|
|
|
<!-- Crash log. Stores stack traces for fatal errors.
|
|
This table is normally empty. -->
|
|
<crash_log>
|
|
<database>system</database>
|
|
<table>crash_log</table>
|
|
|
|
<partition_by />
|
|
<flush_interval_milliseconds>1000</flush_interval_milliseconds>
|
|
<max_size_rows>1024</max_size_rows>
|
|
<reserved_size_rows>1024</reserved_size_rows>
|
|
<buffer_size_rows_flush_threshold>512</buffer_size_rows_flush_threshold>
|
|
<flush_on_crash>true</flush_on_crash>
|
|
</crash_log>
|
|
|
|
<!-- Session log. Stores user log in (successful or not) and log out events. -->
|
|
<session_log>
|
|
<database>system</database>
|
|
<table>session_log</table>
|
|
|
|
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</session_log>
|
|
|
|
<backup_log>
|
|
<database>system</database>
|
|
<table>backup_log</table>
|
|
<partition_by>toYYYYMM(event_date)</partition_by>
|
|
<flush_interval_milliseconds>7500</flush_interval_milliseconds>
|
|
|
|
<ttl>event_date + INTERVAL 5 DAY</ttl>
|
|
<ttl_only_drop_parts>1</ttl_only_drop_parts>
|
|
</backup_log>
|
|
|
|
<!-- Custom TLD lists.
|
|
Format: <name>/path/to/file</name>
|
|
|
|
Changes will not be applied w/o server restart.
|
|
Path to the list is under top_level_domains_path (see above).
|
|
-->
|
|
<top_level_domains_lists>
|
|
<!--
|
|
<public_suffix_list>/path/to/public_suffix_list.dat</public_suffix_list>
|
|
-->
|
|
</top_level_domains_lists>
|
|
|
|
<!-- Configuration of external dictionaries. See:
|
|
https://clickhouse.com/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts
|
|
-->
|
|
<dictionaries_config>*_dictionary.xml</dictionaries_config>
|
|
|
|
<!-- Configuration of user defined executable functions -->
|
|
<user_defined_executable_functions_config>*_function.xml</user_defined_executable_functions_config>
|
|
|
|
<distributed_ddl>
|
|
<!-- Path in ZooKeeper to queue with DDL queries -->
|
|
<path>/clickhouse/task_queue/ddl</path>
|
|
</distributed_ddl>
|
|
|
|
<!-- Example of parameters for GraphiteMergeTree table engine -->
|
|
<graphite_rollup_example>
|
|
<pattern>
|
|
<regexp>click_cost</regexp>
|
|
<function>any</function>
|
|
<retention>
|
|
<age>0</age>
|
|
<precision>3600</precision>
|
|
</retention>
|
|
<retention>
|
|
<age>86400</age>
|
|
<precision>60</precision>
|
|
</retention>
|
|
</pattern>
|
|
<default>
|
|
<function>max</function>
|
|
<retention>
|
|
<age>0</age>
|
|
<precision>60</precision>
|
|
</retention>
|
|
<retention>
|
|
<age>3600</age>
|
|
<precision>300</precision>
|
|
</retention>
|
|
<retention>
|
|
<age>86400</age>
|
|
<precision>3600</precision>
|
|
</retention>
|
|
</default>
|
|
</graphite_rollup_example>
|
|
|
|
<!-- Directory in <clickhouse-path> containing schema files for various input formats.
|
|
The directory will be created if it doesn't exist.
|
|
-->
|
|
<format_schema_path>/var/lib/clickhouse/format_schemas/</format_schema_path>
|
|
|
|
<!-- Default query masking rules, matching lines would be replaced with something else in the
|
|
logs
|
|
(both text logs and system.query_log).
|
|
name - name for the rule (optional)
|
|
regexp - RE2 compatible regular expression (mandatory)
|
|
replace - substitution string for sensitive data (optional, by default - six asterisks)
|
|
-->
|
|
<query_masking_rules>
|
|
<rule>
|
|
<name>hide encrypt/decrypt arguments</name>
|
|
<regexp>((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\\'|.)+'|.*?)\s*\)</regexp>
|
|
<!-- or more secure, but also more invasive:
|
|
(aes_\w+)\s*\(.*\)
|
|
-->
|
|
<replace>\1(???)</replace>
|
|
</rule>
|
|
</query_masking_rules>
|
|
|
|
<merge_tree>
|
|
<max_bytes_to_merge_at_max_space_in_pool>1073741824</max_bytes_to_merge_at_max_space_in_pool>
|
|
<number_of_free_entries_in_pool_to_execute_mutation>2</number_of_free_entries_in_pool_to_execute_mutation>
|
|
<number_of_free_entries_in_pool_to_execute_optimize_entire_partition>2</number_of_free_entries_in_pool_to_execute_optimize_entire_partition>
|
|
</merge_tree>
|
|
</clickhouse>
|
|
- type: bind
|
|
source: ./clickhouse/users.xml
|
|
target: /etc/clickhouse-server/users.xml
|
|
read_only: true
|
|
content: |
|
|
<?xml version="1.0"?>
|
|
<yandex>
|
|
<!-- See also the files in users.d directory where the settings can be overridden. -->
|
|
|
|
<!-- Profiles of settings. -->
|
|
<profiles>
|
|
<!-- Default settings. -->
|
|
<default>
|
|
<!-- Maximum memory usage for processing single query, in bytes. -->
|
|
<max_memory_usage>10000000000</max_memory_usage>
|
|
|
|
|
|
<!-- How to choose between replicas during distributed query processing.
|
|
random - choose random replica from set of replicas with minimum number of errors
|
|
nearest_hostname - from set of replicas with minimum number of errors, choose replica
|
|
with minimum number of different symbols between replica's hostname and local hostname
|
|
(Hamming distance).
|
|
in_order - first live replica is chosen in specified order.
|
|
first_or_random - if first replica one has higher number of errors, pick a random one from replicas
|
|
with minimum number of errors.
|
|
-->
|
|
<load_balancing>random</load_balancing>
|
|
|
|
<allow_nondeterministic_mutations>1</allow_nondeterministic_mutations>
|
|
|
|
<enable_analyzer>0</enable_analyzer>
|
|
<compatibility>25.6</compatibility>
|
|
<distributed_product_mode>global</distributed_product_mode>
|
|
<enable_parallel_replicas>0</enable_parallel_replicas>
|
|
<max_parallel_replicas>1</max_parallel_replicas>
|
|
<allow_experimental_window_functions>1</allow_experimental_window_functions>
|
|
<allow_suspicious_low_cardinality_types>1</allow_suspicious_low_cardinality_types>
|
|
<insert_distributed_sync>1</insert_distributed_sync>
|
|
<throw_on_max_partitions_per_insert_block>false</throw_on_max_partitions_per_insert_block>
|
|
<number_of_mutations_to_throw>1</number_of_mutations_to_throw>
|
|
|
|
</default>
|
|
|
|
<!-- Profile that allows only read queries. -->
|
|
<readonly>
|
|
<readonly>1</readonly>
|
|
</readonly>
|
|
|
|
<api>
|
|
<profile>default</profile>
|
|
</api>
|
|
|
|
<app>
|
|
<profile>default</profile>
|
|
</app>
|
|
|
|
</profiles>
|
|
|
|
<!-- Users and ACL. -->
|
|
<users>
|
|
<!-- If user name was not specified, 'default' user is used. -->
|
|
<default>
|
|
<!-- See also the files in users.d directory where the password can be overridden.
|
|
|
|
Password could be specified in plaintext or in SHA256 (in hex format).
|
|
|
|
If you want to specify password in plaintext (not recommended), place it in 'password' element.
|
|
Example: <password>qwerty</password>.
|
|
Password could be empty.
|
|
|
|
If you want to specify SHA256, place it in 'password_sha256_hex' element.
|
|
Example:
|
|
<password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>
|
|
Restrictions of SHA256: impossibility to connect to ClickHouse using MySQL JS client (as of July
|
|
2019).
|
|
|
|
If you want to specify double SHA1, place it in 'password_double_sha1_hex' element.
|
|
Example:
|
|
<password_double_sha1_hex>e395796d6546b1b65db9d665cd43f0e858dd4303</password_double_sha1_hex>
|
|
|
|
If you want to specify a previously defined LDAP server (see 'ldap_servers' in the main config) for
|
|
authentication,
|
|
place its name in 'server' element inside 'ldap' element.
|
|
Example: <ldap><server>my_ldap_server</server></ldap>
|
|
|
|
If you want to authenticate the user via Kerberos (assuming Kerberos is enabled, see 'kerberos' in
|
|
the main config),
|
|
place 'kerberos' element instead of 'password' (and similar) elements.
|
|
The name part of the canonical principal name of the initiator must match the user name for
|
|
authentication to succeed.
|
|
You can also place 'realm' element inside 'kerberos' element to further restrict authentication to
|
|
only those requests
|
|
whose initiator's realm matches it.
|
|
Example: <kerberos />
|
|
Example: <kerberos><realm>EXAMPLE.COM</realm></kerberos>
|
|
|
|
How to generate decent password:
|
|
Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" |
|
|
sha256sum | tr -d '-'
|
|
In first line will be password and in second - corresponding SHA256.
|
|
|
|
How to generate double SHA1:
|
|
Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" |
|
|
sha1sum | tr -d '-' | xxd -r -p | sha1sum | tr -d '-'
|
|
In first line will be password and in second - corresponding double SHA1.
|
|
-->
|
|
<password></password>
|
|
|
|
<!-- List of networks with open access.
|
|
|
|
To open access from everywhere, specify:
|
|
<ip>::/0</ip>
|
|
|
|
To open access only from localhost, specify:
|
|
<ip>::1</ip>
|
|
<ip>127.0.0.1</ip>
|
|
|
|
Each element of list has one of the following forms:
|
|
<ip> IP-address or network mask. Examples: 213.180.204.3 or 10.0.0.1/8 or 10.0.0.1/255.255.255.0
|
|
2a02:6b8::3 or 2a02:6b8::3/64 or 2a02:6b8::3/ffff:ffff:ffff:ffff::.
|
|
<host> Hostname. Example: server01.yandex.ru.
|
|
To check access, DNS query is performed, and all received addresses compared to peer address.
|
|
<host_regexp> Regular expression for host names. Example, ^server\d\d-\d\d-\d\.yandex\.ru$
|
|
To check access, DNS PTR query is performed for peer address and then regexp is applied.
|
|
Then, for result of PTR query, another DNS query is performed and all received addresses compared
|
|
to peer address.
|
|
Strongly recommended that regexp is ends with $
|
|
All results of DNS requests are cached till server restart.
|
|
-->
|
|
<networks>
|
|
<ip>::/0</ip>
|
|
</networks>
|
|
|
|
<!-- Settings profile for user. -->
|
|
<profile>default</profile>
|
|
|
|
<!-- Quota for user. -->
|
|
<quota>default</quota>
|
|
|
|
<!-- User can create other users and grant rights to them. -->
|
|
<access_management>1</access_management>
|
|
<named_collection_control>1</named_collection_control>
|
|
<show_named_collections>1</show_named_collections>
|
|
<show_named_collections_secrets>1</show_named_collections_secrets>
|
|
</default>
|
|
|
|
<api>
|
|
<password>apipass</password>
|
|
|
|
<networks>
|
|
<ip>::/0</ip>
|
|
</networks>
|
|
|
|
<profile>api</profile>
|
|
|
|
<quota>default</quota>
|
|
</api>
|
|
|
|
<app>
|
|
<password>apppass</password>
|
|
|
|
<networks>
|
|
<ip>::/0</ip>
|
|
</networks>
|
|
|
|
<profile>app</profile>
|
|
|
|
<quota>default</quota>
|
|
</app>
|
|
</users>
|
|
|
|
<!-- Quotas. -->
|
|
<quotas>
|
|
<!-- Name of quota. -->
|
|
<default>
|
|
<!-- Limits for time interval. You could specify many intervals with different limits. -->
|
|
<interval>
|
|
<!-- Length of interval. -->
|
|
<duration>3600</duration>
|
|
|
|
<!-- No limits. Just calculate resource usage for time interval. -->
|
|
<queries>0</queries>
|
|
<errors>0</errors>
|
|
<result_rows>0</result_rows>
|
|
<read_rows>0</read_rows>
|
|
<execution_time>0</execution_time>
|
|
</interval>
|
|
</default>
|
|
</quotas>
|
|
</yandex>
|
|
- type: bind
|
|
source: ./clickhouse/config.d/default.xml
|
|
target: /etc/clickhouse-server/config.d/default.xml
|
|
read_only: true
|
|
content: |
|
|
<clickhouse>
|
|
<tcp_port>9000</tcp_port>
|
|
|
|
<remote_servers>
|
|
<posthog>
|
|
<shard>
|
|
<replica>
|
|
<host>clickhouse</host>
|
|
<port>9000</port>
|
|
</replica>
|
|
</shard>
|
|
</posthog>
|
|
<posthog_single_shard>
|
|
<shard>
|
|
<replica>
|
|
<host>clickhouse</host>
|
|
<port>9000</port>
|
|
</replica>
|
|
</shard>
|
|
</posthog_single_shard>
|
|
<posthog_migrations>
|
|
<shard>
|
|
<replica>
|
|
<host>clickhouse</host>
|
|
<port>9000</port>
|
|
</replica>
|
|
</shard>
|
|
</posthog_migrations>
|
|
<posthog_writable>
|
|
<shard>
|
|
<replica>
|
|
<host>clickhouse</host>
|
|
<port>9000</port>
|
|
</replica>
|
|
</shard>
|
|
</posthog_writable>
|
|
<posthog_primary_replica>
|
|
<shard>
|
|
<replica>
|
|
<host>clickhouse</host>
|
|
<port>9000</port>
|
|
</replica>
|
|
</shard>
|
|
</posthog_primary_replica>
|
|
</remote_servers>
|
|
|
|
<named_collections>
|
|
<msk_cluster>
|
|
<kafka_broker_list from_env="KAFKA_HOSTS"/>
|
|
</msk_cluster>
|
|
<warpstream_ingestion>
|
|
<kafka_broker_list from_env="KAFKA_HOSTS"/>
|
|
</warpstream_ingestion>
|
|
</named_collections>
|
|
|
|
<macros>
|
|
<shard>01</shard>
|
|
<replica>ch1</replica>
|
|
<hostClusterType>online</hostClusterType>
|
|
<hostClusterRole>data</hostClusterRole>
|
|
</macros>
|
|
</clickhouse>
|
|
- type: bind
|
|
source: ./clickhouse/user_defined_function.xml
|
|
target: /etc/clickhouse-server/user_defined_function.xml
|
|
read_only: true
|
|
content: |
|
|
<functions>
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel</name>
|
|
<return_type>Array(Tuple(Int8, Nullable(String), Array(Float64), Array(Array(UUID)), UInt32))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Nullable(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Int8)</type>
|
|
<name>optional_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel steps</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_cohort</name>
|
|
<return_type>Array(Tuple(Int8, UInt64, Array(Float64), Array(Array(UUID)), UInt32))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(UInt64)</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Int8)</type>
|
|
<name>optional_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UUID, UInt64, Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel steps</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_array</name>
|
|
<return_type>Array(Tuple(Int8, Array(String), Array(Float64), Array(Array(UUID)), UInt32))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Array(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Int8)</type>
|
|
<name>optional_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UUID, Array(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel steps</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_test</name>
|
|
<return_type>String</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Array(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Int8)</type>
|
|
<name>optional_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UUID, Nullable(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel_test.py</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_trends</name>
|
|
<return_type>Array(Tuple(UInt64, Int8, Nullable(String), UUID))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>from_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>to_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Nullable(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UInt64, UUID, Nullable(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel trends</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_array_trends</name>
|
|
<!-- Return type for trends is a start interval time, a success flag (1 or -1), and a breakdown value -->
|
|
<return_type>Array(Tuple(UInt64, Int8, Array(String), UUID))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>from_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>to_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Array(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UInt64, UUID, Array(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel trends</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_cohort_trends</name>
|
|
<!-- Return type for trends is a start interval time, a success flag (1 or -1), and a breakdown value -->
|
|
<return_type>Array(Tuple(UInt64, Int8, UInt64, UUID))</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>from_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>to_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(UInt64)</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UInt64, UUID, UInt64, Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel trends</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
|
|
<function>
|
|
<type>executable_pool</type>
|
|
<name>aggregate_funnel_array_trends_test</name>
|
|
<return_type>String</return_type>
|
|
<return_name>result</return_name>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>from_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>to_step</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt8</type>
|
|
<name>num_steps</name>
|
|
</argument>
|
|
<argument>
|
|
<type>UInt64</type>
|
|
<name>conversion_window_limit</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>breakdown_attribution_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>String</type>
|
|
<name>funnel_order_type</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Array(String))</type>
|
|
<name>prop_vals</name>
|
|
</argument>
|
|
<argument>
|
|
<type>Array(Tuple(Nullable(Float64), UInt64, UUID, Array(String), Array(Int8)))</type>
|
|
<name>value</name>
|
|
</argument>
|
|
<format>JSONEachRow</format>
|
|
<command>aggregate_funnel_array_trends_test.py</command>
|
|
<lifetime>600</lifetime>
|
|
</function>
|
|
</functions>
|
|
- posthog-clickhouse-data:/var/lib/clickhouse
|
|
|
|
# Workaround for ClickHouse crash_log table not existing on fresh installs.
|
|
# See: https://github.com/PostHog/posthog/issues/40300
|
|
clickhouse-init:
|
|
image: alpine:3.19
|
|
entrypoint: /bin/sh
|
|
command:
|
|
- '-c'
|
|
- |
|
|
apk add --no-cache curl
|
|
until curl -sf http://clickhouse:8123/ping >/dev/null 2>&1; do sleep 2; done
|
|
curl -sf 'http://clickhouse:8123/' --data "CREATE TABLE IF NOT EXISTS system.crash_log (hostname LowCardinality(String) DEFAULT hostName(), event_date Date, event_time DateTime, timestamp_ns UInt64, signal Int32, thread_id UInt64, query_id String, trace Array(UInt64), trace_full Array(String), version String, revision UInt32, build_id String) ENGINE = MergeTree ORDER BY (event_date, event_time) TTL event_date + INTERVAL 30 DAY"
|
|
depends_on:
|
|
clickhouse:
|
|
condition: service_healthy
|
|
restart: 'no'
|
|
|
|
kafka:
|
|
image: docker.redpanda.com/redpandadata/redpanda:v25.1.9
|
|
command:
|
|
- redpanda
|
|
- start
|
|
- '--kafka-addr internal://0.0.0.0:9092'
|
|
- '--advertise-kafka-addr internal://kafka:9092'
|
|
- '--pandaproxy-addr internal://0.0.0.0:8082'
|
|
- '--advertise-pandaproxy-addr internal://kafka:8082'
|
|
- '--schema-registry-addr internal://0.0.0.0:8081'
|
|
- '--rpc-addr kafka:33145'
|
|
- '--advertise-rpc-addr kafka:33145'
|
|
- '--mode dev-container'
|
|
- '--smp 1'
|
|
- '--memory 1500M'
|
|
- '--reserve-memory 200M'
|
|
- '--overprovisioned'
|
|
- '--set redpanda.empty_seed_starts_cluster=false'
|
|
- '--seeds kafka:33145'
|
|
- '--set redpanda.auto_create_topics_enabled=true'
|
|
environment:
|
|
- ALLOW_PLAINTEXT_LISTENER=true
|
|
healthcheck:
|
|
test: curl -f http://localhost:9644/v1/status/ready || exit 1
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 30
|
|
start_period: 30s
|
|
volumes:
|
|
- posthog-kafka-data:/var/lib/redpanda/data
|
|
|
|
kafka-init:
|
|
image: docker.redpanda.com/redpandadata/redpanda:v25.1.9
|
|
entrypoint: /bin/sh
|
|
command:
|
|
- '-c'
|
|
- |
|
|
TIMEOUT=120
|
|
ELAPSED=0
|
|
until rpk topic list --brokers kafka:9092 2>/dev/null; do
|
|
sleep 3
|
|
ELAPSED=$$((ELAPSED + 3))
|
|
if [ $$ELAPSED -ge $$TIMEOUT ]; then exit 1; fi
|
|
done
|
|
for topic in exceptions_ingestion clickhouse_events_json events_plugin_ingestion; do
|
|
rpk topic create "$$topic" --brokers kafka:9092 -p 1 -r 1 2>&1 || true
|
|
done
|
|
depends_on:
|
|
kafka:
|
|
condition: service_healthy
|
|
restart: 'no'
|
|
|
|
objectstorage:
|
|
image: minio/minio:RELEASE.2025-04-22T22-12-26Z
|
|
environment:
|
|
- MINIO_ROOT_USER=${SERVICE_USER_MINIO}
|
|
- MINIO_ROOT_PASSWORD=${SERVICE_PASSWORD_MINIO}
|
|
entrypoint: sh
|
|
command: -c 'mkdir -p /data/posthog && minio server --address ":19000" --console-address ":19001" /data'
|
|
volumes:
|
|
- posthog-objectstorage:/data
|
|
|
|
seaweedfs:
|
|
image: chrislusf/seaweedfs:4.03
|
|
entrypoint:
|
|
- /bin/sh
|
|
- '-c'
|
|
- |
|
|
/usr/bin/weed "$$@" &
|
|
WEED_PID=$$!
|
|
while true; do
|
|
sleep 5
|
|
if echo "s3.bucket.list" | /usr/bin/weed shell -master=localhost:9333 2>&1 | grep -q "posthog"; then break; fi
|
|
echo "s3.bucket.create -name posthog" | /usr/bin/weed shell -master=localhost:9333 2>&1 || true
|
|
done
|
|
wait $$WEED_PID
|
|
- '--'
|
|
command:
|
|
- server
|
|
- '-s3'
|
|
- '-s3.port=8333'
|
|
- '-dir=/data'
|
|
volumes:
|
|
- posthog-seaweedfs:/data
|
|
healthcheck:
|
|
test: ['CMD', 'sh', '-c', "echo 's3.bucket.list' | /usr/bin/weed shell -master=localhost:9333 2>&1 | grep -q posthog"]
|
|
interval: 5s
|
|
timeout: 10s
|
|
retries: 30
|
|
start_period: 15s
|
|
|
|
temporal:
|
|
image: temporalio/auto-setup:1.20.0
|
|
environment:
|
|
- DB=postgresql
|
|
- DB_PORT=5432
|
|
- POSTGRES_USER=posthog
|
|
- POSTGRES_PWD=${SERVICE_PASSWORD_POSTGRES}
|
|
- POSTGRES_SEEDS=db
|
|
- DYNAMIC_CONFIG_FILE_PATH=config/dynamicconfig/development-sql.yaml
|
|
- ENABLE_ES=false
|
|
healthcheck:
|
|
test: ['CMD-SHELL', 'nc -z $$(hostname) 7233']
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 30
|
|
start_period: 300s
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
volumes:
|
|
- type: bind
|
|
source: ./temporal/dynamicconfig/development-sql.yaml
|
|
target: /etc/temporal/config/dynamicconfig/development-sql.yaml
|
|
read_only: true
|
|
content: |
|
|
limit.maxIDLength:
|
|
- value: 255
|
|
constraints: {}
|
|
system.forceSearchAttributesCacheRefreshOnRead:
|
|
- value: true
|
|
constraints: {}
|
|
|
|
temporal-admin-tools:
|
|
image: temporalio/admin-tools:1.20.0
|
|
environment:
|
|
- TEMPORAL_CLI_ADDRESS=temporal:7233
|
|
depends_on:
|
|
- temporal
|
|
|
|
temporal-ui:
|
|
image: temporalio/ui:2.31.2
|
|
environment:
|
|
- TEMPORAL_ADDRESS=temporal:7233
|
|
- TEMPORAL_CORS_ORIGINS=http://localhost:3000
|
|
- TEMPORAL_CSRF_COOKIE_INSECURE=true
|
|
depends_on:
|
|
temporal:
|
|
condition: service_started
|
|
db:
|
|
condition: service_healthy
|
|
|
|
web:
|
|
image: posthog/posthog:latest
|
|
command:
|
|
- /bin/bash
|
|
- '-c'
|
|
- './bin/migrate && ./bin/docker-server'
|
|
environment:
|
|
- OTEL_SDK_DISABLED=true
|
|
- DISABLE_SECURE_SSL_REDIRECT=true
|
|
- IS_BEHIND_PROXY=true
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- CLICKHOUSE_HOST=clickhouse
|
|
- CLICKHOUSE_DATABASE=posthog
|
|
- CLICKHOUSE_SECURE=false
|
|
- CLICKHOUSE_VERIFY=false
|
|
- CLICKHOUSE_API_USER=api
|
|
- CLICKHOUSE_API_PASSWORD=apipass
|
|
- CLICKHOUSE_APP_USER=app
|
|
- CLICKHOUSE_APP_PASSWORD=apppass
|
|
- KAFKA_HOSTS=kafka
|
|
- REDIS_URL=redis://redis:6379/
|
|
- PGHOST=db
|
|
- PGUSER=posthog
|
|
- PGPASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
|
- DEPLOYMENT=hobby
|
|
- CDP_API_URL=http://plugins:6738
|
|
- FLAGS_REDIS_ENABLED=false
|
|
- SITE_URL=${SERVICE_URL_PROXY}
|
|
- SECRET_KEY=${SERVICE_BASE64_64_SECRETKEY}
|
|
- ENCRYPTION_SALT_KEYS=${SERVICE_PASSWORD_ENCRYPTION}
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=${SERVICE_USER_MINIO}
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_MINIO}
|
|
- OBJECT_STORAGE_ENDPOINT=http://objectstorage:19000
|
|
- OBJECT_STORAGE_PUBLIC_ENDPOINT=${SERVICE_URL_PROXY}
|
|
- SESSION_RECORDING_V2_S3_ENDPOINT=http://seaweedfs:8333
|
|
- SESSION_RECORDING_V2_S3_ACCESS_KEY_ID=any
|
|
- SESSION_RECORDING_V2_S3_SECRET_ACCESS_KEY=any
|
|
- OBJECT_STORAGE_ENABLED=true
|
|
- RECORDING_API_URL=http://plugins:6738
|
|
- LIVESTREAM_HOST=${SERVICE_URL_PROXY}/livestream
|
|
- USE_GRANIAN=true
|
|
- GRANIAN_WORKERS=2
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
clickhouse:
|
|
condition: service_healthy
|
|
clickhouse-init:
|
|
condition: service_completed_successfully
|
|
kafka:
|
|
condition: service_healthy
|
|
kafka-init:
|
|
condition: service_completed_successfully
|
|
objectstorage:
|
|
condition: service_started
|
|
seaweedfs:
|
|
condition: service_healthy
|
|
|
|
worker:
|
|
image: posthog/posthog:latest
|
|
command: ./bin/docker-worker-celery --with-scheduler
|
|
environment:
|
|
- OTEL_SDK_DISABLED=true
|
|
- DISABLE_SECURE_SSL_REDIRECT=true
|
|
- IS_BEHIND_PROXY=true
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- CLICKHOUSE_HOST=clickhouse
|
|
- CLICKHOUSE_DATABASE=posthog
|
|
- CLICKHOUSE_SECURE=false
|
|
- CLICKHOUSE_VERIFY=false
|
|
- CLICKHOUSE_API_USER=api
|
|
- CLICKHOUSE_API_PASSWORD=apipass
|
|
- CLICKHOUSE_APP_USER=app
|
|
- CLICKHOUSE_APP_PASSWORD=apppass
|
|
- KAFKA_HOSTS=kafka
|
|
- REDIS_URL=redis://redis:6379/
|
|
- PGHOST=db
|
|
- PGUSER=posthog
|
|
- PGPASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
|
- DEPLOYMENT=hobby
|
|
- CDP_API_URL=http://plugins:6738
|
|
- FLAGS_REDIS_ENABLED=false
|
|
- SITE_URL=${SERVICE_URL_PROXY}
|
|
- SECRET_KEY=${SERVICE_BASE64_64_SECRETKEY}
|
|
- ENCRYPTION_SALT_KEYS=${SERVICE_PASSWORD_ENCRYPTION}
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=${SERVICE_USER_MINIO}
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_MINIO}
|
|
- OBJECT_STORAGE_ENDPOINT=http://objectstorage:19000
|
|
- OBJECT_STORAGE_PUBLIC_ENDPOINT=${SERVICE_URL_PROXY}
|
|
- SESSION_RECORDING_V2_S3_ENDPOINT=http://seaweedfs:8333
|
|
- SESSION_RECORDING_V2_S3_ACCESS_KEY_ID=any
|
|
- SESSION_RECORDING_V2_S3_SECRET_ACCESS_KEY=any
|
|
- OBJECT_STORAGE_ENABLED=true
|
|
- RECORDING_API_URL=http://plugins:6738
|
|
- POSTHOG_SKIP_MIGRATION_CHECKS=1
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
clickhouse:
|
|
condition: service_healthy
|
|
kafka:
|
|
condition: service_healthy
|
|
web:
|
|
condition: service_started
|
|
|
|
plugins:
|
|
image: posthog/posthog-node:latest
|
|
command: node nodejs/dist/index.js
|
|
environment:
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- PERSONS_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- BEHAVIORAL_COHORTS_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- CYCLOTRON_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- REDIS_URL=redis://redis:6379/
|
|
- POSTHOG_REDIS_HOST=redis
|
|
- POSTHOG_REDIS_PORT=6379
|
|
- INGESTION_REDIS_HOST=redis
|
|
- INGESTION_REDIS_PORT=6379
|
|
- LOGS_REDIS_HOST=redis
|
|
- LOGS_REDIS_PORT=6379
|
|
- LOGS_REDIS_TLS=false
|
|
- CDP_REDIS_HOST=redis
|
|
- CDP_REDIS_PORT=6379
|
|
- SESSION_RECORDING_API_REDIS_HOST=redis
|
|
- SESSION_RECORDING_API_REDIS_PORT=6379
|
|
- COOKIELESS_REDIS_HOST=redis
|
|
- COOKIELESS_REDIS_PORT=6379
|
|
- CLICKHOUSE_HOST=clickhouse
|
|
- CLICKHOUSE_DATABASE=posthog
|
|
- CLICKHOUSE_SECURE=false
|
|
- CLICKHOUSE_VERIFY=false
|
|
- SITE_URL=${SERVICE_URL_PROXY}
|
|
- SECRET_KEY=${SERVICE_BASE64_64_SECRETKEY}
|
|
- ENCRYPTION_SALT_KEYS=${SERVICE_PASSWORD_ENCRYPTION}
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=${SERVICE_USER_MINIO}
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_MINIO}
|
|
- SESSION_RECORDING_V2_S3_ACCESS_KEY_ID=any
|
|
- SESSION_RECORDING_V2_S3_SECRET_ACCESS_KEY=any
|
|
- SESSION_RECORDING_V2_S3_TIMEOUT_MS=120000
|
|
- OBJECT_STORAGE_ENDPOINT=http://objectstorage:19000
|
|
- OBJECT_STORAGE_PUBLIC_ENDPOINT=${SERVICE_URL_PROXY}
|
|
- SESSION_RECORDING_V2_S3_ENDPOINT=http://seaweedfs:8333
|
|
- OBJECT_STORAGE_ENABLED=true
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
clickhouse:
|
|
condition: service_healthy
|
|
kafka:
|
|
condition: service_healthy
|
|
objectstorage:
|
|
condition: service_started
|
|
seaweedfs:
|
|
condition: service_healthy
|
|
web:
|
|
condition: service_started
|
|
|
|
temporal-django-worker:
|
|
image: posthog/posthog:latest
|
|
command: ./bin/temporal-django-worker
|
|
environment:
|
|
- OTEL_SDK_DISABLED=true
|
|
- DISABLE_SECURE_SSL_REDIRECT=true
|
|
- IS_BEHIND_PROXY=true
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- CLICKHOUSE_HOST=clickhouse
|
|
- CLICKHOUSE_DATABASE=posthog
|
|
- CLICKHOUSE_SECURE=false
|
|
- CLICKHOUSE_VERIFY=false
|
|
- CLICKHOUSE_API_USER=api
|
|
- CLICKHOUSE_API_PASSWORD=apipass
|
|
- CLICKHOUSE_APP_USER=app
|
|
- CLICKHOUSE_APP_PASSWORD=apppass
|
|
- KAFKA_HOSTS=kafka
|
|
- REDIS_URL=redis://redis:6379/
|
|
- PGHOST=db
|
|
- PGUSER=posthog
|
|
- PGPASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
|
- DEPLOYMENT=hobby
|
|
- CDP_API_URL=http://plugins:6738
|
|
- FLAGS_REDIS_ENABLED=false
|
|
- SITE_URL=${SERVICE_URL_PROXY}
|
|
- SECRET_KEY=${SERVICE_BASE64_64_SECRETKEY}
|
|
- ENCRYPTION_SALT_KEYS=${SERVICE_PASSWORD_ENCRYPTION}
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=${SERVICE_USER_MINIO}
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_MINIO}
|
|
- OBJECT_STORAGE_ENDPOINT=http://objectstorage:19000
|
|
- OBJECT_STORAGE_PUBLIC_ENDPOINT=${SERVICE_URL_PROXY}
|
|
- SESSION_RECORDING_V2_S3_ENDPOINT=http://seaweedfs:8333
|
|
- SESSION_RECORDING_V2_S3_ACCESS_KEY_ID=any
|
|
- SESSION_RECORDING_V2_S3_SECRET_ACCESS_KEY=any
|
|
- OBJECT_STORAGE_ENABLED=true
|
|
- RECORDING_API_URL=http://plugins:6738
|
|
- TEMPORAL_HOST=temporal
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
clickhouse:
|
|
condition: service_healthy
|
|
kafka:
|
|
condition: service_healthy
|
|
objectstorage:
|
|
condition: service_started
|
|
seaweedfs:
|
|
condition: service_healthy
|
|
temporal:
|
|
condition: service_healthy
|
|
|
|
asyncmigrationscheck:
|
|
image: posthog/posthog:latest
|
|
command: python manage.py run_async_migrations --check
|
|
restart: 'no'
|
|
environment:
|
|
- OTEL_SDK_DISABLED=true
|
|
- DISABLE_SECURE_SSL_REDIRECT=true
|
|
- IS_BEHIND_PROXY=true
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- CLICKHOUSE_HOST=clickhouse
|
|
- CLICKHOUSE_DATABASE=posthog
|
|
- CLICKHOUSE_SECURE=false
|
|
- CLICKHOUSE_VERIFY=false
|
|
- CLICKHOUSE_API_USER=api
|
|
- CLICKHOUSE_API_PASSWORD=apipass
|
|
- CLICKHOUSE_APP_USER=app
|
|
- CLICKHOUSE_APP_PASSWORD=apppass
|
|
- KAFKA_HOSTS=kafka
|
|
- REDIS_URL=redis://redis:6379/
|
|
- PGHOST=db
|
|
- PGUSER=posthog
|
|
- PGPASSWORD=${SERVICE_PASSWORD_POSTGRES}
|
|
- DEPLOYMENT=hobby
|
|
- CDP_API_URL=http://plugins:6738
|
|
- FLAGS_REDIS_ENABLED=false
|
|
- SITE_URL=${SERVICE_URL_PROXY}
|
|
- SECRET_KEY=${SERVICE_BASE64_64_SECRETKEY}
|
|
- ENCRYPTION_SALT_KEYS=${SERVICE_PASSWORD_ENCRYPTION}
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=${SERVICE_USER_MINIO}
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_MINIO}
|
|
- OBJECT_STORAGE_ENDPOINT=http://objectstorage:19000
|
|
- OBJECT_STORAGE_PUBLIC_ENDPOINT=${SERVICE_URL_PROXY}
|
|
- SESSION_RECORDING_V2_S3_ENDPOINT=http://seaweedfs:8333
|
|
- SESSION_RECORDING_V2_S3_ACCESS_KEY_ID=any
|
|
- SESSION_RECORDING_V2_S3_SECRET_ACCESS_KEY=any
|
|
- OBJECT_STORAGE_ENABLED=true
|
|
- RECORDING_API_URL=http://plugins:6738
|
|
- SKIP_ASYNC_MIGRATIONS_SETUP=0
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
clickhouse:
|
|
condition: service_healthy
|
|
kafka:
|
|
condition: service_healthy
|
|
web:
|
|
condition: service_started
|
|
|
|
capture:
|
|
image: ghcr.io/posthog/posthog/capture:master
|
|
environment:
|
|
- ADDRESS=0.0.0.0:3000
|
|
- KAFKA_TOPIC=events_plugin_ingestion
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- REDIS_URL=redis://redis:6379/
|
|
- CAPTURE_MODE=events
|
|
- RUST_LOG=info,rdkafka=warn
|
|
depends_on:
|
|
kafka:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
replay-capture:
|
|
image: ghcr.io/posthog/posthog/capture:master
|
|
environment:
|
|
- ADDRESS=0.0.0.0:3000
|
|
- KAFKA_TOPIC=session_recording_snapshot_item_events
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- REDIS_URL=redis://redis:6379/
|
|
- CAPTURE_MODE=recordings
|
|
depends_on:
|
|
kafka:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
livestream:
|
|
image: ghcr.io/posthog/posthog/livestream:master
|
|
environment:
|
|
- LIVESTREAM_JWT_SECRET=${SERVICE_BASE64_64_SECRETKEY}
|
|
- LIVESTREAM_MMDB_PATH=/share/GeoLite2-City.mmdb
|
|
- LIVESTREAM_KAFKA_BROKERS=kafka:9092
|
|
- LIVESTREAM_KAFKA_TOPIC=events_plugin_ingestion
|
|
- LIVESTREAM_KAFKA_GROUP_ID=livestream
|
|
- LIVESTREAM_REDIS_ADDRESS=redis:6379
|
|
depends_on:
|
|
geoip-init:
|
|
condition: service_completed_successfully
|
|
kafka:
|
|
condition: service_started
|
|
volumes:
|
|
- posthog-share:/share
|
|
- type: bind
|
|
source: ./livestream/configs.yml
|
|
target: /code/configs/configs.yml
|
|
read_only: true
|
|
content: |
|
|
debug: false
|
|
kafka:
|
|
brokers: 'kafka:9092'
|
|
topic: 'events_plugin_ingestion'
|
|
group_id: 'livestream'
|
|
security_protocol: 'PLAINTEXT'
|
|
session_recording_enabled: true
|
|
session_recording_security_protocol: 'PLAINTEXT'
|
|
redis:
|
|
address: 'redis:6379'
|
|
mmdb:
|
|
path: '/share/GeoLite2-City.mmdb'
|
|
|
|
feature-flags:
|
|
image: ghcr.io/posthog/posthog/feature-flags:master
|
|
healthcheck:
|
|
test: ['CMD', 'curl', '-f', 'http://localhost:3001/_readiness']
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 12
|
|
start_period: 10s
|
|
environment:
|
|
- WRITE_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- READ_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- PERSONS_WRITE_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- PERSONS_READ_DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- MAXMIND_DB_PATH=/share/GeoLite2-City.mmdb
|
|
- REDIS_URL=redis://redis:6379/
|
|
- ADDRESS=0.0.0.0:3001
|
|
- RUST_LOG=info
|
|
- COOKIELESS_REDIS_HOST=redis
|
|
- COOKIELESS_REDIS_PORT=6379
|
|
volumes:
|
|
- posthog-share:/share
|
|
depends_on:
|
|
geoip-init:
|
|
condition: service_completed_successfully
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
property-defs-rs:
|
|
image: ghcr.io/posthog/posthog/property-defs-rs:master
|
|
environment:
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- SKIP_WRITES=false
|
|
- SKIP_READS=false
|
|
- FILTER_MODE=opt-out
|
|
depends_on:
|
|
kafka-init:
|
|
condition: service_completed_successfully
|
|
db:
|
|
condition: service_healthy
|
|
|
|
cyclotron-janitor:
|
|
image: ghcr.io/posthog/posthog/cyclotron-janitor:master
|
|
environment:
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- KAFKA_TOPIC=clickhouse_app_metrics2
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
kafka:
|
|
condition: service_started
|
|
|
|
geoip-init:
|
|
image: alpine:3.19
|
|
entrypoint: /bin/sh
|
|
command:
|
|
- '-c'
|
|
- |
|
|
if [ -f /share/GeoLite2-City.mmdb ]; then echo "GeoIP DB already exists"; exit 0; fi
|
|
apk add --no-cache curl brotli
|
|
curl -L 'https://mmdbcdn.posthog.net/' --http1.1 | brotli --decompress > /share/GeoLite2-City.mmdb
|
|
chmod 644 /share/GeoLite2-City.mmdb
|
|
restart: 'no'
|
|
volumes:
|
|
- posthog-share:/share
|
|
|
|
cymbal:
|
|
image: ghcr.io/posthog/posthog/cymbal:master
|
|
environment:
|
|
- KAFKA_HOSTS=kafka:9092
|
|
- KAFKA_CONSUMER_GROUP=cymbal
|
|
- KAFKA_CONSUMER_TOPIC=exceptions_ingestion
|
|
- OBJECT_STORAGE_BUCKET=posthog
|
|
- OBJECT_STORAGE_ACCESS_KEY_ID=any
|
|
- OBJECT_STORAGE_SECRET_ACCESS_KEY=any
|
|
- OBJECT_STORAGE_ENDPOINT=http://seaweedfs:8333
|
|
- OBJECT_STORAGE_FORCE_PATH_STYLE=true
|
|
- BIND_HOST=0.0.0.0
|
|
- BIND_PORT=3302
|
|
- DATABASE_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- PERSONS_URL=postgres://posthog:${SERVICE_PASSWORD_POSTGRES}@db:5432/posthog
|
|
- MAXMIND_DB_PATH=/share/GeoLite2-City.mmdb
|
|
- REDIS_URL=redis://redis:6379/
|
|
- ISSUE_BUCKETS_REDIS_URL=redis://redis:6379/
|
|
- RUST_LOG=info
|
|
volumes:
|
|
- posthog-share:/share
|
|
depends_on:
|
|
geoip-init:
|
|
condition: service_completed_successfully
|
|
kafka-init:
|
|
condition: service_completed_successfully
|
|
seaweedfs:
|
|
condition: service_healthy
|
|
db:
|
|
condition: service_healthy
|
|
redis:
|
|
condition: service_healthy
|
|
|
|
proxy:
|
|
image: caddy:2-alpine
|
|
command: caddy run -c /etc/caddy/Caddyfile
|
|
environment:
|
|
- SERVICE_URL_PROXY_8000
|
|
depends_on:
|
|
- web
|
|
- capture
|
|
- livestream
|
|
ports:
|
|
- '8000'
|
|
volumes:
|
|
- type: bind
|
|
source: ./caddy/Caddyfile
|
|
target: /etc/caddy/Caddyfile
|
|
content: |
|
|
:8000 {
|
|
@replay-capture {
|
|
path /s /s/ /s/*
|
|
}
|
|
@capture {
|
|
path /e /e/ /e/*
|
|
path /i/v0 /i/v0/ /i/v0/*
|
|
path /batch /batch/ /batch/*
|
|
path /capture /capture/ /capture/*
|
|
}
|
|
@livestream {
|
|
path /livestream /livestream/ /livestream/*
|
|
}
|
|
@flags {
|
|
path /flags /flags/ /flags/*
|
|
}
|
|
@webhooks {
|
|
path /public/webhooks /public/webhooks/ /public/webhooks/*
|
|
path /public/m/ /public/m/*
|
|
}
|
|
@objectstorage {
|
|
path /posthog /posthog/ /posthog/*
|
|
}
|
|
handle @livestream {
|
|
uri strip_prefix /livestream
|
|
reverse_proxy livestream:8080 {
|
|
flush_interval -1
|
|
}
|
|
}
|
|
handle @replay-capture {
|
|
reverse_proxy replay-capture:3000
|
|
}
|
|
handle @capture {
|
|
reverse_proxy capture:3000
|
|
}
|
|
handle @flags {
|
|
reverse_proxy feature-flags:3001
|
|
}
|
|
handle @webhooks {
|
|
reverse_proxy plugins:6738
|
|
}
|
|
handle @objectstorage {
|
|
reverse_proxy objectstorage:19000
|
|
}
|
|
handle {
|
|
reverse_proxy web:8000
|
|
}
|
|
}
|
|
- posthog-caddy-data:/data
|
|
- posthog-caddy-config:/config
|
|
|