一,前言

Docker 建站小记,我使用了四个镜像来搭建:nginx,certbot,mysql,gradle。欢迎访问:https://www.zzk0.top

这个网页是从 github 上找的个人主页,背景用的是 bing 的壁纸,中间有两个链接,一个指向我的 github,一个指向博客园。后端项目目前只有一个接口,当有人访问这个网站的时候,就会向后端项目发出一个请求,由 nginx 负责将对 api.zzk0.top 的请求转发到后端项目。

最理想的状态是,我直接 docker-compose up,我就可以将项目运行起来了。不过我的方法,需要自己手动配置一下才行,一个是初始化申请 SSL 的脚本,一个是定时分割 NGINX 日志。之后就只需要 docker-compose up 就行了。

这里简单讲讲这四个镜像分别是干什么的吧。

  • nginx,这个是 http 服务器,用来提供提供静态资源的,这篇博客大部分内容都是在讲如何配置 nginx。
  • certbot,这个用来申请 SSL 证书。设置了一个定时任务,每个月刷新一下证书。
  • mysql,后端项目数据库。
  • gradle,编译并运行 springboot 项目。

二,NGINX

重新加载配置

修改了 NGINX 的配置,但是又不想重新启动容器。我们可以通过向容器发送命令来加载新配置。

# docker exec -it your-name nginx -s reload
2021/01/23 02:30:58 [notice] 23#23: signal process started

HTTPS 配置

首先我们需要证书和密钥,我们可以使用免费的 Let's Encrypt 来生成,不过三个月就会过期,所以需要刷新一下。

证书的生成可以选择在本机上还是在 Docker 里,如果在本机上生成,我们可以选择 standalone 模式,但是这样的话,它需要短暂占用一下 80 端口来验证这个域名是否是你的。因此当你有一个正在运行的 NGINX 并且占用了 80 端口的话,我们需要去暂停它。如果在 Docker 中生成,并且你的网站有一个根目录,那么可以使用 webroot 模式,它会在你的网站根目录下生成一些文件,然后通过域名去访问它来验证这个域名是不是你的,使用 webroot 模式就不需要暂停 NGINX,因此对正在运行的网站影响会小一些。

选择前者的好处是,不需要定制 Docker,但是需要短暂停止服务器;选择后者的好处是,不需要停止服务器,可移植性更好一点,本机只需要有 Docker 就能跑,但是需要定制镜像比较麻烦。不过,这种比较常见的需求,我们上 docker hub 搜一搜,一找就有了:https://hub.docker.com/r/staticfloat/nginx-certbot/ 。再搜一搜,我们会发现另一个方案:为什么不搞一个 certbot 的容器呢?然后将 nginx 的容器和 certbot 的容器连接起来!好,那我们就加多一个容器,来帮我们生成 SSL 证书好了。

申请

这篇文章可以参考看看 certbot 的操作。这篇文章提供了 certbot 和 nginx 的方案。

从文章配套的 Github 仓库 中把它的脚本和配置文件复制粘贴过来,把所有的 example.org 域名改成自己的域名,然后运行它的脚本。如果失败了,建议检查一下是不是 NGINX 没有启动。这个脚本不会提醒你 NGINX 没有启动,如果失败了,很有可能是 NGINX 没有配置好。

一开始跑这个脚本,我失败了几次。之后逐步执行脚本,然后启动容器看看什么问题。一看,才知道原来是 https 的推荐参数文件没有下载好,所以手动下载了那几个文件,然后修改脚本为复制而不是下载。

重定向

nginx 将 http 重定向到 https,完整的配置文件可以看附录。

server {
listen 80;
server_name zzk0.top www.zzk0.top;
server_tokens off; location /.well-known/acme-challenge/ {
root /var/www/certbot;
} location / {
return 301 https://$host$request_uri;
}
} server {
listen 443 ssl;
server_name zzk0.top www.zzk0.top;
root /var/www/html;
server_tokens off; ssl_certificate /etc/letsencrypt/live/zzk0.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zzk0.top/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / {
try_files $uri $uri/ =404;
}
}

配置子域名

假设有一个域名 test.com,我们需要将对 api.test.com 的请求转发到 Tomcat,对 test.com 的请求则直接提供静态网站。

这个需求比较简单,在 server 下面设置好 server_name 就可以了。另外,我们还需要注意不要让别人用 ip 访问我们的网站,网上的说法是,别人可以恶意使用未备案的域名指向这个 ip,然后导致网站被封掉了。

server {
listen 80 default_server;
server_name _;
return 403;
} server {
listen 443 default_server;
server_name _;
ssl_certificate /etc/letsencrypt/live/zzk0.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zzk0.top/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 403;
}

访问日志

