1 docker中时区设置
写dockerfile时添加以下代码:
ENV DEBIAN_FRONTEND noninteractive
#定义时区参数
ENV TZ=Asia/Shanghai
ENV LANG C.UTF-8
RUN apt-get update \
&& apt-get upgrade -y \
# 安装时区依赖包tzfata,并设置时区为东八区
&& apt-get install -y tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& rm -rf /var/lib/apt/lists/*
2 python程序中设置时区
python程序中设置时区,一定要系统中/usr/share/zoneinfo文件夹下有时区文件夹及文件,或者设置不能成功,而且设置时区,一定要在入口文件的最顶行设置,否则可能在设置之前的部分代码可能不会生效
import os
import time
os.environ['TZ'] = 'Asia/Shanghai'
time.tzset()
3 使用docker+uwsgi+nginx联合部署项目
3.1 nginx配置
user www-data;
worker_processes auto;
pid /var/log/nginx/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 10005 default_server;
listen [::]:10005 default_server;
root /home/traffic/app;
server_name localhost;
access_log /home/traffic/app/log/nginx_access.log;
error_log /home/traffic/app/log/nginx_error.log;
location / {
proxy_redirect off;
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;
include uwsgi_params;
uwsgi_pass localhost:10000;
uwsgi_param UWSGI_CHDIR /home/traffic/app;
uwsgi_param UWSGI_SCRIPT traffic_per_http:app;
uwsgi_param UWSGI_PYHOME /usr/bin;
uwsgi_send_timeout 2; # 指定向uWSGI传送请求的超时时间,完成握手后向uWSGI传送请求的超时时间。
uwsgi_connect_timeout 2; # 指定连接到后端uWSGI的超时时间。
uwsgi_read_timeout 600; # 指定接收uWSGI应答的超时时间,完成握手后接收uWSGI应答的超时时间。
}
location ~ ^\/static\/.*$ {
expires 30d;
autoindex on;
add_header Cache-Control private;
alias /home/traffic/app/static/;
}
location ~ ^\/media\/.*$ {
alias /home/traffic/app/media/;
}
}
}
3.2 uwsgi配置
[uwsgi]
master = true
socket = 127.0.0.1:10000
chdir = /home/traffic/app
pythonpath = /usr/bin/python3
wsgi-file = traffic_per_http.py
callable = app
logto = /home/traffic/app/log/uwsgi.log
processes = 4 //处理器个数
threads = 2 //线程个数
gevent = 1000
async = 30
stats = 127.0.0.1:9191 //获取uwsgi统计信息的服务地址
vacuum = true #当服务器退出的时候自动删除unix socket文件和pid文件。
listen = 120 #设置socket的监听队列大小
;pidfile = /var/run/uwsgi.pid #指定pid文件
enable-threads = true #允许用内嵌的语言启动线程。这将允许你在app程序中产生一个子线程
# daemonize使用需要单独注意,若nginx前台运行,则需要配置daemonize,若nginx后台运行,则不需要配置该句
daemonize = /home/traffic/app/log/traffic_uwsgi.log # 使进程在后台运行,并将日志打到指定的日志文件或者udp服务器
3.3dockerfile写入内容及权限问题解决办法
nginx启动时报错权限问题,可以通过RUN chown root /usr/sbin/nginx及chmod u+s /usr/sbin/nginx两句予以解决,意为使用root用户启动nginx,如果不使用这两句,则需要通过修改nginx需要写入的日志文件所在的文件夹的权限来达到普通用户启动nginx的目的,用普通用户启动nginx会有警告信息。
如果向root用户管理的文件及文件夹中写入内容而因为没有权限不能启动,可以通过增加权限予以解决,如RUN chmod 777 /usr/sbin/nginx。
容器启动因为权限而不能顺利启动的,需要检查是否向root管理的文件及文件夹中写入过数据(如日志、进程文件等数据),如果写入过,则需要使用RUN来修改,如(RUN chmod -R 777 /var/run),因为没有权限而不能向/var/run文件夹下写入文件,运行了该句,即可使用普通用户身份写入数据到/var/run文件夹中。
dockerfile中谨慎使用root用户启动镜像,因为部署在集群平台会因为安全问题而不能部署成功。
FROM ubuntu:20.04
LABEL description="nginx container based on UBUNTU 20.04"
ENV DEBIAN_FRONTEND noninteractive
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
#定义时区参数
ENV TZ=Asia/Shanghai LANG=C.UTF-8
ENV redisHost=127.0.0.1 redisPort=6379 redisPassword='**' redisChannel=traffic_channel \
pgDB=traffic pgHost=127.0.0.1 pgPort=5432 pgPwd=** pgUser=traffic
RUN apt-get update \
&& apt-get upgrade -y \
# 安装时区依赖包tzfata,并设置时区为东八区
&& apt-get install -y tzdata \
&& ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
&& echo $TZ > /etc/timezone \
&& apt-get install -y python3.8 \
&& apt-get install -y python3-pip \
&& apt-get install -y nginx \
&& rm -rf /var/lib/apt/lists/\*
COPY ./requirements.txt requirements.txt
RUN pip3 install --no-cache-dir --default-timeout=1200 -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
#RUN pip3 install numpy==1.20.2 pandas==1.2.3 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com
RUN adduser -u 6789 --disabled-password --gecos '' traffic \
&& adduser traffic sudo
ADD ./ /home/traffic/app
RUN mkdir -p /home/traffic/app/log \
&& chmod -R 777 /home/traffic/app \
&& chmod -R 777 /var/log/nginx \
&& chmod -R 777 /var/lib/nginx \
&& chmod -R 777 /var/run \
&& chmod 777 /usr/sbin/nginx \
&& chmod -R 777 /etc/nginx/ \
&& chown root /usr/sbin/nginx \ # 本句及下一句解决nginx启动警告信息,意为使用root启动nginx
&& chmod u+s /usr/sbin/nginx # 当在集群化平台部署报不能使用root启动时,需要删除本句及上一句
WORKDIR /home/traffic/app
USER traffic
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 10005
# 当使用nginx -g "daemon on;"时,nginx将以后台运行,所以uwsgi必须以前台方式运行,配置文件中不能有daemonize信息
# 当nginx -g "daemon off;",nginx以前台方式运行,所以uwsgi则需以后台方式运行,配置文件中需要有daemonize配置
# 执行多个命令时,必须前面都是后台运行,最后一个在前台运行,daemon off表示nginx关闭后台运行,意即nginx在前台运行
#ENTRYPOINT nginx -g "daemon on;" && uwsgi --ini traffic.ini
ENTRYPOINT uwsgi --ini traffic.ini && nginx -g "daemon off;"
4 supervisor部署项目
4.1修改supervisor.conf配置文件
修改/etc/supervisor/supervisor.conf文件
; supervisor config file
[unix_http_server]
file=/var/run/supervisor.sock ; (the path to the socket file)
chmod=0700 ; sockef file mode (default 0700)
[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor ; ('AUTO' child log dir, default $TEMP)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[inet_http_server] ; inet (TCP) server disabled by default
port=0.0.0.0:9001 ; (ip_address:port specifier, *:port for all iface)
username=admin ; (default is no username (open server))
password=123456 ; (default is no password (open server))
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL for a unix socket
; The [include] section can just contain the "files" setting. This
; setting can list multiple files (separated by whitespace or
; newlines). It can also contain wildcards. The filenames are
; interpreted as relative to this file. Included files *cannot*
; include files themselves.
[include]
files = /etc/supervisor/conf.d/*.conf
; 将自定义的文件夹添加到下面一行
files = /etc/supervisor/config.d/*.ini
4.2编写配置文件
vim supervisor_task.ini
chmod -x supervisor_task.ini
[program:traffic-performance-http]
user=main
environment=
pgDB="traffic",
pgHost="127.0.0.1",
pgPort=5432,
pgPwd="**",
pgUser="traffic"
command=/bin/bash -c "cd ~/Desktop/traffic&&~/env/traffic/bin/gunicorn -c gun.py traffic_per_http:app"
directory=~/Desktop/traffic/
autorestart=true
startsecs=10
stderr_logfile=~/Desktop/traffic/log/traffic-performance-http.log
stdout_logfile=~/Desktop/traffic/log/traffic-performance-http.log
daemon=true
startretries=100
stopasgroup=true
killasgroup=true