+ echo '== containers + restart policies (vendor compose: restart: always) =='
== containers + restart policies (vendor compose: restart: always) ==
+ for c in $APP $PGC $CHC
++ docker inspect -f '{{.Config.Image}}' plausible-ce-plausible-1
++ docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' plausible-ce-plausible-1
++ docker inspect -f '{{.State.Status}}' plausible-ce-plausible-1
+ echo 'plausible-ce-plausible-1 image=ghcr.io/plausible/community-edition:v3.2.1 policy=always status=running'
plausible-ce-plausible-1 image=ghcr.io/plausible/community-edition:v3.2.1 policy=always status=running
+ for c in $APP $PGC $CHC
++ docker inspect -f '{{.Config.Image}}' plausible-ce-plausible_db-1
++ docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' plausible-ce-plausible_db-1
++ docker inspect -f '{{.State.Status}}' plausible-ce-plausible_db-1
+ echo 'plausible-ce-plausible_db-1 image=postgres:16-alpine policy=always status=running'
plausible-ce-plausible_db-1 image=postgres:16-alpine policy=always status=running
+ for c in $APP $PGC $CHC
++ docker inspect -f '{{.Config.Image}}' plausible-ce-plausible_events_db-1
++ docker inspect -f '{{.HostConfig.RestartPolicy.Name}}' plausible-ce-plausible_events_db-1
++ docker inspect -f '{{.State.Status}}' plausible-ce-plausible_events_db-1
+ echo 'plausible-ce-plausible_events_db-1 image=clickhouse/clickhouse-server:24.12-alpine policy=always status=running'
plausible-ce-plausible_events_db-1 image=clickhouse/clickhouse-server:24.12-alpine policy=always status=running
+ echo '== app command =='
== app command ==
+ docker inspect -f '{{json .Config.Cmd}}' plausible-ce-plausible-1
["sh","-c","/entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"]
+ echo '== clickhouse databases/tables =='
== clickhouse databases/tables ==
+ CH 'SHOW DATABASES'
+ docker exec plausible-ce-plausible_events_db-1 clickhouse-client -q 'SHOW DATABASES'
INFORMATION_SCHEMA
default
information_schema
plausible_events_db
system
+ CH 'SHOW TABLES FROM plausible_events_db'
+ docker exec plausible-ce-plausible_events_db-1 clickhouse-client -q 'SHOW TABLES FROM plausible_events_db'
acquisition_channel_paid_sources
acquisition_channel_paid_sources_dict
acquisition_channel_source_category
acquisition_channel_source_category_dict
events
events_v2
imported_browsers
imported_custom_events
imported_devices
imported_entry_pages
imported_exit_pages
imported_locations
imported_operating_systems
imported_pages
imported_sources
imported_visitors
ingest_counters
location_data
location_data_dict
schema_migrations
sessions
sessions_v2
sessions_v2_tmp_versioned
+ echo '== events_v2 engine =='
== events_v2 engine ==
+ CH 'SELECT name, engine FROM system.tables WHERE database='\''plausible_events_db'\'' AND name IN ('\''events_v2'\'','\''sessions_v2'\'')'
+ docker exec plausible-ce-plausible_events_db-1 clickhouse-client -q 'SELECT name, engine FROM system.tables WHERE database='\''plausible_events_db'\'' AND name IN ('\''events_v2'\'','\''sessions_v2'\'')'
events_v2	MergeTree
sessions_v2	VersionedCollapsingMergeTree
+ echo '== events_v2 schema (first 30 cols) =='
== events_v2 schema (first 30 cols) ==
+ CH 'DESCRIBE TABLE plausible_events_db.events_v2'
+ docker exec plausible-ce-plausible_events_db-1 clickhouse-client -q 'DESCRIBE TABLE plausible_events_db.events_v2'
+ head -30
timestamp	DateTime				Delta(4), LZ4	
name	LowCardinality(String)					
site_id	UInt64					
user_id	UInt64					
session_id	UInt64					
hostname	String				ZSTD(3)	
pathname	String				ZSTD(3)	
referrer	String				ZSTD(3)	
referrer_source	String				ZSTD(3)	
country_code	FixedString(2)					
screen_size	LowCardinality(String)					
operating_system	LowCardinality(String)					
browser	LowCardinality(String)					
utm_medium	String				ZSTD(3)	
utm_source	String				ZSTD(3)	
utm_campaign	String				ZSTD(3)	
meta.key	Array(String)				ZSTD(3)	
meta.value	Array(String)				ZSTD(3)	
browser_version	LowCardinality(String)					
operating_system_version	LowCardinality(String)					
subdivision1_code	LowCardinality(String)					
subdivision2_code	LowCardinality(String)					
city_geoname_id	UInt32					
utm_content	String				ZSTD(3)	
utm_term	String				ZSTD(3)	
revenue_reporting_amount	Nullable(Decimal(18, 3))					
revenue_reporting_currency	FixedString(3)					
revenue_source_amount	Nullable(Decimal(18, 3))					
revenue_source_currency	FixedString(3)					
city	UInt32	ALIAS	city_geoname_id			
+ echo '== postgres sites columns =='
== postgres sites columns ==
+ PG 'select column_name, data_type, column_default from information_schema.columns where table_name='\''sites'\'' order by ordinal_position'
+ docker exec plausible-ce-plausible_db-1 psql -U postgres -d plausible_db -tAc 'select column_name, data_type, column_default from information_schema.columns where table_name='\''sites'\'' order by ordinal_position'
id|bigint|nextval('sites_id_seq'::regclass)
domain|character varying|
inserted_at|timestamp without time zone|
updated_at|timestamp without time zone|
timezone|character varying|
public|boolean|false
locked|boolean|false
has_stats|boolean|false
imported_data|jsonb|
stats_start_date|date|
ingest_rate_limit_scale_seconds|integer|60
ingest_rate_limit_threshold|integer|
native_stats_start_at|timestamp without time zone|now()
domain_changed_from|character varying|
domain_changed_at|timestamp without time zone|
allowed_event_props|ARRAY|
conversions_enabled|boolean|true
funnels_enabled|boolean|true
props_enabled|boolean|true
accept_traffic_until|timestamp without time zone|
installation_meta|jsonb|
team_id|bigint|
legacy_time_on_page_cutoff|date|to_date('1970-01-01'::text, 'YYYY-MM-DD'::text)
consolidated|boolean|false
+ echo '== postgres users count =='
== postgres users count ==
+ PG 'select count(*) from users'
+ docker exec plausible-ce-plausible_db-1 psql -U postgres -d plausible_db -tAc 'select count(*) from users'
0
+ echo '== served tracker scripts =='
== served tracker scripts ==
+ for p in /js/script.js /js/plausible.js /js/script.outbound-links.js
+++ echo /js/script.js
+++ tr / _
++ curl -s -o tracker_js_script.js -w '%{http_code}' http://127.0.0.1:8000/js/script.js
+ echo '/js/script.js http=200'
/js/script.js http=200
+ for p in /js/script.js /js/plausible.js /js/script.outbound-links.js
+++ echo /js/plausible.js
+++ tr / _
++ curl -s -o tracker_js_plausible.js -w '%{http_code}' http://127.0.0.1:8000/js/plausible.js
+ echo '/js/plausible.js http=200'
/js/plausible.js http=200
+ for p in /js/script.js /js/plausible.js /js/script.outbound-links.js
+++ echo /js/script.outbound-links.js
+++ tr / _
++ curl -s -o tracker_js_script.outbound-links.js -w '%{http_code}' http://127.0.0.1:8000/js/script.outbound-links.js
+ echo '/js/script.outbound-links.js http=200'
/js/script.outbound-links.js http=200
+ echo '== tracker script: content-type + payload field names + version (from the served /js/script.js) =='
== tracker script: content-type + payload field names + version (from the served /js/script.js) ==
+ grep -oE text/plain tracker_js_script.js
+ head -1
text/plain
+ grep -oE 'n:[a-zA-Z_$]+,v:[0-9]+|\.v=[0-9]+|v:[0-9]+' tracker_js_script.js
+ head -5
v:33
.v=33
.v=33
+ grep -oE /api/event tracker_js_script.js
+ head -1
/api/event
+ echo '== rpc smoke =='
== rpc smoke ==
+ RPC 'IO.puts("rpc-ok " <> to_string(1 + 1))'
+ tail -2
+ docker exec plausible-ce-plausible-1 /app/bin/plausible rpc 'IO.puts("rpc-ok " <> to_string(1 + 1))'
rpc-ok 2
+ echo '== /api/event trap probes (expect 202 for all; dropped header on bot UA + unknown site; 400 on bad JSON) =='
== /api/event trap probes (expect 202 for all; dropped header on bot UA + unknown site; 400 on bad JSON) ==
++ SEND 10.9.9.1 /probe-bot curl/8.0
++ local d=bench.example tv
+++ cat tracker_v
+++ echo 0
++ tv=0
++ curl -s -o /dev/null -D - -X POST http://127.0.0.1:8000/api/event -H 'Content-Type: text/plain' -H 'User-Agent: curl/8.0' -H 'X-Forwarded-For: 10.9.9.1' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.9' -d '{"n":"pageview","v":0,"u":"http://bench.example/probe-bot","d":"bench.example","r":null}'
++ awk 'BEGIN{c="";d="none"} /^HTTP/{c=$2} tolower($1)=="x-plausible-dropped:"{d=$2} END{gsub(/\r/,"",d); print c" dropped="d}'
+ echo 'bot UA (curl default):     202 dropped=1'
bot UA (curl default):     202 dropped=1
++ SEND 10.9.9.2 /probe-unknown 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' not-a-site.invalid
++ local d=not-a-site.invalid tv
+++ cat tracker_v
+++ echo 0
++ tv=0
++ curl -s -o /dev/null -D - -X POST http://127.0.0.1:8000/api/event -H 'Content-Type: text/plain' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' -H 'X-Forwarded-For: 10.9.9.2' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.9' -d '{"n":"pageview","v":0,"u":"http://not-a-site.invalid/probe-unknown","d":"not-a-site.invalid","r":null}'
++ awk 'BEGIN{c="";d="none"} /^HTTP/{c=$2} tolower($1)=="x-plausible-dropped:"{d=$2} END{gsub(/\r/,"",d); print c" dropped="d}'
+ echo 'unknown site:              202 dropped=1'
unknown site:              202 dropped=1
++ curl -s -o /dev/null -w '%{http_code}' -X POST http://127.0.0.1:8000/api/event -H 'Content-Type: text/plain' -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' -d nope
+ echo 'bad json:                  400'
bad json:                  400
