## 工程目录 ```commandline ├── Dockerfile ├── docker-compose.yml ├── entrypoint.sh ├── mysql_app.sql ├── mysql_auth.sql ├── nginx.conf ├── supervisord.conf └── website ├── db ├── handlers ├── service ├── util ├── app.py ├── url.py ├── handler.py └── dist ├── index.html ├── ... ``` ## 配置信息 ### Dockerfile ```bash # generalai:v1是镜像名,192.168.10.94:5000是镜像仓库docker registry本地地址 FROM 192.168.10.94:5000/generalai:v1 # Set timezone ENV TZ=Asia/Shanghai # Install necessary packages RUN apt-get update && apt-get install -y \ # python3-pip \ # mysql-client \ default-mysql-client \ redis-tools \ && apt-get clean RUN mkdir -p /app/lemon RUN mkdir -p /app/fileupload RUN mkdir -p /app/log # Set working directory,设置工作目录之后,COPY命令的目标目录就是workdir指定的目录 WORKDIR /app/lemon # Copy application files # 拷贝工程文件,将工程文件拷贝到镜像的指定目录下,如果拷贝完整目录,需要使用"website/",不能使用"website/*" COPY website/ ./website/ COPY dist/ ./dist/ # COPY mysql_app.sql /app/lemon/ # Install Python dependencies # RUN pip3 install -r /app/lemon/website/requirements.txt # Copy supervisor configuration COPY supervisor.conf /etc/supervisor/conf.d/lemon.conf # Copy nginx configuration # COPY nginx.conf /etc/nginx/sites-available/lemon # RUN ln -s /etc/nginx/sites-available/lemon /etc/nginx/sites-enabled/ # COPY entrypoint.sh /app/lemon/entrypoint.sh # RUN chmod +x /app/lemon/entrypoint.sh # 拷贝entrypoint.sh文件,将entrypoint.sh文件拷贝到镜像根目录下 COPY entrypoint.sh / RUN sed -i 's/\r//' /entrypoint.sh RUN chmod +x /entrypoint.sh # Expose port EXPOSE 80 # VOLUME /data # Start services # ENTRYPOINT留空,入口文件entrypoint.sh配置在docker-compose.yml中,由docker-compose执行 ENTRYPOINT [] ``` 编译 ```shell # docker build,便于移植 docker build -t lemon:latest . docker images 查看生成的镜像 lemon:latest ``` ### docker-compose.yml ```shell version: "3.3" services: web: # build: . working_dir: /app/lemon/website # 设置工作目录,不设置会导致程序import错误 image: lemon:latest tty: true container_name: lemon_web privileged: true # ports: # - "80:80" # - "8989:8989" volumes: # - /data/app/lemon:/app/lemon # 如果由相同的设置,则会覆盖Dockfile中COPY的文件 - /data/app/log:/app/log - /data/app/fileupload:/app/fileupload - /usr/sbin/dmidecode:/usr/sbin/dmidecode # dmidecode命令需要root权限,否则会报错 - /dev/mem:/dev/mem # /dev/mem需要root权限,否则会报错 environment: - TZ=Asia/Shanghai networks: # 配置网络 - lemon_network depends_on: - mysql - redis # 执行entrypoint.sh文件,并执行supervisord启动服务 command: sh -c "/entrypoint.sh && /usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf" nginx: image: nginx:latest container_name: lemon_nginx ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/conf.d/lemon.conf # 挂载配置文件 - ./dist:/app/lemon/dist # 挂载前端目录 depends_on: - web networks: - lemon_network mysql: image: mysql:8.0 container_name: lemon_mysql ports: - "13306:3306" environment: MYSQL_ROOT_PASSWORD: SghjdA887# # 设置root用户密码 MYSQL_DATABASE: aiplatform # 设置数据库 volumes: - /data/mysql_data:/var/lib/mysql # 挂载数据目录 - ./mysql_auth.sql:/docker-entrypoint-initdb.d/auth.sql # 挂载权限初始化sql - ./mysql_app.sql:/docker-entrypoint-initdb.d/app.sql # 挂载数据库初始化sql networks: - lemon_network redis: image: redis:latest container_name: lemon_redis ports: - "16379:6379" command: redis-server --requirepass hgkiYY87 # 设置密码 volumes: - /data/redis_data:/data networks: - lemon_network #volumes: # mysql_data: # redis_data: networks: lemon_network: driver: bridge # 如果不设置,则默认使用bridge ``` ### entrypoint.sh ```bash #!/bin/bash # 初始化数据库,mysql_app.sql通过挂载的方式初始化,所以本处的代码注释掉了 #if [ -f "/app/lemon/mysql_app.sql" ];then # echo "Initializing MySQL database..." # # 初始化数据库, -p 表示使用密码登录,请使用实际的密码 # mysql -h lemon_mysql -u root -pxxx aiplatform < /app/lemon/mysql_app.sql # echo "MySQL initialization completed." #else # echo "Mysql init error:init sql file does not exist" #fi # 更新配置文件 if [ ! -f "/app/lemon/website/settings_local.py" ];then echo "@@init settings_local file" cat > /app/lemon/website/settings_local.py << EOF mysql_app = { "host": "lemon_mysql:3306", # docker-compose中设置了相同的networks,可以直接使用lemon_mysql:3306访问 "database": "aiplatform", "user": "root", "password": "xxx", # 请替换为实际的密码 "time_zone": "+8:00" } redis_app = ("lemon_redis", 6379, 0, "xxxx") # 请替换为实际的密码 EOF fi # 设置要列出的目录 dir_path="/app/lemon" # 函数,递归打印目录结构 function print_dir_structure() { local dir="$1" local indent="$2" # 打印当前目录 echo "$indent$(basename "$dir")" # 遍历目录下的所有项目 for item in "$dir"/* do # 如果是目录,递归打印 if [ -d "$item" ]; then print_dir_structure "$item" "$indent " # 如果是文件,打印文件名 elif [ -f "$item" ]; then echo "$indent $(basename "$item")" fi done } # print_dir_structure "$dir_path" "-" # 启动Tornado应用程序 #echo "启动Tornado应用程序" #if [ -f "/app/lemon/website/app.py" ];then # echo "@@app.py存在" # python /app/lemon/website/app.py --port=8889 >> /app/log/lemon.log 2>&1 #else # echo "app.py文件错误:文件不存在" #fi echo "启动完成" ``` ### mysql初始化 ``` mysql_app.sql, 数据库的结构,以及默认账号的初始化 mysql_auth.sql, 修改密码加密规格,修改密码 ``` ### nginx ``` server { listen 80; server_name 192.168.10.94; root /app/lemon/dist; # 静态文件目录,请替换为实际的路径 location ^~ /api { proxy_pass http://lemon_web:8989; # lemon_web为容器的默认host proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { try_files $uri $uri/ /index.html; } } ``` ### supervisor ``` [program:lemon] directory=/app/lemon/website command=python /app/lemon/website/app.py --port=8989 numprocs=1 process_name=%(program_name)s_%(process_num)02d autorestart=true autostart=true startsecs=5 redirect_stderr=true stdout_logfile=/app/log/app_%(process_num)02d.log ``` ``` command 可以使用动态参数,例如:--port=88%(process_num)02d,默认进程使用8800端口, 多进程则修改numproc的值,如numproc=2,则第一个进程使用8800端口,第二个进程使用8801端口。 ``` ## 启动项目 ### 本地编译启动 ``` 1. 修改配置文件 2. 编译,docker build -t lemon . 3. docker-compose up -d ``` ### 镜像打包 ``` Dockerfile中首行配置 FROM 192.168.10.94:5000/generalai:v1,使用的是开发环境的docker registry镜像 这个image中包含工程运行需要的基础环境,包括各种包,supervisor 镜像制作: docker build -t lemon . 镜像导出: export: docker export lemon_web lemon.tar # lemon_web是docker-compose.yml中的container name, 或者使用container id 或者save: docker save -o lemon.tar lemon:latest # 导出为tar文件,方便传输 ``` ### 导入docker镜像包 ``` import: docker import lemon.tar lemon:latest 或者load: docker load < lemon.tar docker-compose up -d ``` ### 查看日志 ``` docker logs -f lemon_web ```