前一阵公司有一个将项目部署到私有化本地的需求,我对服务器没什么研究,搭建起来很费力,所以用docker做了一系列项目私有化部署的镜像,现在写个博客记录一下学习和搭建的过程。
拿我现在的项目举例,分为前端(vue实现),后端(PHP laravel框架), onlineJudge(在线判题) 以及数据层和缓存(mysql, redis)。思路就是首先为各个项目创建镜像上传到dockerhub,然后使用docker-compose 一键部署
Laravel项目创建镜像- 进入项目目录,创建dockerfile文件, 内容如下
FROM php:7.4-fpm
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list &&
sed -i 's/security.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list &&
sed -i 's/security-cdn.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list
RUN sed -i 's/9000//run/php/php7.4-fpm.sock/' /usr/local/etc/php-fpm.d/zz-docker.conf
RUN mkdir /run/php
&& touch /run/php/php7.4-fpm.sock
&& chmod 777 /run/php/php7.4-fpm.sock
&& chmod +s /run/php/php7.4-fpm.sock
#### 安装PHP扩展 ######################
RUN pecl install redis-5.1.1 &&
docker-php-ext-enable redis
RUN docker-php-ext-install pdo &&
docker-php-ext-install pdo_mysql &&
docker-php-ext-enable pdo pdo_mysql
#### 安装nginx和supervisor 扩展 ######################
RUN apt-get update -yqq &&
apt-get install -yqq
nginx supervisor cron
RUN echo "* * * * * cd /var/www/kaoshi.web.server && php artisan schedule:run >> /dev/null 2>&1" >> /etc/crontab
#### 复制配置文件到镜像 ######################
COPY ./ /var/www/kaoshi.web.server/
COPY ./php-fpm/www.conf /usr/local/etc/php-fpm.d/
COPY ./sites/default /etc/nginx/sites-enabled/
COPY ./supervisor.conf /etc/supervisor/conf.d/
###### 修改laravel项目的各种配置 #########################
RUN chown -R www-data:www-data /var/www/kaoshi.web.server
&& mv /var/www/kaoshi.web.server/.env.docker /var/www/kaoshi.web.server/.env
ENV MYSQL_HOST=127.0.0.1
ENV MYSQL_DATAbase=exam
ENV MYSQL_USER=root
ENV MYSQL_PASSWORD=root
ENV REDIS_HOST=127.0.0.1
ENV REDIS_PORT=6379
ENV JUDGE_SERVER_HOST=kaoshi_judge_server
ENV JUDGE_SERVER_PORT=8080
WORKDIR /var/www/kaoshi.web.server
ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]
EXPOSE 80
这个文件比较长,大概的构建思路是 以php7.4镜像为基础,切换apt-get源 -> 安装php扩展 -> 安装nginx及其他需要的扩展 -> 复制项目目录中的各种配置文件 -> 设置启动脚本 -> 设置暴露的端口号。
这里要使用ENV命令设置laravel的各种配置,因为这些配置需要在后期的docker-compose创建容器时可以自由修改
- 编写启动脚本文件,我这里额外启动了 supervisord, crond 因为需要用到队列服务,`
#!/bin/bash
sed -i "s/MYSQL_HOST/${MYSQL_HOST}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MYSQL_DATAbase/${MYSQL_DATAbase}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MYSQL_USER/${MYSQL_USER}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MYSQL_PASSWORD/${MYSQL_PASSWORD}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MYSQL_USER/${MYSQL_USER}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MY_REDIS_HOST/${REDIS_HOST}/" /var/www/kaoshi.web.server/.env &&
sed -i "s/MY_REDIS_PORT/${REDIS_PORT}/" /var/www/kaoshi.web.server/.env
supervisord -c /etc/supervisor/supervisord.conf
supervisorctl start all
# Start php-fpm cron in background
php-fpm -D
/etc/init.d/cron start
# Start nginx in foreground
nginx -g "daemon off;"
- 构建镜像并上传
准备工作:这里需要你拥有一个docker账号,认证通过后,构建好的镜像上传到自己的镜像库中。
进入项目目录, 执行构建命令
> docker build -t youdockerid:backend_server ./
上传有两种方式,直接使用docker面版登录后上传,或者docker push也可以 很简单。
前台项目构建镜像构建过程和文件都基本类似,只是具体的配置等有所区别,同样是构建完毕后上传即可
dockerfile:
FROM node:16.3
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list &&
sed -i 's/security.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list &&
sed -i 's/security-cdn.debian.org/mirrors.aliyun.com/' /etc/apt/sources.list
RUN npm config set registry https://registry.npm.taobao.org
####### 复制项目文件 ###########################################
COPY ./ /var/www/kaoshi.frontend/
####### 安装nginx ###########################################
RUN apt-get update -yqq &&
apt-get install -yqq
nginx
COPY ./sites/default /etc/nginx/sites-enabled/
RUN mv /var/www/kaoshi.frontend/nuxt.config.docker.js /var/www/kaoshi.frontend/nuxt.config.js
&& npm install -g pm2
ENV LISTEN_HOST=127.0.0.1
ENV LISTEN_PORT=3306
ENV PROXY_HOST=api.kaoshi.test
WORKDIR /var/www/kaoshi.frontend
ADD ./startup.sh /opt/startup.sh
RUN sed -i 's/r//g' /opt/startup.sh
CMD ["/bin/bash", "/opt/startup.sh"]
EXPOSE 80
startup.sh:
#!/bin/bash
sed -i "s/LISTEN_HOST/${LISTEN_HOST}/" /var/www/kaoshi.frontend/nuxt.config.js &&
sed -i "s/LISTEN_PORT/${LISTEN_PORT}/" /var/www/kaoshi.frontend/nuxt.config.js &&
sed -i "s/PROXY_HOST/${PROXY_HOST}/" /var/www/kaoshi.frontend/nuxt.config.js &&
sed -i "s/LISTEN/http://${LISTEN_HOST}:${LISTEN_PORT}/" /etc/nginx/sites-enabled/default
cd /var/www/kaoshi.frontend && pm2 start npm --name "kaoshi" -- start
# Start nginx in foreground
nginx -g "daemon off;"
构建:
> docker build -t youdockerid:fronend_server ./编写docker-compose一键部署
- 首先创建一个新的目录作为部署目录,目录结构如下
├── .env //配置文件
├── .env.example
├── data //mysql或者redis或其他模块的数据存储在此
│ ├── mysql
│ └── redis
│ └── appendonly.aof
├── docker-compose.yml //部署文件
└── initdb.d //数据库初始化文件
└── init.sql
docker-compose.yml:
version: '3.5'
networks:
backend:
driver: bridge
services:
### backend ##################################
backend_server:
container_name: backend_server
image: yourdockerid/backend_server:latest
restart: always
networks:
- backend
environment:
MYSQL_HOST: ${MYSQL_HOST}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATAbase: ${MYSQL_DATAbase}
REDIS_HOST: ${REDIS_HOST}
REDIS_PORT: ${REDIS_PORT}
JUDGE_SERVER_HOST: ${JUDGE_SERVER_HOST}
JUDGE_SERVER_PORT: ${JUDGE_SERVER_PORT}
### frontend ##################################
frontend_server:
container_name: frontend_server
image: yourdockerid/frontend_server:latest
restart: always
ports:
- "0.0.0.0:80:80"
networks:
- backend
environment:
LISTEN_HOST: ${FRONTEND_LISTEN_HOST}
LISTEN_PORT: ${FRONTEND_LISTEN_PORT}
### mysql ##################################
mysql_server:
container_name: mysql_server
image: mysql:8.0
command: --default-authentication-plugin=mysql_native_password
restart: always
volumes:
- ./data/mysql:/data
- ./initdb.d:/docker-entrypoint-initdb.d
networks:
- backend
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATAbase: ${MYSQL_DATAbase}
### redis ##################################
redis_server:
container_name: redis_server
image: redis:5.0-alpine
command: redis-server --appendonly yes
restart: always
networks:
- backend
volumes:
- ./data/redis:/data
.env:
### MYSQL ################################################# MYSQL_HOST=mysql_server MYSQL_USER=root MYSQL_PASSWORD=root MYSQL_DATAbase=example ### REDIS ################################################# REDIS_HOST=redis_server REDIS_PORT=6379 ### frontend ################################################# FRONTEND_LISTEN_HOST=127.0.0.1 FRONTEND_LISTEN_PORT=3306
都写完了之后就可以愉快地构建了:
> docker-composer up -d Starting mysql_server ... done Starting redis_server ... done Starting frontend_server ... done Starting backend_server ... done
大功告成!
尾巴因为是蛮久之前弄的,所以有些细节踩坑的地方可能忘记提示了,如果有哪些地方不清楚或者需要指正的,欢迎留言
dockerhub: https://registry.hub.docker.com/



