https://pages.github.com/
https://vercel.com
这里 只能输入 公开的仓库地址
下面在 GitHub 私有仓库,利用 GitHub App 来安装 Vercel, 更新: 错误,
GitHub Marketplace
没有Vercel App
, 通过下方来导入私有仓库
目测只能创建完后,修改分支
更新: 可以通过修改下方链接来创建 Project, 这样创建时就能自定义分支
https://vercel.com/new/clone?repository-url=https://github.com/yiyungent/yiyungent.github.io/tree/gh-pages
修改 branch 为
gh-pages
由于直接使用
gh-pages
构建好的结果,因此下方直接置空
现在流程,本地改完后,push 到 GitHub主分支 ( master ),然后触发
GitHub Actions
构建完成到gh-pages
, 然后这会触发两次 Vercel 的Deployment
, 第一次 来自master
, 第二次来自GitHub Actions
推送到的gh-pages
, 第一次是不正确的,会导致 404, 第二次即可正常访问
完成
https://yiyungent.vercel.app/ https://yiyungent-yiyungent.vercel.app/ https://yiyungent-git-gh-pages-yiyungent.vercel.app/
https://pages.cloudflare.com/
完成
https://yiyungent.pages.dev/
https://www.netlify.com/
完成
https://yiyungent.netlify.app
参考:
https://railway.app/button
参考:
app.json
: 模板描述, 环境变量heroku.yml
: 如何 buildbuild:
docker:
web: docker/Dockerfile
{
"name": "PanIndex",
"description": "简易的网盘目录列表",
"keywords": [
"PanIndex", "cloud.189.cn", "teambition"
],
"env": {
"TZ": {
"description": "时区",
"value": "Asia/Shanghai"
},
"LANG": {
"description": "编码格式",
"value": "en_US.UTF-8"
},
"PAN_INDEX_VERSION": {
"description": "PanIndex版本,默认为最新版,查看:https://github.com/libsgh/PanIndex/releases",
"required": false,
"value": ""
},
"PAN_INDEX_CONFIG": {
"description": "程序配置,json格式,从后台获取复制到这里",
"required": false,
"value": ""
},
"PAN_INDEX_DEBUG": {
"description": "调试模式,设置为true将输出更多日志",
"value": "false"
}
},
"website": "http://github.com/libsgh/PanIndex",
"repository": "http://github.com/libsgh/PanIndex",
"stack": "container",
"features": [
"runtime-dyno-metadata"
]
}
最后生成效果:
https://heroku.com/deploy?template=https://github.com/libsgh/PanIndex
https://www.koyeb.com/
https://fly.io/
https://render.com/
参考:
若以仓库根目录为模板, 则
Dockerfile
必须位于仓库根目录仓库根目录/Dockerfile
# Railway Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
# ...
# for Railway
WORKDIR /app
ADD railway-entrypoint.sh ./railway-entrypoint.sh
RUN chmod +x ./railway-entrypoint.sh
# ...
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
#ENTRYPOINT ["dotnet", "WebScreenshot.dll"]
ENTRYPOINT ["/bin/sh", "./railway-entrypoint.sh"]
仓库根目录/railway-entrypoint.sh
#!/bin/sh
# 注意: $PORT 非常重要, Railway 必须监听此端口
export ASPNETCORE_URLS="http://+:$PORT"
export ASPNETCORE_ENVIRONMENT="Production"
export TZ="Asia/Shanghai"
dotnet WebScreenshot.dll
参考:
仓库根目录/app.json
{
"name": "Squidex",
"description": "Headless CMS and Content Managment Hub",
"website": "https://squidex.io/",
"repository": "https://github.com/Squidex/squidex",
"logo": "https://avatars.githubusercontent.com/u/25371797?s=200&v=4",
"success_url": "/",
"env": {
"DOMAIN": {
"description": "The domain name under which your instance is available",
"value": "https://[YOUR-HEROKU-APPNAME].herokuapp.com"
},
"MONGO_USERNAME": {
"description": "Mongo Username, follow https://devcenter.heroku.com/articles/ormongo#open-the-dashboard to create a database named Squidex and then edit the deployment to reflect the credentials you used",
"value": "Squidex"
},
"MONGO_PASSWORD": {
"description": "Mongo Password (see MONGO_USERNAME)",
"value": "Squidex123"
}
},
"formation": {
"web": {
"quantity": 1,
"size": "standard-1x"
}
},
"addons": [
{
"plan": "ormongo:2-mmap",
"as": "MONGO"
}
],
"stack": "container"
}
仓库根目录/heroku.yml
build:
docker:
web: packer/heroku/squidex/Dockerfile
PS:
heroku.yml
: If you don’t include arun
section, Heroku uses theCMD
specified in theDockerfile
.
需要注意 2 点: - Heroku Docker 容器内部应用需要监听
$PORT
端口 - Heroku 对ENTRYPOINT [ "dotnet", "HerokuApp.dll" ]
支持不好, 建议CMD [ "dotnet", "HerokuApp.dll" ]
, 或则在ENTRYPOINT
运行 bash
# Heroku Dockerfile
# ENTRYPOINT [ "dotnet", "HerokuApp.dll" ]
# Use the following instead for Heroku
CMD ASPNETCORE_URLS=http://*:$PORT dotnet HerokuApp.dll
在程序中写死监听端口
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
// For running in Railway
var portVar = Environment.GetEnvironmentVariable("PORT");
if (portVar is {Length: >0} && int.TryParse(portVar, out int port))
{
webBuilder.ConfigureKestrel(options =>
{
options.ListenAnyIP(port);
});
}
});
# Heroku Dockerfile
CMD [ "dotnet", "HerokuApp.dll" ]
heroku.yml
build:
docker:
web: deploy/heroku/Dockerfile
deploy/heroku/Dockerfile
# Heroku Dockerfile
FROM yiyungent/webscreenshot:latest
ADD heroku-entrypoint.sh /heroku-entrypoint.sh
RUN chmod +x /heroku-entrypoint.sh
ENTRYPOINT ["/bin/sh", "/heroku-entrypoint.sh"]
deploy/heroku/heroku-entrypoint.sh
#!/bin/sh
export ASPNETCORE_URLS="http://+:$PORT"
dotnet WebScreenshot.dll
heroku.yml
注意: 此种方法,
Docker build context
位于src/WebApi/
, 而不是仓库根目录
build:
docker:
web: src/WebApi/Dockerfile
run:
web: cd /app && dotnet WebApi.dll --urls="http://*:$PORT"
参考:
参考:
fly.io 与其它不一样,没有 Web 可视化面板,只能用 CLI 来创建 App
Windows: PowerShell
iwr https://fly.io/install.ps1 -useb | iex
flyctl auth login
参考:
flyctl info
flyctl status
flyctl logs
参考:
在
Dockerfile
目录执行
fly launch
注意: 这里 Railway 的 Dockerfile 没有放在仓库根目录,因此 template 需指定为子目录 https://github.com/yiyungent/Dragonfly/tree/main/deploy/railway
Dockerfile
# Railway Dockerfile
# 注意: yiyungent/dragonfly:latest railway 会一直使用缓存,不会更新镜像
FROM yiyungent/dragonfly:v0.1.1
ADD railway-entrypoint.sh ./railway-entrypoint.sh
RUN chmod +x ./railway-entrypoint.sh
ADD railway-PluginCore.Config.json ./railway-PluginCore.Config.json
ENTRYPOINT ["/bin/sh", "./railway-entrypoint.sh"]
railway-entrypoint.sh
#!/bin/sh
# region env
export ASPNETCORE_URLS="http://+:$PORT"
export ASPNETCORE_ENVIRONMENT="Production"
export TZ="Asia/Shanghai"
# endregion env
# region PluginCore
echo ${PLUGINCORE_ADMIN_USERNAME}
echo ${PLUGINCORE_ADMIN_PASSWORD}
mkdir App_Data
touch /app/App_Data/PluginCore.Config.json
cat '/app/railway-PluginCore.Config.json' | sed "s/PLUGINCORE_ADMIN_USERNAME/${PLUGINCORE_ADMIN_USERNAME}/g" | tee '/app/App_Data/PluginCore.Config.json'
cat '/app/App_Data/PluginCore.Config.json' | sed "s/PLUGINCORE_ADMIN_PASSWORD/${PLUGINCORE_ADMIN_PASSWORD}/g" | tee '/app/App_Data/PluginCore.Config.json'
# endregion PluginCore
dotnet WebApi.dll
railway-PluginCore.Config.json
{"Admin":{"UserName":"PLUGINCORE_ADMIN_USERNAME","Password":"PLUGINCORE_ADMIN_PASSWORD"},"FrontendMode":"LocalEmbedded","RemoteFrontend":"https://cdn.jsdelivr.net/gh/yiyungent/plugincore-admin-frontend@0.3.0/dist-cdn","PluginWidgetDebug":false}
Dockerfile
# Heroku Dockerfile
FROM yiyungent/dragonfly:v0.1.1
ADD heroku-entrypoint.sh ./heroku-entrypoint.sh
RUN chmod +x ./heroku-entrypoint.sh
ADD heroku-PluginCore.Config.json ./heroku-PluginCore.Config.json
ENTRYPOINT ["/bin/sh", "./heroku-entrypoint.sh"]
heroku-entrypoint.sh
#!/bin/sh
# region env
export ASPNETCORE_URLS="http://+:$PORT"
export ASPNETCORE_ENVIRONMENT="Production"
export TZ="Asia/Shanghai"
# endregion env
# region PluginCore
echo ${PLUGINCORE_ADMIN_USERNAME}
echo ${PLUGINCORE_ADMIN_PASSWORD}
mkdir App_Data
touch /app/App_Data/PluginCore.Config.json
cat '/app/heroku-PluginCore.Config.json' | sed "s/PLUGINCORE_ADMIN_USERNAME/${PLUGINCORE_ADMIN_USERNAME}/g" | tee '/app/App_Data/PluginCore.Config.json'
cat '/app/App_Data/PluginCore.Config.json' | sed "s/PLUGINCORE_ADMIN_PASSWORD/${PLUGINCORE_ADMIN_PASSWORD}/g" | tee '/app/App_Data/PluginCore.Config.json'
# endregion PluginCore
dotnet WebApi.dll
heroku-PluginCore.Config.json
{"Admin":{"UserName":"PLUGINCORE_ADMIN_USERNAME","Password":"PLUGINCORE_ADMIN_PASSWORD"},"FrontendMode":"LocalEmbedded","RemoteFrontend":"https://cdn.jsdelivr.net/gh/yiyungent/plugincore-admin-frontend@0.3.0/dist-cdn","PluginWidgetDebug":false}
app.json
{
"name": "Dragonfly",
"description": "Web 自动化平台 - Heroku Deploy",
"keywords": ["yiyungent", "Dragonfly"],
"website": "https://github.com/yiyungent/Dragonfly",
"repository": "https://github.com/yiyungent/Dragonfly",
"success_url": "/",
"env": {
"PLUGINCORE_ADMIN_USERNAME": {
"description": "PluginCore Admin 用户名",
"value": "admin",
"required": true
},
"PLUGINCORE_ADMIN_PASSWORD": {
"description": "PluginCore Admin 密码",
"value": "Dragonfly",
"required": true
}
},
"stack": "container"
}
heroku.yml
build:
docker:
web: deploy/heroku/Dockerfile