Docker series builds a website traffic monitoring system based on umami
This article was last updated 238 days ago. The information in it may have developed or changed. If it is invalid, please leave a message in the comment section.

Note: The content of this article about deployment is outdated. For the latest deployment tutorial, see:Home Data Center Series The latest version of umami (2.11.3) detailed construction tutorial, you can still refer to this article for initialization operations after successful deployment.

Preface

Since the blog went online, I have studied a lot of related technologies: health monitoring (uptime-kuma), fault message push (bark), web application firewall (Changting Lei Chi), etc., but there is a lack of an intuitive way to view the source of access.


To be honest, the Changting Leichi can be simply seen as follows:

image.png

But firstly, this is too rough, after all, it is not specially designed for this purpose, and secondly, this page cannot be taken out separately...


After searching online, I found the tool Umami: Umami is an easy-to-use, self-hosted, open source website access traffic statistics and analysis tool. Umami does not use cookies, does not track users, and all collected data is anonymized, in compliance with GDPR policies, and has very low resource usage. Although its functions are simple, the analyzed data content is very rich.

The introduction was good, so I decided to use it. After the construction was completed, the final effect was as follows:

image.png

image.png

image.png

image.png

Deploy Umami

Umami needs a database, and by default it supports two databases: mysql and postgresql. If I follow the convention of my previous articles, I will definitely reuse mariadb if possible, but umami is a bit special: the database it uses requires special initialization, and a blank database is not enough. Special initialization is a hassle (simplicity is king), so this article makes an exception and uses docker-compose to build it. I deployed umami on a lightweight server on Tencent Cloud.

Create docker-compose.yml file

Create a docker-compose.yml file in the corresponding directory, I am in /docker/umami:

mkdir -p /docker/umami cd /docker/umami vim docker-compose.yml

The content of docker-compose.yml is as follows:

---
version: '3'
services:
  umami:
    image: ghcr.io/mikecao/umami:postgresql-latest
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgresql://umami:umami@db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: replace-me-with-a-random-string
      TRACKER_SCRIPT_NAME: random-string.js
    depends_on:
      - db
    restart: always
    networks:
      - public-net
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - ./sql/schema.postgresql.sql:/docker-entrypoint-initdb.d/schema.postgresql.sql:ro
      - ./data:/var/lib/postgresql/data
    restart: always
    networks:
      - public-net

networks:
  public-net:
    external: true

There are 4 things to note:
1. You need to create the sql directory and data directory in advance:

mkdir /docker/umami/sql mkdir /docker/umami/data

2. Networks
Since I already have a bridge network called public-net, the structure is as follows:

services: umami: networks: - public-net db: networks: - public-net networks: public-net: external: true

If it is a newly built network, it should be similar to:

services: umami: networks: - default db: networks: - default networks: default: name: public-net

3. Pay attention to whether port 3000 of the host machine is occupied. If it is occupied, change it to an unused port.

4. Create schema.postgresql.sql file
Note that in the db section there is a file mounted into the containerschema.postgresql.sqlThis is a sql script file, which is what I mentioned earlier about the need to initialize the database in advance. We need to create this file manually:

vim /docker/umami/sql/schema.postgresql.sql

Paste the following content and save and exit:

drop table if exists event;
drop table if exists pageview;
drop table if exists session;
drop table if exists website;
drop table if exists account;

create table account (
    user_id serial primary key,
    username varchar(255) unique not null,
    password varchar(60) not null,
    is_admin bool not null default false,
    created_at timestamp with time zone default current_timestamp,
    updated_at timestamp with time zone default current_timestamp
);

create table website (
    website_id serial primary key,
    website_uuid uuid unique not null,
    user_id int not null references account(user_id) on delete cascade,
    name varchar(100) not null,
    domain varchar(500),
    share_id varchar(64) unique,
    created_at timestamp with time zone default current_timestamp
);

create table session (
    session_id serial primary key,
    session_uuid uuid unique not null,
    website_id int not null references website(website_id) on delete cascade,
    created_at timestamp with time zone default current_timestamp,
    hostname varchar(100),
    browser varchar(20),
    os varchar(20),
    device varchar(20),
    screen varchar(11),
    language varchar(35),
    country char(2)
);

