Docker Compose 配置

创建 docker-compose.yml 文件:

services:
shlink:
image: shlinkio/shlink:latest
container_name: shlink
environment:
DB_DRIVER: "mysql"
DB_HOST: shlink-db
DB_PORT: 3306
DB_NAME: shlink
DB_USER: shlink
DB_PASSWORD: ${DB_PASSWORD}
DEFAULT_DOMAIN: "s.diraw.top"
WEB_PORT: 8080
env_file:
- ./.env
ports:
- "127.0.0.1:8090:8080"
depends_on:
shlink-db:
condition: service_healthy
restart: unless-stopped
dns:
- 8.8.8.8
- 1.1.1.1
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/rest/v3/health || exit 1"]
interval: 30s
timeout: 10s
retries: 5
start_period: 45s

shlink-web-client:
image: shlinkio/shlink-web-client:latest
container_name: shlink-web-client
environment:
SHLINK_WEB_CLIENT_API_URL: "https://s.diraw.top"
SHLINK_WEB_CLIENT_BASE_PATH: "/admin"
ports:
- "127.0.0.1:8091:8080"
depends_on:
shlink:
condition: service_healthy
restart: unless-stopped

shlink-db:
image: mariadb:10.11
container_name: shlink-db
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: shlink
MYSQL_USER: shlink
MYSQL_PASSWORD: ${DB_PASSWORD}
env_file:
- ./.env
volumes:
- ./db_shlink:/var/lib/mysql
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "/usr/bin/mysqladmin ping -h localhost -u root -p${MYSQL_ROOT_PASSWORD}"]
interval: 10s
timeout: 5s
retries: 5
start_period: 60s

创建 .env 文件

DB_PASSWORD=DB_PASSWORD
MYSQL_ROOT_PASSWORD=MYSQL_ROOT_PASSWORD
SHLINK_ALLOW_GUEST_LINKS="false"
SHLINK_FORCE_AUTHENTICATION="true"

注意设置 DB_PASSWORDMYSQL_ROOT_PASSWORD 密码

docker compose down
docekr compose up -d

注意端口占用

nginx 反向代理

创建 /etc/nginx/sites-available/s.diraw.top.conf 文件:

# 定义 Shlink API 和 Web Client 的 Docker 容器地址
upstream shlink_api_upstream {
server 127.0.0.1:8090;
keepalive 32;
}

upstream shlink_web_client_upstream {
server 127.0.0.1:8091;
keepalive 32;
}

server {
listen 80;
listen [::]:80;
server_name s.diraw.top;

# API
location ^~ /rest/ {
proxy_pass http://shlink_api_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# Web Client 入口
location ^~ /admin/ {
proxy_pass http://shlink_web_client_upstream/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# Web Client 静态资源
location = /favicon.ico { proxy_pass http://shlink_web_client_upstream/favicon.ico; }
location = /favicon.png { proxy_pass http://shlink_web_client_upstream/favicon.png; }
location = /favicon.gif { proxy_pass http://shlink_web_client_upstream/favicon.gif; }
location = /favicon.svg { proxy_pass http://shlink_web_client_upstream/favicon.svg; }
location = /manifest.json { proxy_pass http://shlink_web_client_upstream/manifest.json; }

location /assets/ {
proxy_pass http://shlink_web_client_upstream/assets/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location = /service-worker.js {
proxy_pass http://shlink_web_client_upstream/service-worker.js;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location ^~ /icons/ {
proxy_pass http://shlink_web_client_upstream/icons/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

# 其它所有路径交给 API 处理
location / {
proxy_pass http://shlink_api_upstream;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
sudo ln -s /etc/nginx/sites-available/s.diraw.top.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

然后去域名控制台添加A记录,然后

sudo certbot --nginx -d s.diraw.top

进入控制台

docker exec -it shlink php bin/cli api-key:generate

之后浏览器登录 https://s.diraw.top/admin/,选择 HOME -> 添加 Server

点击Save,即可进入控制台

测试

服务器上测试:

curl -s -X POST 'http://127.0.0.1:8090/rest/v3/short-urls' \
-H 'X-Api-Key: apikey' \
-H 'Content-Type: application/json' \
-d '{"longUrl":"https://example.com"}'

客户端上测试:

curl -s -X POST 'http://s.diraw.top/rest/v3/short-urls' \
-H 'X-Api-Key: apikey' \
-H 'Content-Type: application/json' \
-d '{"longUrl":"https://example.com"}'

注意把 apikey 替换成刚刚生成的

控制台反向代理

如果你直接用 http://s.diraw.top/admin,你会发现你刷新一下,网站会被短链的形式匹配到,很麻烦

所以如果给控制台单独反向代理一下,会比较方便

# 定义 Shlink Web Client 的 Docker 容器地址
upstream shlink_web_client_upstream {
server 127.0.0.1:8091;
keepalive 32;
}

server {
listen 80;
listen [::]:80;
server_name admin.s.diraw.top;

location / {
proxy_pass http://shlink_web_client_upstream/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
sudo ln -s /etc/nginx/sites-available/admin.s.diraw.top.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

然后去域名控制台添加A记录,然后

sudo certbot --nginx -d admin.s.diraw.top

之后访问 admin.s.diraw.top 即可