“把麻烦留给自己,把方便留给别人”
,这才是我们折腾的终极目标。在上一篇中YesPlayMusic
虽然能用,但是需要安装两个镜像,总归还是不算方便,更何况还有不完美的公网访问。经过老苏的不懈努力,v2
版实现了将播放器和API
集成在一个镜像中,成功解决了:
v1
版不能刷新页面的问题公网反代的问题可以连接到Last.me
支持上传云盘
构建镜像
如果你不想自己构建,可以跳过,直接阅读下一章节
折腾bypy
时学习的supervisor
让老苏有了新的想法,那就是把前端播放器、后端API
、nginx
整到一个容器中,把群晖上没完成的事情尝试在容器中搞定,所以就有了本文
前端继续还是采用占位符的方式,老苏还是保留了变量,原本是可以将VUE_APP_NETEASE_API_URL
写死为/api
的参考了网易 API
官方的Dockerfile
,所以没有像第一版使用nginx:1.12-alpine
做基础镜像,而是用了node:lts-alpine
,并在其中安装了一个nginx
FROM node:16.5 as build-depsLABEL maintainer=laosu<wbsu@># environmentENV VUE_APP_NETEASE_API_URL netease_vanauENV VUE_APP_ELECTRON_API_URL netease_vaeauxENV VUE_APP_ELECTRON_API_URL_DEV netease_vaeaudENV VUE_APP_LASTFM_API_KEY netease_valakENV VUE_APP_LASTFM_API_SHARED_SECRET netease_valassENV DEV_SERVER_PORT netease_dspWORKDIR /app#COPY package.json yarn.lock ./#RUN yarnRUN TMPDIR=/tmp yarn install#RUN yarn config set registry "https://registry./" \# && TMPDIR=/tmp yarn installCOPY . ./RUN yarn buildFROM node:lts-alpineRUN apk update \&& apk add --no-cache supervisor openssh nginxCOPY --from=build-deps /app/dist /usr/share/nginx/htmlCOPY --from=build-deps /app/supervisord.conf /etc/supervisord.conf# nginxCOPY --from=build-deps /app/default.conf /etc/nginx/conf.d/default.confCOPY --from=build-deps /app/nginx.conf /etc/nginx/nginx.confRUN mkdir -p /usr/local/nginx/logs# api serverWORKDIR /apiCOPY --from=build-deps /app/netease_api/. /apiCOPY --from=build-deps /app/replace_api_url.sh /apiRUN chmod +x replace_api_url.shRUN npm config set registry "https://registry./" \&& npm install --production# CMD ["sh", "replace_api_url.sh"]ENTRYPOINT ["supervisord","-c","/etc/supervisord.conf"]EXPOSE 80
replace_api_url.sh
用于替换ENV
设置的占位符
这个和第一版是一样的
#!/usr/bin/env shfind '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_vanau,'"$VUE_APP_NETEASE_API_URL"',g' {} \;find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_vaeaux,'"$VUE_APP_ELECTRON_API_URL"',g' {} \;find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_vaeaud,'"$VUE_APP_ELECTRON_API_URL_DEV"',g' {} \;find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_valak,'"$VUE_APP_LASTFM_API_KEY"',g' {} \;find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_valass,'"$VUE_APP_LASTFM_API_SHARED_SECRET"',g' {} \;find '/usr/share/nginx/html' -name '*.js' -exec sed -i -e 's,netease_dsp,'"$DEV_SERVER_PORT"',g' {} \;nginx -g "daemon off;"
supervisord.conf
文件是新增用来控制进程的,前端app
是运行在nginx
上的静态页面,后端api
基于node.js
[include]files = /etc/supervisor/conf.d/*.conf[program:app]command=./replace_api_url.sh[program:api]command=node app.js#directory will be any folder where you wnat supervisor to cd before executing.#directory=/project autostart=trueautorestart=falsestartretries=3#user will be anyone you want but make sure that user will have the enough privilage.user=root[supervisord]nodaemon=truelogfile=/tmp/supervisord.logpidfile=/tmp/supervisord.pidloglevel=debuglogfile_maxbytes=10MB[supervisorctl]
nginx
设置文件nginx.conf
镜像中的位置
/etc/nginx/nginx.conf
,比默认的nginx.conf
文件多一行pid /usr/local/nginx/logs/nginx.pid;
,如果没有会出现错误:nginx: [emerg] open() "/run/nginx/nginx.pid" failed (2: No such file or directory)
# /etc/nginx/nginx.confuser nginx;pid /usr/local/nginx/logs/nginx.pid; # Set number of worker processes automatically based on number of CPU cores.worker_processes auto;# Enables the use of JIT for regular expressions to speed-up their processing.pcre_jit on;# Configures default error logger.error_log /var/log/nginx/error.log warn;# Includes files with directives to load dynamic modules.include /etc/nginx/modules/*.conf;events {# The maximum number of simultaneous connections that can be opened by# a worker process.worker_connections 1024;}http {# Includes mapping of file name extensions to MIME types of responses# and defines the default type.include /etc/nginx/mime.types;default_type application/octet-stream;# Name servers used to resolve names of upstream servers into addresses.# It's also needed when using tcpsocket and udpsocket in Lua modules.#resolver 208.67.222.222 208.67.220.220;# Don't tell nginx version to clients.server_tokens off;# Specifies the maximum accepted body size of a client request, as# indicated by the request header Content-Length. If the stated content# length is greater than this size, then the client receives the HTTP# error code 413. Set to 0 to disable.client_max_body_size 1m;# Timeout for keep-alive connections. Server will close connections after# this time.keepalive_timeout 65;# Sendfile copies data between one FD and other from within the kernel,# which is more efficient than read() + write().sendfile on;# Don't buffer data-sends (disable Nagle algorithm).# Good for sending frequent small bursts of data in real time.tcp_nodelay on;# Causes nginx to attempt to send its HTTP response head in one packet,# instead of using partial frames.#tcp_nopush on;# Path of the file with Diffie-Hellman parameters for EDH ciphers.#ssl_dhparam /etc/ssl/nginx/dh2048.pem;# Specifies that our cipher suits should be preferred over client ciphers.ssl_prefer_server_ciphers on;# Enables a shared SSL cache with size that can hold around 8000 sessions.ssl_session_cache shared:SSL:2m;# Enable gzipping of responses.#gzip on;# Set the Vary HTTP header as defined in the RFC 2616.gzip_vary on;# Enable checking the existence of precompressed files.#gzip_static on;# Specifies the main log format.log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';# Sets the path, format, and configuration for a buffered log write.access_log /var/log/nginx/access.log main;# Includes virtual hosts configs.include /etc/nginx/conf.d/*.conf;}
nginx
设置文件default.conf
镜像中的位置
/etc/nginx/conf.d/default.conf
,将/api
转发给后端处理
server{listen 80;server_name default_serve; # 配置项目域名root /usr/share/nginx/html;index index.html index.htm;# 1.转给前端处理location / {# 前端打包后的静态目录alias /usr/share/nginx/html/;# 解决页面刷新404问题try_files $uri $uri/ /index.html;# 处理上传文件大小client_max_body_size 1000m;}# 2.转给后端处理location ^~ /api/ {proxy_pass http://127.0.0.1:3000/;# 处理上传文件大小client_max_body_size 1000m;}}
构建镜像和容器运行的基本命令如下👇
# 下载代码,当前对应的是 0.4.1git clone /qier222/YesPlayMusic.git# 或者镜像站点git clone /qier222/YesPlayMusic.git# 进入目录cd YesPlayMusic# 将 Dockerfile 、 replace_api_url.sh 、supervisord.conf、nginx.conf 、default.conf 五个文件放进代码目录中# 构建镜像docker build -t wbsu/yesplaymusic:v2 .# 生成容器docker run -d \--name=yesplaymusic \-p 3310:80 \-e VUE_APP_NETEASE_API_URL=/api \-e VUE_APP_LASTFM_API_KEY=<your Last.fm API KEY> \-e VUE_APP_LASTFM_API_SHARED_SECRET=<your Last.fm API SHARED SECRET> \wbsu/yesplaymusic:v2# --------调试-------------# 进入容器docker exec --user root -it yesplaymusic /bin/sh# 将生成的静态文件拷贝到容器外docker cp yesplaymusic:/usr/share/nginx/html/. ./dist# 将生成的静态文件拷贝到容器内docker cp /dist/. yesplaymusic:/usr/share/nginx/html# ------------------------
安装
注册表中搜索wbsu
,找到wbsu/yesplaymusic
,版本选latest
。
如果你之前已经安装过
YesPlayMusic
,建议先删除老版本的容器和镜像再进行安装
端口
端口不冲突就行
环境
如果你还没有
Last.fm
账号,可以去 https://www.last.fm/api/account/create 创建一个API
帐户。
老苏没有填Callback URL
如果你已经创建好了,需要查询可以去 https://www.last.fm/api/accounts 找到你的
API Applications
运行
在浏览器中输入http://群晖IP:3310
就能看到主界面
第三方授权
在设置
-->第三方
-->连接 Last.fm
-->授权连接
在跳转页面选择YES ALLOW ACCESS
进行授权
授权之后会显示成功
点完成
,能看到连接的Last.fm
账号
反代
反代已经没问题了
说明
文中提到的文件,都可以在 /wbsu/Dockerfile 找到
个人精力有限,很难做全面的测试,如果你发现有什么问题,请反馈给老苏,反馈方式:
给公众号发消息。虽然老苏的公众号并不支持留言,并且还有很多限制,但聊胜于无点『 阅读原文 』 去老苏的博客 (https://laosu.ml) 留言发邮件:wbsu@、wbsu@
参考文档
qier222/YesPlayMusic: 高颜值的第三方网易云播放器,支持 Windows / macOS / Linux
地址:/qier222/YesPlayMusic
Binaryify/NeteaseCloudMusicApi: 网易云音乐 Node.js API service
地址:/Binaryify/NeteaseCloudMusicApi
Bug. Yarn couldn’t build package phantomjs. npm could. · Issue #1016 · yarnpkg/yarn
地址:/yarnpkg/yarn/issues/1016
单机,前后端分离,Nginx反向代理 - 简书
地址:/p/3c2c3f64f1ad
Nginx代理同域名前后端分离项目 | Laravel China 社区
地址:/articles/50668