create table pageview (
    view_id serial primary key,
    website_id int not null references website(website_id) on delete cascade,
    session_id int not null references session(session_id) on delete cascade,
    created_at timestamp with time zone default current_timestamp,
    url varchar(500) not null,
    referrer varchar(500)
);

create table event (
    event_id serial primary key,
    website_id int not null references website(website_id) on delete cascade,
    session_id int not null references session(session_id) on delete cascade,
    created_at timestamp with time zone default current_timestamp,
    url varchar(500) not null,
    event_type varchar(50) not null,
    event_value varchar(50) not null
);

create index website_user_id_idx on website(user_id);

create index session_created_at_idx on session(created_at);
create index session_website_id_idx on session(website_id);

create index pageview_created_at_idx on pageview(created_at);
create index pageview_website_id_idx on pageview(website_id);
create index pageview_session_id_idx on pageview(session_id);
create index pageview_website_id_created_at_idx on pageview(website_id, created_at);
create index pageview_website_id_session_id_created_at_idx on pageview(website_id, session_id, created_at);

create index event_created_at_idx on event(created_at);
create index event_website_id_idx on event(website_id);
create index event_session_id_idx on event(session_id);

insert into account (username, password, is_admin) values ('admin', '2b10$BUli0c.muyCW1ErNJc3jL.vFRFtFJWrT8/GcR4A.sUdCznaXiqFXa', true);

Pull the image first:

docker pull ghcr.io/mikecao/umami:postgresql-latest docker pull postgres:15-alpine

The domestic pull speed will be very slow, but if there is an environment that uses science or magic, you can consider using proxychains, see my other article:Home data center series of powerful local proxy tools: proxychains (cli)

Pull up the container

cd /docker/umami docker-compose up -d

If the container works properly,http://host IP:3000The login page will open:

image.png

Default username: admin, default password: umami

After entering, the default language is English. Click the red box button to change the language to Simplified Chinese:

image.png

image.png

Add a reverse proxy

Use the public domain name to publish umami through reverse proxy. I use the Baota Linux panel. Other 1panel, NPM, etc. can also be used. You can configure it according to your own familiar methods. Then you can access umami with the domain name. For specific configuration steps, see the article:Linux panel series configure reverse proxy and use non-443 port for publishing.

Configure umami

Add the website you want to count

Log in to umami via domain name.
Click "Settings" - "Add Website":

image.png

Then enter the name and domain name of the website that needs to be monitored. If you want others to see some of the information, click "Enable Shared Link" in the red box, and then click Save:
image.png

After adding, the interface is as follows:
image.png

The button in the red box in the above picture is "Get Shared Link", which allows others to see some statistics of your site. However, you cannot see the information now. You need to embed the tracking code into the website you want to monitor for it to take effect.

Get Tracking Code

点击”设置”中点击红框按钮来获取追踪代码:
image.png

The following interface pops up:
image.png

Click the copy button below to get the tracking code.

Insert tracking code

The configuration is different for different website building methods. I use WordPress to build my website, and use the Argon theme. You can directly configure it in the "Header Script" option of Argon as follows:
image.png

If it is another way, you can find something similar to header.php and put it in<head></head>Just between the tags.

Optimization

If the country/region is unknown and the source cannot be counted, you can add the following code in the reverse proxy configuration:

location = /api/collect 
{
   proxy_pass http://ip:端口/api/collect;
   proxy_buffering on;
   proxy_http_version 1.1;
   proxy_ssl_session_reuse off;
   proxy_ssl_server_name on;
   proxy_set_header X-Forwarded-Proto https;
   proxy_set_header X-Real-IP remote_addr;
   proxy_set_header X-Forwarded-Forproxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Host  $host;
}

Just replace the IP port with your configuration.

最终效果见本站”顶部菜单”-“其他功能”-“流量监控”:
image.png

The content of the blog is original. Please indicate the source when reprinting! For more blog articles, you can go toSitemapUnderstand. The RSS address of the blog is:https://blog.tangwudi.com/feed, welcome to subscribe; if necessary, you can joinTelegram GroupDiscuss the problem together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠(ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ°Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Emoticons
Emoji
Little Dinosaur
flower!
Previous
Next
       
error:
en_US
Spring Festival
hapiness