Docker 部署 Hexo
起因:由于云服务器经常改变,导致云服务器上需要不断部署,为了不重复工作,这里使用 Docker 部署 Hexo 以后可以不用重复部署,只需要将数据转移即可
技术栈&准备工作 所用到的技术:
准备工作: 这里的工作主要是需要购买一台云服务器,域名,服务器上需要有Docker
、vim
、Docker Compose
目录结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 . ├── data │ ├── blog_files │ │ └── hexo │ ├── conf.d │ ├── ssl │ │ └── certs │ └── twikoo_data ├── docker-compose.yml ├── nginx_dockerfile │ ├── Dockerfile │ ├── hexo.conf │ ├── init_https.sh │ ├── init_pwd.sh │ ├── start.sh │ └── twikoo.conf └── test.sh
docker-compose.yml 容器编排配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 version: '3' services: nginx: build: ./nginx_dockerfile ports: - "80:80" - "443:443" - "2333:22" volumes: - "./data/blog_files/hexo:/var/www/hexo" - "./data/ssl/certs:/etc/letsencrypt/" - "./data/conf.d:/etc/nginx/conf.d" environment: - PASSWD={your_password} - EMAIL={your_email} - DOMAIN={your_domain} container_name: "nginx" twikoo: image: imaegoo/twikoo container_name: "twikoo" restart: unless-stopped ports: - "8099:8080" environment: TWIKOO_THROTTLE: 1000 volumes: - "./data/twikoo_data:/app/data"
nginx
中,构建文件夹是./nginx_dockerfile
使用了三个端口映射 80
端口接收 http
请求,443
端口处理 https
,这里将宿主机2333
映射到 容器的22
端口解决 ssh 连接问题
将博客源文件、SSL证书、nginx的配置文件挂载到数据盘,以实现数据的持久化,以及容器的初始时的无状态
注意这里的 volums 如果是将空的宿主机的目录挂载到容器内部的一个不为空的目录,则容器内部数据会被覆盖,也就是覆盖为空
并且设置 PASSWD
EMAIL
DOMAIN
三个环境变量,来初始化容器内部的 root 初始密码,邮箱(申请https需要的),域名
到这一步需要做的是将宿主机的 2333 和 8099 端口暴露出来,并且在 之后的 ssh 连接以及指定 ssh key 的时候需要指定端口名
为 -p 2333
Nginx 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 FROM nginx:latestRUN sed -i "s@http://deb.debian.org@http://mirrors.aliyun.com@g" /etc/apt/sources.list.d/debian.sources \ && rm -Rf /var/lib/apt/lists/* \ && apt-get update RUN apt-get install -y git certbot python3-certbot-nginx expect openssh-server net-tools \ && mkdir /var/repo/ \ && chmod -R 755 /var/repo/ \ && git init --bare /var/repo/resinceBlog.git \ && echo "git --work-tree=/var/www/hexo --git-dir=/var/repo/resinceBlog.git checkout -f" > /var/repo/resinceBlog.git/hooks/post-receive \ && chmod +x /var/repo/resinceBlog.git/hooks/post-receive \ && mkdir -p /var/www/hexo \ && chmod -R 755 /var/www/hexo \ && mkdir -p ~/.ssh \ && touch ~/.ssh/authorized_keys \ && chmod 700 ~/.ssh/ \ && chmod 600 ~/.ssh/authorized_keys \ && echo "PubkeyAuthentication yes" >> /etc/ssh/sshd_config \ && echo "PermitRootLogin yes" >> /etc/ssh/sshd_config \ && echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config \ && echo "AuthorizedKeysFile .ssh/authorized_keys" >>/etc/ssh/sshd_config \ && mkdir /run /sshd COPY hexo.conf /root/init_file/hexo.conf COPY twikoo.conf /root/init_file/twikoo.conf COPY start.sh /docker-entrypoint.d/start.sh COPY init_pwd.sh /root/init_file/init_pwd.sh COPY init_https.sh /root/init_file/init_https.sh RUN chmod +x /docker-entrypoint.d/start.sh \ && apt-get install -y expect \ && apt-get install -y tcl EXPOSE 80 EXPOSE 443 EXPOSE 22
其中 Configure git and nginx
的大部分配置来自原本部署服务器端的命令,具体可以看我之前的博客:博客搭建(一) | Resince 之后的配置 sshd 文件是将宿主机的部分选项打开,比如允许 root 用户登录,允许使用 ssh key 登录
注意:
在这份镜像中,apt的配置文件是在 /etc/apt/sources.list.d/debian.sources
中,而不是在 /etc/apt/sources.list/
文件中
初始化 nginx 配置这一步是为了防止直接转移到 /etc/nginx/conf.d
文件夹后,被后来的数据盘覆盖 ,为了将数据放在配置文件夹中,我们在 start.sh
入口文件中,将配置文件转移到conf.d
文件夹中
关于覆盖问题具体可以看 dockerfile使用COPY覆盖父镜像定义的volume
entrypoint file
中有两个关键点
首先为了容器数据的初始化,需要 .sh
脚本 以及expert
来处理比如密码初始化,以及https
的申请等,这个在 dockerfile
中不支持实现
其次为什么不直接将 start.sh
设置为 ENTERYPOINT
呢,原因是由于这样会直接覆盖之前的入口点配置,导致功能不完整,而在 nginx
的这份镜像中,就有设置有入口配置文件夹 /docker-entrypoint.d
所以只需要将初始化文件转移到对应文件夹即可
nginx config hexo.conf
1 2 3 4 5 6 7 8 9 server { listen 80; server_name resince.fun; location / { root /var/www/hexo; index index.html index.htm; } }
twikoo.conf
1 2 3 4 5 6 7 8 9 10 11 12 upstream twi { server resince.fun:8099; } server { listen 80; server_name twikoo.resince.fun; location / { proxy_pass http://twi; } }
以上是简单的nginx
文件配置
entrypoint file start.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #!/bin/sh /usr/sbin/sshd if [ -z "$(ls -A /etc/nginx/conf.d) " ]then mv /root/init_file/twikoo.conf /etc/nginx/conf.d/twikoo.conf mv /root/init_file/hexo.conf /etc/nginx/conf.d/hexo.conf sed -i "s@resince.fun@$DOMAIN @g" /etc/nginx/conf.d/hexo.conf sed -i "s@resince.fun@$DOMAIN @g" /etc/nginx/conf.d/twikoo.conf else echo "conf.d is empty" fi if [ $PASSWD ]then chmod +x /root/init_file/init_pwd.sh ./root/init_file/init_pwd.sh unset PASSWD else echo "you need init password by yourself" fi chmod +x /root/init_file/init_https.sh./root/init_file/init_https.sh exit 0
init_pwd.sh
1 2 3 4 5 6 7 8 #!/usr/bin/expect -f set PASSWD $env (PASSWD)spawn passwd expect "New password:" send "$PASSWD \r" expect "Retype new password:" send "$PASSWD \r" expect eof
init_https.sh
1 2 3 4 5 6 7 8 9 10 11 #!/usr/bin/expect -f set EMAIL $env (EMAIL)set DOMAIN $env (DOMAIN)spawn certbot --nginx expect { "Enter email address" { send "$EMAIL \n" ;exp_continue} "Please read the Terms of Service" {send "y\n" ;exp_continue} "Would you be willing, once your first certificate is successfully issued" {send "N\n" ;exp_continue} "Select the appropriate numbers separated by commas and/or spaces" {send "\n" } eof }
以上是使用 expect
来对交互式命令进行自动化处理
需要注意的是这里是使用 certbot
申请 https 证书,这里需要你将 DNS 解析配置好,并且证书的申请每周有固定次数(不要想我一样,重复删除建立容器导致达到次数上限)
启动 在对应文件夹下输入
再进入容器,按照test.sh
的命令输入一遍即可
test.sh的命令就是简单的生成 https
还需要你本地的电脑生成ssh key
并发送到对应的容器中
1 ssh-copy-id -i ~/.ssh/id_rsa -p 2333 username@ip # 这里要指定端口
最后直接 hexo d
即可
注意这里没有写 certbot
的自动重新申请证书,大概三个月需要自己进入容器,执行
转移 之后有新的云主机,只需要复制一份 docker-compose.yml
,并把原来的 data
文件转移即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 version: '3' services: nginx: image: resince/hexo-server ports: - "80:80" - "443:443" - "2333:22" volumes: - "./data/blog_files/hexo:/var/www/hexo" - "./data/ssl/certs:/etc/letsencrypt/" - "./data/conf.d:/etc/nginx/conf.d" environment: - PASSWD={your_password} - EMAIL={your_email} - DOMAIN={your_domain} container_name: "nginx" twikoo: image: imaegoo/twikoo container_name: "twikoo" restart: unless-stopped ports: - "8099:8080" environment: TWIKOO_THROTTLE: 1000 volumes: - "./data/twikoo_data:/app/data"
注意打包时需要使用 sudo
将 ssl
的所有文件均打包