为了记录网站的访问记录,可以使用 NGINX 的访问日志来做记录,按天分割。NGINX 的镜像里面没有 crontab,所以这里就用主机来做。方法是每天定时将文件重命名,然后 reload NGINX。不过这个部分比较不智能,每次更换主机的时候,都需要手动去配置,还需要修改下面的路径。

#!/bin/sh
LOGS_PATH=/root/home/data/nginx
TODAY=$(date -d 'today' +%Y-%m-%d) mv ${LOGS_PATH}/error.log ${LOGS_PATH}/error_${TODAY}.log
mv ${LOGS_PATH}/access.log ${LOGS_PATH}/access_${TODAY}.log docker exec -i home-nginx nginx -s reload

接下来,将以下内容加入到 /etc/crontab 中,这样就可以执行每日任务了。每天凌晨4点的时候,自动分割日志。

0 4 * * * root /root/home/nginx/daily_log.sh >> /root/home/data/nginx/daily_log.log 2>&1

三,MySQL

有时候我们需要进入数据库的镜像里面去看看数据。

# 进入镜像
docker exec -it your-name bash # 登录
mysql -uroot -p # 罗列数据库
show database

四,后端项目

后端项目使用 SpringBoot 来做。需求是:启动 Docker 后构建源码并运行。这个部分使用 gradle 的镜像,启动的时候,运行 gradle bootRun 就可以了。

当我们更新了后端项目之后,我们只需要重启这个容器,就可以构建了。我的后端项目容器名字叫做 springboot,重启一下就可以将接口更新了,不过重启过程中的请求会失败。

docker restart springboot

下面是 docker-compose.yml 中的配置。

web:
container_name: springboot
restart: always
image: gradle:6.7.1-jdk8
depends_on:
- db
volumes:
- ./api:/home/gradle/project
environment:
TZ : 'Asia/Shanghai'
command: bash -c "cd /home/gradle/project && gradle bootRun"

附录

NGINX 配置

user nginx;
worker_processes 1; error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid; events {
worker_connections 1024;
} http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
upstream tomcat {
server web:8080;
} log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; limit_req_zone $binary_remote_addr zone=api_limit_req:10m rate=30r/m; sendfile on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf; # forbid access via ip address
server {
listen 80 default_server;
server_name _;
return 403;
} server {
listen 443 default_server;
server_name _;
ssl_certificate /etc/letsencrypt/live/zzk0.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zzk0.top/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 403;
} # configure zzk0.top, redirect to https and serve static files
server {
listen 80;
server_name zzk0.top www.zzk0.top;
server_tokens off; location /.well-known/acme-challenge/ {
root /var/www/certbot;
} location / {
return 301 https://$host$request_uri;
}
} server {
listen 443 ssl;
server_name zzk0.top www.zzk0.top;
root /var/www/html;
server_tokens off; ssl_certificate /etc/letsencrypt/live/zzk0.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zzk0.top/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / {
try_files $uri $uri/ =404;
}
} # configure api.zzk0.top, backend api
server {
listen 80;
server_name api.zzk0.top;
server_tokens off; location /.well-known/acme-challenge/ {
root /var/www/certbot;
} location / {
return 301 https://$host$request_uri;
}
} server {
listen 443 ssl;
server_name api.zzk0.top;
server_tokens off; ssl_certificate /etc/letsencrypt/live/zzk0.top/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/zzk0.top/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / {
limit_req zone=api_limit_req;
proxy_pass http://tomcat;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
} }

Docker 配置

version: '3'
services:
certbot:
container_name: home-certbot
restart: always
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 720h & wait $${!}; done;'" nginx:
container_name: home-nginx
restart: always
image: nginx:1.18.0
ports:
- 80:80
- 443:443
depends_on:
- web
links:
- web:web
environment:
TZ : 'Asia/Shanghai'
volumes:
- ./html:/var/www/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
- ./data/nginx:/var/log/nginx
command: "/bin/sh -c 'while :; do sleep 720h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" db:
container_name: home-db
restart: always
image: mysql:8.0.13
ports:
- 7706:3306
volumes:
- ./data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: backend_database
MYSQL_USER: root
MYSQL_PASSWORD: root web:
container_name: springboot
restart: always
image: gradle:6.7.1-jdk8
depends_on:
- db
volumes:
- ./api:/home/gradle/project
environment:
TZ : 'Asia/Shanghai'
command: bash -c "cd /home/gradle/project && gradle bootRun"

