方案概述
- 安装 Docker 环境
- 使用官方的
docker-compose.yaml启动Loki+Grafana+Promtail Grafana配置Loki数据源- 配置 Nginx 反代
Loki并添加认证功能 - 配置 Docker 插件来测试日志推送
Loki功能

整体架构
Loki:负责存储日志和处理查询。Promtail:代理,负责收集日志并将其发送给Loki。Grafana:用于日志展示等。
操作步骤
一、安装 Docker 环境
参考:Ubuntu 20.04 从官方源安装最新的 Docker
二、使用官方的 docker-compose.yaml 启动 Loki + Grafana + Promtail
官方仓库:loki/production/
使用 Docker Compose 来部署,在 /opt 下创建一个 grafana-loki 文件夹,再在 Grafana-Loki 文件夹下创建 docker-compose.yml 文件,复制以下内容到文件,保存。
为 Loki 服务添加了 volumes 配置,将宿主机上的 ./loki-data 目录持久化到容器内的 /loki。
为 Promtail 服务添加了 volumes 配置,将 Promtail 的配置映射进去。
为 Loki 和 Promtail 服务添加了 user: "10001",显式地以非 Root 用户运行,这有助于匹配默认的容器权限设置。
networks:
loki:
services:
loki:
image: grafana/loki:3.6.0
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- loki
restart: unless-stopped
volumes:
- ./loki-data:/loki # <-- 🎯 添加了数据卷映射
promtail:
image: grafana/promtail:3.6.0
volumes:
- /var/log:/var/log
command: -config.file=/etc/promtail/config.yml
networks:
- loki
restart: unless-stopped
grafana:
environment:
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
entrypoint:
- sh
- -euc
- |
mkdir -p /etc/grafana/provisioning/datasources
cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: true
version: 1
editable: false
EOF
/run.sh
image: grafana/grafana:latest
ports:
- "3000:3000"
networks:
- loki
restart: unless-stopped
解决权限问题的步骤 (Execution Steps)
在您使用新的 docker-compose.yml 启动之前,您必须在宿主机上设置权限,这是解决 permission denied 错误的关键。
1. 创建数据目录
在您的 /opt/grafana-loki 目录下创建 Loki 的数据目录。
mkdir loki-data
2. 更改目录所有权
将该目录的所有权更改为 Loki 容器内部使用的用户 ID 10001。
sudo chown -R 10001:10001 loki-data
3. 创建 Promtail 配置文件
您还需要一个 Promtail 的配置文件 (promtail-config.yml),否则 Promtail 会失败。在 /opt/ 目录下创建此文件:grafana-loki
promtail-config.yml 示例:
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
4. 启动服务
docker compose up -d
查看Loki日志,应该没有错误了docker compose logs loki检查Loki是否运行docker compose ps | grep lokiserver { listen 443 ssl; server_name grafana.ceshiku.cn; # SSL 配置 ssl_certificate /etc/nginx/ssl/grafana.ceshiku.cn/certificate.crt; ssl_certificate_key /etc/nginx/ssl/grafana.ceshiku.cn/private.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; location / { proxy_pass http://1.2.3.4:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Port $server_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; # This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close. proxy_read_timeout 900s; } }同时需要在
nginx.conf的http配置段中增加:map $http_upgrade $connection_upgrade { default upgrade; '' close; }
三、Grafana 配置 Loki 数据源

选择 Loki 数据源
如果是和 Loki 在同一 Docker 网络下,使用 http://loki:3100 即可访问,其他情况需要使用公网或内网 IP:

配置 Loki
同时由于 Loki 本身没有认证功能,因此这里也不需要配置认证信息,填完名字和 URL 后就结束了:

Loki 连接成功
因为将宿主机的
/var/log目录映射给了Promtail,因此当前Loki已经开始收集宿主机的日志。
可以在Grafana面板上配置检索进行查看:宿主机日志检索
四、配置 Nginx 反代 Loki 并添加认证功能
官方对于认证功能的描述:Authentication
Nginx 认证添加可以参考:Creating a Password File
很明显把任何不需要认证的服务暴露在公网,都不会是一个很好的注意,因此这里需要添加下简单的认证。
创建认证用户:
apt-get install apache2-utils
mkdir -vp /etc/nginx/auth/
touch /etc/nginx/auth/.loki
# logger 为用户名
sudo htpasswd /etc/nginx/auth/.loki logger
之后输入密码,然后查看 /etc/nginx/auth/.loki 文件会看到用户名和 Hash 后的密码:
cat /etc/nginx/auth/.loki

用户密码
之后用 Nginx 反代 3100 端口的 Loki 服务,并设置使用认证:
server {
listen 443 ssl;
server_name loki.ceshiku.cn;
# 认证信息配置
auth_basic "Administrator’s Area";
auth_basic_user_file /etc/nginx/auth/.loki;
# SSL 配置
ssl_certificate /etc/nginx/ssl/loki.ceshiku.cn/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/loki.ceshiku.cn/private.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
location / {
proxy_pass http://1.2.3.4:3100;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
# This allows the ability for the execute shell window to remain open for up to 15 minutes. Without this parameter, the default is 1 minute and will automatically close.
proxy_read_timeout 900s;
}
}

需要登录
之后记得关闭没有认证的
3100端口的防火墙或安全组。
五、配置 Docker 插件来测试日志推送 Loki 功能
1、安装 Loki driver client 插件
参考:Install the Docker driver client
docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions
docker plugin ls
2、指定容器的日志推送到 Loki
参考:Change the logging driver for a container
这里拿 Nginx 容器举例:
docker run -d \
--name nginx \
--restart=unless-stopped \
--log-driver=loki \
--log-opt loki-url="https://logger:your_logger_password@loki.ceshiku.cn/loki/api/v1/push" \
--log-opt loki-retries=5 \
--log-opt loki-batch-size=400 \
-p 80:80 \
nginx:latest
之后回到 Grafana 面板,用适当的查询条件就能看到刚刚启动的容器的日志了:

Nginx 的启动日志
docker stop nginx docker rm nginx
3、配置全局日志推送到 Loki
需要修改的是 /etc/docker/daemon.json 文件:
vi /etc/docker/daemon.json
{
"debug" : true,
"log-driver": "loki",
"log-opts": {
"loki-url": "https://logger:your_logger_password@loki.ceshiku.cn/loki/api/v1/push",
"loki-batch-size": "400"
}
}
保存之后重启下 Docker 服务:
sudo systemctl daemon-reload
sudo systemctl restart docker
启动个 Caddy 容器测试下:
docker run -d \
--name caddy \
--restart=unless-stopped \
-p 80:80 \
caddy:latest
之后去 Grafana 面板确认下,Caddy 的日志应该也会出现:

Caddy 的启动日志
docker stop caddy docker rm caddy
1、新的 添加了开机自启的代码
networks:
loki:
services:
loki:
image: grafana/loki:3.6.0
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- loki
restart: unless-stopped # <-- 已添加
promtail:
image: grafana/promtail:3.6.0
volumes:
- /var/log:/var/log
command: -config.file=/etc/promtail/config.yml
networks:
- loki
restart: unless-stopped # <-- 已添加
grafana:
environment:
- GF_PATHS_PROVISIONING=/etc/grafana/provisioning
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
entrypoint:
- sh
- -euc
- |
mkdir -p /etc/grafana/provisioning/datasources
cat <<EOF > /etc/grafana/provisioning/datasources/ds.yaml
apiVersion: 1
datasources:
- name: Loki
type: loki
access: proxy
orgId: 1
url: http://loki:3100
basicAuth: false
isDefault: true
version: 1
editable: false
EOF
/run.sh
image: grafana/grafana:latest
ports:
- "3000:3000"
networks:
- loki
restart: unless-stopped # <-- 已添加
