diff --git a/doc/services-flake/clickhouse.md b/doc/services-flake/clickhouse.md new file mode 100644 index 00000000..8badfb74 --- /dev/null +++ b/doc/services-flake/clickhouse.md @@ -0,0 +1,27 @@ +# Clickhouse + +## Getting Started + +```nix +# In `perSystem.process-compose.` +{ + services.clickhouse."clickhouse-1".enable = true; +} +``` + +## Tips & Tricks + +### Change the HTTP default port + +Clickhouse has [HTTP Interface](https://clickhouse.com/docs/en/interfaces/http) that is enabled by default on port 8123. To change the default port, use the `extraConfig` option: + +```nix +{ + services.clickhouse."clickhouse-1" = { + enable = true; + extraConfig = '' + http_port: 9050 + ''; + }; +} +``` diff --git a/doc/services-flake/services.md b/doc/services-flake/services.md index e232db02..c5ee9cd8 100644 --- a/doc/services-flake/services.md +++ b/doc/services-flake/services.md @@ -8,6 +8,7 @@ short-title: Services > This list denotes the progress of documentation, not implementation. See full list of implemented services at [gh]. - [ ] Apache Kafka +- [ ] [[clickhouse]]# - [ ] Elasticsearch - [ ] MySQL - [ ] Nginx diff --git a/nix/clickhouse.nix b/nix/clickhouse.nix new file mode 100644 index 00000000..ea417c9b --- /dev/null +++ b/nix/clickhouse.nix @@ -0,0 +1,87 @@ +# Based on: https://github.com/cachix/devenv/blob/main/src/modules/services/clickhouse.nix +{ pkgs, lib, name, config, ... }: +let + inherit (lib) types; +in +{ + options = { + enable = lib.mkEnableOption name; + + package = lib.mkOption { + type = types.package; + description = "Which package of clickhouse to use"; + default = pkgs.clickhouse; + defaultText = lib.literalExpression "pkgs.clickhouse"; + }; + + port = lib.mkOption { + type = types.int; + description = "Which port to run clickhouse on. This port is for `clickhouse-client` program"; + default = 9000; + }; + + dataDir = lib.mkOption { + type = types.str; + default = "./data/${name}"; + description = "The clickhouse data directory"; + }; + + extraConfig = lib.mkOption { + type = types.lines; + description = "Additional configuration to be appended to `clickhouse-config.yaml`."; + default = ""; + }; + + outputs.settings = lib.mkOption { + type = types.deferredModule; + internal = true; + readOnly = true; + default = { + processes = { + "${name}" = + let + clickhouseConfig = pkgs.writeText "clickhouse-config.yaml" '' + logger: + level: warning + console: 1 + tcp_port: ${toString config.port} + default_profile: default + default_database: default + path: ${config.dataDir}/clickhouse + tmp_path: ${config.dataDir}/clickhouse/tmp + user_files_path: ${config.dataDir}/clickhouse/user_files + format_schema_path: ${config.dataDir}/clickhouse/format_schemas + user_directories: + users_xml: + path: ${config.package}/etc/clickhouse-server/users.xml + ${config.extraConfig} + ''; + startScript = pkgs.writeShellApplication { + name = "start-clickhouse"; + runtimeInputs = [ config.package ]; + text = '' + clickhouse-server --config-file=${clickhouseConfig} + ''; + }; + in + { + command = "${lib.getExe startScript}"; + + readiness_probe = { + exec.command = ''${config.package}/bin/clickhouse-client --query "SELECT 1" --port ${builtins.toString config.port}''; + initial_delay_seconds = 2; + period_seconds = 10; + timeout_seconds = 4; + success_threshold = 1; + failure_threshold = 5; + }; + namespace = name; + + # https://github.com/F1bonacc1/process-compose#-auto-restart-if-not-healthy + availability.restart = "on_failure"; + }; + }; + }; + }; + }; +} diff --git a/nix/clickhouse_test.nix b/nix/clickhouse_test.nix new file mode 100644 index 00000000..4c5978ca --- /dev/null +++ b/nix/clickhouse_test.nix @@ -0,0 +1,35 @@ +{ pkgs, config, ... }: { + services.clickhouse."clickhouse" = { + enable = true; + extraConfig = '' + http_port: 9050 + ''; + }; + + settings.processes.test = + let + cfg = config.services.clickhouse."clickhouse"; + in + { + command = pkgs.writeShellApplication { + runtimeInputs = [ cfg.package pkgs.gnugrep pkgs.curl ]; + text = + let + # Tests based on: https://github.com/NixOS/nixpkgs/blob/master/nixos/tests/clickhouse.nix + tableDDL = pkgs.writeText "ddl.sql" "CREATE TABLE `demo` (`value` FixedString(10)) engine = MergeTree PARTITION BY value ORDER BY tuple();"; + insertQuery = pkgs.writeText "insert.sql" "INSERT INTO `demo` (`value`) VALUES ('foo');"; + selectQuery = pkgs.writeText "select.sql" "SELECT * from `demo`"; + in + '' + clickhouse-client < ${tableDDL} + clickhouse-client < ${insertQuery} + clickhouse-client < ${selectQuery} | grep foo + + # Test clickhouse http port + curl http://localhost:9050 | grep Ok + ''; + name = "clickhouse-test"; + }; + depends_on."clickhouse".condition = "process_healthy"; + }; +} diff --git a/nix/default.nix b/nix/default.nix index 4ce0d8d3..44616f08 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -5,6 +5,7 @@ in { imports = builtins.map multiService [ ./apache-kafka.nix + ./clickhouse.nix ./elasticsearch.nix ./mysql.nix ./nginx.nix diff --git a/test/flake.nix b/test/flake.nix index 23a2a3c2..e51ab8fd 100644 --- a/test/flake.nix +++ b/test/flake.nix @@ -38,6 +38,7 @@ in builtins.listToAttrs (builtins.map mkPackageFor [ ../nix/apache-kafka_test.nix + ../nix/clickhouse_test.nix ../nix/elasticsearch_test.nix ../nix/mysql_test.nix ../nix/nginx_test.nix