Docker 建站小记的更多相关文章

  1. Githun&HEXO建站小记

    title: 建站小记 date: 2018-03-04 11:10:54 updated: 2018-03-06 12:00:00 tags: [hexo,next,建站,学习,前端技术,折腾,博客 ...

  2. 基于ZKEACMS的.Net Core多租户CMS建站系统

    多租户架构 多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下共用相同的系统或程序组件,并且可确保各用户间数据的隔离性.简单讲:在一台服务器上运行单个应用实例,它为 ...

  3. .Net Core 3.0开源可视化设计CMS内容管理系统建站系统

    简介 ZKEACMS,又名纸壳CMS,是可视化编辑设计的内容管理系统.基于.Net Core开发可跨平台运行,并拥有卓越的性能. 纸壳CMS基于插件式设计,功能丰富,易于扩展,可快速创建网站. 布局设 ...

  4. WordPress建站和搭独立博客

    之前有帮外面的公司建站的经历 不去管html css js 服务器脚本等 对于菜鸟新手而言, 一个WAMP + WordPress(博客程序)就够了 都弄好了再部署到云端服务器上 其实整个过程只是安装 ...

  5. WordPress建站 新手入门

    WordPress建站 新手入门教程系列 1. WordPress入门 之 什么是WordPress? 2. WordPress入门 之 搭建WordPress站点需要什么条件? 3. WordPre ...

  6. [web建站] 优课急送《零基础快速学习建站》视频+课件【价值399元】

    [课程介绍]你想快速建一个网站出来吗?你想从什么都不懂到一两天出一个漂漂亮亮的站吗?你想完成领导交给你的任务找人建站吗?你想自己建站来创业吗?你想学会建站之后,利用给别人建站来赚钱吗?你想建一个跟某个 ...

  7. 浅析 Magento网站建站空间的选择

    对 Magento稍有了解的人都知道,作为一个功能异常强大的网络商城程序,Magento的运行对主机空间的要求是非常高的:很多 Magento建站公司都会推荐 VPS 甚至独立服务器来运行 Magen ...

  8. 建站随手记:about server stack

    建站需要,随手记: Server Stack: ----------- 标准的mezzanine的Stack设置 前端:Nginx wsgi:gunicorn cms tool: mezzanine ...

  9. vps云服务器建站后绑定域名的方法?

    有很多的新手站长们,都不知道vps建站后该如何绑定自己的域名,这里就Windows系统的VPS主机利用iis绑定网站域名的方法,简要介绍一下. 通常情况下,我们在使用IIS建站的时候,都会有一步提示, ...

  10. 国庆送干货——前端建站实用UI工具vajoyJS

    差不多是从七月开始有空就写一写,写到现在也算是可以拿出来展示了,vajoyJS是一款可以提供多项建站常用UI功能的插件库,让你轻松创建简易幻灯片.模态窗口和单屏滚页等效果.vajoyJS依赖于 jQu ...

随机推荐

  1. NPOIHelper

    public class NPOIHelper { public static void WriteDataToExceel(string fileName, DataSet ds) { if (Fi ...

  2. 【MySQL】结构行长度的一些限制

    今天被开发提交的DDL变更再次困惑,表中字段较多,希望将已有的两个varchar(4000)字段改为varchar(20000),我想innodb对varchar的存储不就是取前768字节记录当前行空 ...

  3. Android 封装Dialog

    package com.example.myandroid01; import android.support.v7.app.ActionBarActivity; import android.os. ...

  4. cocos2dx 3.x中的渲染机制

    1.由2.x的渲染节点,变成添加渲染命令,可以避免重复渲染相同的节点,提高了渲染效率 2.单机游戏通常要求apk包在30M以内,没压缩1M会有1%的转换率(下载转换率),即收入会提高 3.2.x中首先 ...

  5. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  6. Android 开机自启动应用

    Android启动时,会发出一个系统广播 ACTION_BOOT_COMPLETED,它的字符串常量表示为 “android.intent.action.BOOT_COMPLETED” 开机自启动程序 ...

  7. hadoop笔记之Hive入门(Hive的体系结构)

    Hive入门(二) Hive入门(二) Hive的体系结构 ○ Hive的元数据 Hive将元数据存储在数据库中(metastore),支持mysql.derby.oracle等数据库,Hive默认是 ...

  8. Win8.1应用开发之异步编程

    在win8应用商店开发时,我们会遇到很多异步方法.它们存在的目的就是为了确保你的应用在运行须要大量时间的任务时仍能保持良好的响应,也就是说调用异步API是为了响应用户的操作.设想一下我们点击一个But ...

  9. java基础,集合,HashMap,源码解析

    最怕,你以为你懂咯,其实你还不懂: 见贤思齐,看看那些我们习以为常的集合,通过相关定义.源码,思考分析,加深对其的理解,提高编码能力,能做一个略懂的程序员: 做几个我们常用的集合类.开篇HashMap ...

  10. Java基础——反射 reflect

    什么是反射 (1)Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称 ...