YOURLS 1.10.6 Docker Compose 部署指南
YOURLS 1.10.6 Docker Compose 部署指南:yourls 官方镜像 + MySQL 8.0 双服务编排、安装向导、登录 nonce 实录、301 短链验证与排障沉淀,全部命令带实测回显。
YOURLS 1.10.6 Docker Compose 部署指南
> 目标:在一台 Linux 服务器上用 Docker Compose 完成 YOURLS 1.10.6 + MySQL 8.0 双服务编排部署,从零到拿到第一条 301 短链。本文全部命令与回显均于 2026-10-30 在 Ubuntu 22.04 服务器(IP 192.168.1.200)实测通过。
一、环境信息
- 操作系统:Ubuntu 22.04(IP 192.168.1.200,已安装 Docker Engine 与 Compose 插件);
- 架构:x86_64;
- YOURLS:1.10.6(官方镜像
yourls:1.10.6,759MB;镜像内为 Apache 2.4.69 + PHP 8.5.12); - 数据库:MySQL 8.0(官方镜像
mysql:8.0,1.1GB); - 端口规划:YOURLS 容器内监听 8080,宿主机映射 8134;
- 数据目录:
/opt/yourls/user(YOURLS 用户层:配置、插件、页面、语言包)与/opt/yourls/mysql(数据库文件); - 短链站点地址:
http://192.168.1.200:8134(生产环境换成自有域名,如https://s.example.com); - 演示账号:用户名
admin、密码q1w2e3r4、MySQL 业务密码同为q1w2e3r4。
二、镜像选型说明
YOURLS 的 Docker 镜像有三类可选:yourls(Docker 官方镜像,由 docker-library 审核,docker pull yourls 即可)、yourls/yourls(项目方同名镜像)以及第三方构建。本文采用 Docker 官方镜像 yourls:1.10.6,理由:官方渠道维护、与 PHP/Apache 版本组合经过 docker-library 测试、支持 _FILE 后缀环境变量读取 Docker Secrets。官方镜像内置 Apache 2.4.69 与 PHP 8.5.12,应用代码位于容器内 /var/www/html,启动时由 entrypoint 脚本完成「检查环境变量 → 生成 user/config.php → 等待数据库就绪 → 启动 Apache」的全过程,无需手工初始化。
数据库镜像选 mysql:8.0 而非 8.4/9.x:YOURLS 官方兼容面以 MySQL/MariaDB 稳定线为主,8.0 是最保守可靠的选择(MariaDB 11 亦可替换,compose 写法相同)。
三、前置条件
- 服务器已安装 Docker Engine 与
docker compose插件(安装方法见 《Docker Compose 安装与多容器编排》); - 服务器可访问外网或已配置镜像加速(拉取
yourls:1.10.6与mysql:8.0); - 端口 8134 未被占用,验证方法:
ss -ltn | grep 8134 || echo "8134 空闲"
实测回显:
8134 空闲
- 规划好 YOURLS 站点地址:它决定了所有生成的短链 URL 前缀,务必与实际访问地址完全一致(含端口、不含末尾斜杠),否则会出现登录后 301 回跳与短链域名错乱(排障实录见第九节)。
四、部署步骤
4.1 创建目录与编排文件
mkdir -p /opt/yourls/user /opt/yourls/mysql /opt/yourls/compose
cd /opt/yourls/compose
创建 docker-compose.yml(以下为实测原文件,可直接复制替换站点地址与密码):
name: yourls-1.10.6-stack
services:
yourls:
image: yourls:1.10.6
container_name: yourls-1.10.6-web
restart: unless-stopped
ports:
- "8134:8080"
environment:
YOURLS_SITE: "http://192.168.1.200:8134"
YOURLS_USER: "admin"
YOURLS_PASS: "q1w2e3r4"
YOURLS_DB_HOST: "mysql"
YOURLS_DB_USER: "yourls"
YOURLS_DB_PASS: "q1w2e3r4"
YOURLS_DB_NAME: "yourls"
YOURLS_DB_PREFIX: "yourls_"
YOURLS_UNIQUE_URLS: "false"
YOURLS_URL_CONVERT: "62"
volumes:
- /opt/yourls/user:/var/www/html/user
depends_on:
- mysql
networks:
- yourls-net
mysql:
image: mysql:8.0
container_name: yourls-1.10.6-mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "q1w2e3r4"
MYSQL_DATABASE: "yourls"
MYSQL_USER: "yourls"
MYSQL_PASSWORD: "q1w2e3r4"
volumes:
- /opt/yourls/mysql:/var/lib/mysql
networks:
- yourls-net
networks:
yourls-net:
driver: bridge
ipam:
config:
- subnet: 10.89.59.0/24
关键项说明:YOURLS_SITE 必须与实际访问地址一致;YOURLS_DB_HOST 指向 compose 内的 mysql 服务名;YOURLS_UNIQUE_URLS: false 允许同一长链创建多条短链(默认 true 全局唯一);YOURLS_URL_CONVERT: 62 使用 62 进制短码(区分大小写,短码空间更大,36 为默认);ipam.subnet 显式指定网段避免与既有 compose 网络冲突(无此需求可删除 networks 里的 ipam 段)。
4.2 启动编排栈
docker compose up -d
实测回显:
Container yourls-1.10.6-mysql Starting
Container yourls-1.10.6-mysql Started
Container yourls-1.10.6-web Starting
Container yourls-1.10.6-web Started
4.3 确认服务状态
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
yourls-1.10.6-mysql mysql:8.0 "docker-entrypoint.s…" mysql 26 seconds ago Up 25 seconds 3306/tcp, 33060/tcp
yourls-1.10.6-web yourls:1.10.6 "container-entrypoin…" yourls 26 seconds ago Up 25 seconds 80/tcp, 8443/tcp, 0.0.0.0:8134->8080/tcp, [::]:8134->8080/tcp
查看 YOURLS 启动日志确认初始化完成:
docker compose logs yourls
实测回显(节选):
yourls-1.10.6-web | YOURLS not found in /var/www/html - copying now...
yourls-1.10.6-web | Complete! YOURLS has been successfully copied to /var/www/html
yourls-1.10.6-web | Running custom script /docker-entrypoint-init.d/*
yourls-1.10.6-web | ... ignoring /docker-entrypoint-init.d/*
yourls-1.10.6-web | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.89.59.3. Set the 'ServerName' directive globally to suppress this message
yourls-1.10.6-web | [Fri Oct 30 07:19:16.115745 2026] [mpm_prefork:notice] [pid 1:tid 1] AH00163: Apache/2.4.69 (Debian) PHP/8.5.12 configured -- resuming normal operations
YOURLS has been successfully copied 表示应用代码已就位,Apache/2.4.69 (Debian) PHP/8.5.12 configured -- resuming normal operations 表示 Web 服务已监听。AH00558 提示是无害警告(未配置全局 ServerName),不影响使用。
4.4 完成安装向导
首次访问根路径会得到 403——这是官方镜像文档明确注明的行为(「On first instantiation, reaching the root folder will generate an error. Access the YOURLS administration interface via the path /admin/」),因为安装完成前短链表不存在:
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.200:8134/
实测回显:
403
浏览器访问安装向导(或命令行查看页面确认版本):
curl -s http://192.168.1.200:8134/admin/install.php | grep -oE '<title>[^<]+</title>'
实测回显:
<title>Install YOURLS « YOURLS — Your Own URL Shortener | http://192.168.1.200:8134/</title>
安装页是一个 POST 表单(按钮 Install YOURLS),浏览器中直接点击即可;命令行等价操作:
curl -s "http://192.168.1.200:8134/admin/install.php" -d 'install=Install YOURLS'
实测回显(节选):
File .htaccess successfully created/updated.
Table 'yourls_url' created.
Table 'yourls_options' created.
Table 'yourls_log' created.
YOURLS tables successfully created.
» YOURLS Administration Page
三张核心表(yourls_url/yourls_options/yourls_log)建表成功即安装完成。到库侧复核一遍:
docker exec yourls-1.10.6-mysql sh -c 'mysql -uyourls -pq1w2e3r4 yourls -e "SHOW TABLES;"'
实测回显:
Tables_in_yourls
yourls_log
yourls_options
yourls_url
4.5 登录管理后台
浏览器打开 http://192.168.1.200:8134/admin/,输入 admin / q1w2e3r4 登录。登录表单带 nonce 防 CSRF 令牌,命令行模拟需先取 nonce 再提交:
# 从登录页取 nonce(每次会话不同)
NONCE=$(curl -s -c /tmp/yourls-cookie.txt "http://192.168.1.200:8134/admin/index.php" \
| grep -oE 'name="nonce" value="[a-z0-9]+"' | grep -oE '[a-z0-9]{10}')
# 带 nonce 提交登录
curl -s -b /tmp/yourls-cookie.txt -c /tmp/yourls-cookie.txt -o /dev/null \
-w 'login http:%{http_code} redirect:%{redirect_url}\n' \
"http://192.168.1.200:8134/admin/index.php" \
-d "username=admin&password=q1w2e3r4&nonce=$NONCE&submit=Login"
# 确认已进入后台
curl -s -b /tmp/yourls-cookie.txt "http://192.168.1.200:8134/admin/index.php" | grep -oE '<title>[^<]+</title>'
实测回显:
login http:301 redirect:http://192.168.1.200:8134/admin/index.php
<title>YOURLS — Your Own URL Shortener | http://192.168.1.200:8134/</title>
登录成功后页面标题从「Login — YOURLS」变为「YOURLS — Your Own URL Shortener」,同时服务端种下名为 yourls_<随机串> 的会话 cookie。
4.6 创建第一条短链并验证 301 跳转
用内置 API 创建短链(API 认证细节见本专栏 《YOURLS 1.10.6 API 使用详解》,此处用最直观的用户名密码参数):
curl -s "http://192.168.1.200:8134/yourls-api.php" \
--data-urlencode 'url=https://www.quzuo.net/' \
--data-urlencode 'title=Quzuo 主站' \
--data-urlencode 'keyword=quzuo' \
--data-urlencode 'action=shorturl' --data-urlencode 'format=json' \
--data-urlencode 'username=admin' --data-urlencode 'password=q1w2e3r4'
实测回显:
{
"status": "success",
"code": "",
"message": "https://www.quzuo.net/ added to database",
"errorCode": "",
"statusCode": "200",
"url": {
"keyword": "quzuo",
"url": "https://www.quzuo.net/",
"title": "Quzuo \u4e3b\u7ad9",
"date": "2026-10-30 07:21:34",
"ip": "192.168.1.200"
},
"title": "Quzuo \u4e3b\u7ad9",
"shorturl": "http://192.168.1.200:8134/quzuo"
}
访问短链验证 301 重定向:
curl -sI "http://192.168.1.200:8134/quzuo" | head -8
实测回显:
HTTP/1.1 301 Moved Permanently
Date: Fri, 30 Oct 2026 07:21:42 GMT
Server: Apache/2.4.69 (Debian)
X-Powered-By: PHP/8.5.12
X-Robots-Tag: noindex
Location: https://www.quzuo.net/
Content-Type: text/html; charset=UTF-8
Location 指向长链、X-Robots-Tag: noindex 防搜索引擎收录,部署闭环完成。
五、数据持久化说明
本编排把两类数据都落在宿主机目录(bind mount):
| 宿主机目录 | 容器内路径 | 内容 |
|---|---|---|
/opt/yourls/mysql | /var/lib/mysql | MySQL 全部数据文件(实验实测约 202MB:系统库 + yourls 三张表) |
/opt/yourls/user | /var/www/html/user | YOURLS 用户层:config.php、plugins/、pages/、languages/ |
首次启动后 /opt/yourls/user 会被 entrypoint 写入以下文件(实测 ls /opt/yourls/user):
config-container.php
config-sample.php
config.php
index.html
languages
pages
plugins
其中 config.php 是由环境变量生成的实际生效配置(内容为读取 YOURLS_* 环境变量的 PHP 代码),config-container.php 是镜像内置的容器适配引导文件。不要再手工编辑 config.php 覆盖环境变量——容器化形态下配置的唯一事实来源是 compose 的 environment 段;要自定义环境变量覆盖不到的高级参数,做法是在 user/ 下放置自定义 PHP 或构建派生镜像,见下一节。
持久化验证:重启栈后数据不丢:
docker compose restart && sleep 10 && curl -s -o /dev/null -w '%{http_code}\n' http://192.168.1.200:8134/quzuo
实测回显(重启后短链依然 301):
301
六、环境变量表
YOURLS 官方镜像的全部环境变量(来源:docker-library 官方镜像文档与镜像内 entrypoint 实测,2026-10-30):
| 环境变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
YOURLS_SITE | 是 | 无 | 站点 URL,小写、无末尾斜杠;决定短链域名前缀 |
YOURLS_USER | 是 | 无 | 管理账号用户名 |
YOURLS_PASS | 是 | 无 | 管理账号密码 |
YOURLS_DB_HOST | 否(有 mysql 服务时必填) | mysql | 数据库主机,非标端口写 host:port |
YOURLS_DB_USER | 否 | root | 数据库用户名 |
YOURLS_DB_PASS | 否 | 空 | 数据库密码 |
YOURLS_DB_NAME | 否 | yourls | 数据库名,需预先创建 |
YOURLS_DB_PREFIX | 否 | yourls_ | 表前缀 |
YOURLS_UNIQUE_URLS | 否 | true | 同一长链是否只允许一条短链 |
YOURLS_URL_CONVERT | 否 | 36 | 短码进制:36 纯小写 / 62 区分大小写 |
YOURLS_PRIVATE | 否 | true | 私密模式(后台登录 + API 鉴权) |
YOURLS_COOKIEKEY | 否 | 自动随机 | cookie 加密盐 |
YOURLS_HOURS_OFFSET | 否 | 0 | 时区偏移小时数 |
YOURLS_LANG | 否 | 空 | 界面语言(翻译文件放 user/languages/) |
YOURLS_DEBUG | 否 | false | 调试模式 |
YOURLS_NO_VERSION_CHECK | 否 | true | 是否禁用版本更新检查 |
YOURLS_NOSTATS | 否 | false | 是否禁用统计功能 |
此外,以上变量全部支持 <名>_FILE 后缀形式(如 YOURLS_DB_PASS_FILE=/run/secrets/db_pass),从文件读取敏感值以对接 Docker Secrets——这是官方镜像文档明确列出的支持清单(YOURLS_DB_HOST/USER/PASS/NAME/PREFIX/SITE/USER/PASS 八项)。
七、配置参数说明与配置文件挂载
容器化 YOURLS 的配置分三层:
- 环境变量层(compose
environment):覆盖user/config.php的绝大多数开关,是首选配置入口,变量全集见上表; - user/ 目录挂载层:
/opt/yourls/user挂到容器/var/www/html/user,可放入插件(plugins/)、静态页(pages/)、翻译(languages/);YOURLS 官方镜像文档注明插件/页面/语言分别放入上述子目录后在后台启用,并保证读写执行权限; - 高级常量层:极少数环境变量不覆盖的常量(如
YOURLS_COOKIEKEY显式固定值)可在 compose 里直接给值;若需在config.php之外追加 PHP 级定制(钩子、过滤器),可挂载自定义 PHP 文件进user/并由 YOURLS 加载机制引入。裸机形态下手工编辑user/config.php的完整参数说明,见本专栏 《YOURLS 1.10.6 配置参数详解》。
八、等价 docker run
不使用 compose 时,以下两条 docker run 等价于第四节的编排(先建网络,后起库与应用):
docker network create --subnet 10.89.59.0/24 yourls-net
实测回显(已存在时):
Error response from daemon: network with name yourls-net already exists
# 1. 启动 MySQL
docker run -d --name yourls-1.10.6-mysql \
--network yourls-net \
-e MYSQL_ROOT_PASSWORD="q1w2e3r4" \
-e MYSQL_DATABASE="yourls" \
-e MYSQL_USER="yourls" \
-e MYSQL_PASSWORD="q1w2e3r4" \
-v /opt/yourls/mysql:/var/lib/mysql \
mysql:8.0
# 2. 启动 YOURLS
docker run -d --name yourls-1.10.6-web \
--network yourls-net \
-p 8134:8080 \
-e YOURLS_SITE="http://192.168.1.200:8134" \
-e YOURLS_USER="admin" \
-e YOURLS_PASS="q1w2e3r4" \
-e YOURLS_DB_HOST="mysql" \
-e YOURLS_DB_USER="yourls" \
-e YOURLS_DB_PASS="q1w2e3r4" \
-e YOURLS_DB_NAME="yourls" \
-v /opt/yourls/user:/var/www/html/user \
yourls:1.10.6
启动后的安装向导、登录、建链步骤与 4.4–4.6 完全一致。
九、常用运维命令与常见问题
常用运维命令:
docker compose ps # 查看双服务状态
docker compose logs -f yourls # 跟踪 YOURLS 日志
docker compose restart yourls # 只重启 YOURLS
docker compose down # 停止并移除(数据在宿主机目录,不受影响)
docker compose pull && docker compose up -d # 升级:改 yml 中 image tag 后拉新启动
常见问题(含实测排障实录):
Q1:根路径访问 403 Forbidden?
安装完成前根路径必然 403(短链表不存在),从 /admin/ 进安装向导即可;安装完成后根路径就是短链跳转入口,不存在首页。
Q2:登录后又被 301 踢回登录页,cookie 不生效?
排障实录:实测中用 http://localhost:8134/admin/index.php 提交登录,返回 301 redirect:http://192.168.1.200:8134/admin/index.php——YOURLS 把请求重定向到 YOURLS_SITE 定义的站点地址,而 localhost 访问与站点地址不一致导致会话 cookie 域不匹配。解决:始终用与 YOURLS_SITE 完全一致的地址访问(本例为 http://192.168.1.200:8134),换用正式域名时同步修改 YOURLS_SITE 并重启。
Q3:YOURLS 容器反复重启或日志报数据库连接失败?
MySQL 首次初始化(生成数据目录)需要 20–40 秒,YOURLS entrypoint 会等待数据库就绪;若仍失败,检查 YOURLS_DB_HOST/USER/PASS 与 mysql 服务的 MYSQL_USER/MYSQL_PASSWORD 是否一一对应、MYSQL_DATABASE 是否与 YOURLS_DB_NAME 一致(本编排均为 yourls)。
Q4:启动日志出现 AH00558: apache2: Could not reliably determine the server's fully qualified domain name?
无害警告,Apache 未配置全局 ServerName 时的标准提示,YOURLS 功能不受影响;介意可在 compose 加自定义 Apache 配置挂载消除。
Q5:API 返回 {"message":"Please log in","errorCode":"403"}?
私密模式(YOURLS_PRIVATE=true 默认开启)下 API 必须带凭据(username/password 参数或 signature 签名),认证方式详见本专栏 《YOURLS 1.10.6 API 使用详解》。
Q6:创建重复长链报 409?
1.10.5 起重复长 URL 返回 HTTP 409 Conflict(旧版为 400),属预期行为;需要同一长链多条短链时把 YOURLS_UNIQUE_URLS 设为 false(本编排已如此配置)。
十、参考链接
- 官方文档:https://yourls.org/docs/
- Docker 官方镜像:https://hub.docker.com/_/yourls
- 镜像文档源(docker-library/docs):https://github.com/docker-library/docs/tree/master/yourls
- 站内关联:《YOURLS 1.10.6 介绍与选型指南》、《YOURLS 1.10.6 配置参数详解》、《YOURLS 1.10.6 API 使用详解》