Merge pull request #209 from haiwen/v7.1-pro

V7.1 pro
This commit is contained in:
Daniel Pan 2020-04-16 15:32:41 +08:00 committed by GitHub
commit 051d4f879e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 324 additions and 90 deletions

View file

@ -0,0 +1,72 @@
# Lastet phusion baseimage as of 20180412, based on ubuntu 18.04
# See https://hub.docker.com/r/phusion/baseimage/tags/
FROM phusion/baseimage:0.11
RUN apt-get update --fix-missing
# Utility tools
RUN apt-get install -y vim htop net-tools psmisc wget curl
# For suport set local time zone.
RUN export DEBIAN_FRONTEND=noninteractive && apt-get install tzdata -y
# Nginx
RUN apt-get install -y nginx
# Java
RUN apt-get install -y openjdk-8-jre
# Libreoffice
RUN apt-get install -y libreoffice libreoffice-script-provider-python libsm-dev
RUN apt-get install -y ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy
# Tools
RUN apt-get install -y zlib1g-dev pwgen openssl poppler-utils
# Python3
RUN apt-get install -y python3 python3-pip python3-setuptools python3-ldap python-rados
RUN python3.6 -m pip install --upgrade pip && rm -r /root/.cache/pip
RUN pip3 install --timeout=3600 click termcolor colorlog pymysql \
django==1.11.29 && rm -r /root/.cache/pip
RUN pip3 install --timeout=3600 Pillow pylibmc captcha jinja2 \
sqlalchemy django-pylibmc django-simple-captcha && \
rm -r /root/.cache/pip
RUN pip3 install --timeout=3600 boto oss2 pycryptodome twilio python-ldap configparser && \
rm -r /root/.cache/pip
# Scripts
COPY scripts_7.1 /scripts
COPY templates /templates
COPY services /services
RUN mkdir -p /etc/my_init.d && \
rm -f /etc/my_init.d/* && \
cp /scripts/create_data_links.sh /etc/my_init.d/01_create_data_links.sh
RUN mkdir -p /etc/service/nginx && \
rm -f /etc/nginx/sites-enabled/* /etc/nginx/conf.d/* && \
mv /services/nginx.conf /etc/nginx/nginx.conf && \
mv /services/nginx.sh /etc/service/nginx/run
# Seafile
WORKDIR /opt/seafile
ENV SEAFILE_VERSION=7.1.3 SEAFILE_SERVER=seafile-pro-server
RUN mkdir -p /opt/seafile/ && cd /opt/seafile/ && \
wget -O seafile-pro-server_${SEAFILE_VERSION}_x86-64_Ubuntu.tar.gz \
"https://download.seafile.com/d/6e5297246c/files/?p=/pro/seafile-pro-server_${SEAFILE_VERSION}_x86-64_Ubuntu.tar.gz&dl=1" && \
tar -zxvf seafile-pro-server_${SEAFILE_VERSION}_x86-64_Ubuntu.tar.gz && \
rm -f seafile-pro-server_${SEAFILE_VERSION}_x86-64_Ubuntu.tar.gz
EXPOSE 80
CMD ["/sbin/my_init", "--", "/scripts/start.py"]

View file

@ -0,0 +1,34 @@
daemon off;
user www-data;
worker_processes auto;
events {
worker_connections 768;
}
http {
include /etc/nginx/mime.types;
server_names_hash_bucket_size 256;
server_names_hash_max_size 1024;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
log_format seafileformat '$http_x_forwarded_for $remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_response_time';
access_log /var/log/nginx/access.log seafileformat;
error_log /var/log/nginx/error.log info;
gzip on;
gzip_types text/plain text/css application/javascript application/json text/javascript;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
location / {
return 444;
}
}
}

View file

@ -0,0 +1,3 @@
#!/bin/bash
exec 2>&1
exec /usr/sbin/nginx

View file

@ -0,0 +1,3 @@
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# min hour dayofmonth month dayofweek command
0 0 1 * * root /scripts/ssl.sh {{ ssl_dir }} {{ domain }}

View file

@ -0,0 +1,99 @@
# -*- mode: nginx -*-
# Auto generated at {{ current_timestr }}
{% if https -%}
server {
listen 80;
server_name _ default_server;
# allow certbot to connect to challenge location via HTTP Port 80
# otherwise renewal request will fail
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
location / {
rewrite ^ https://{{ domain }}$request_uri? permanent;
}
}
{% endif -%}
server {
{% if https -%}
listen 443;
ssl on;
ssl_certificate /shared/ssl/{{ domain }}.crt;
ssl_certificate_key /shared/ssl/{{ domain }}.key;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
# TODO: More SSL security hardening: ssl_session_tickets & ssl_dhparam
# ssl_session_tickets on;
# ssl_session_ticket_key /etc/nginx/sessionticket.key;
# ssl_session_cache shared:SSL:10m;
# ssl_session_timeout 10m;
{% else -%}
listen 80;
{% endif -%}
server_name {{ domain }};
client_max_body_size 10m;
location / {
proxy_pass http://127.0.0.1:8000/;
proxy_read_timeout 310s;
proxy_set_header Host $host;
proxy_set_header Forwarded "for=$remote_addr;proto=$scheme";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Connection "";
proxy_http_version 1.1;
client_max_body_size 0;
access_log /var/log/nginx/seahub.access.log seafileformat;
error_log /var/log/nginx/seahub.error.log;
}
location /seafhttp {
rewrite ^/seafhttp(.*)$ $1 break;
proxy_pass http://127.0.0.1:8082;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 0;
proxy_connect_timeout 36000s;
proxy_read_timeout 36000s;
proxy_request_buffering off;
access_log /var/log/nginx/seafhttp.access.log seafileformat;
error_log /var/log/nginx/seafhttp.error.log;
}
location /seafdav {
client_max_body_size 0;
fastcgi_pass 127.0.0.1:8080;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
access_log /var/log/nginx/seafdav.access.log seafileformat;
error_log /var/log/nginx/seafdav.error.log;
}
location /media {
root /opt/seafile/seafile-server-latest/seahub;
}
# For letsencrypt
location /.well-known/acme-challenge/ {
alias /var/www/challenges/;
try_files $uri =404;
}
}

View file

@ -14,19 +14,19 @@ RUN export DEBIAN_FRONTEND=noninteractive && apt-get install tzdata -y
RUN apt-get install -y nginx
# Python3
RUN apt-get install -y python3 python3-pip python3-setuptools python3-ldap
RUN apt-get install -y python3 python3-pip python3-setuptools
RUN python3.6 -m pip install --upgrade pip && rm -r /root/.cache/pip
RUN pip3 install --timeout=3600 click termcolor colorlog pymysql \
django==1.11.29 && rm -r /root/.cache/pip
RUN pip3 install --timeout=3600 Pillow pylibmc captcha jinja2 \
sqlalchemy psd-tools django-pylibmc django-simple-captcha && \
sqlalchemy django-pylibmc django-simple-captcha && \
rm -r /root/.cache/pip
# Scripts
COPY scripts /scripts
COPY scripts_7.1 /scripts
COPY templates /templates
COPY services /services

View file

@ -26,12 +26,12 @@ EOF
mkdir -p /var/www/challenges
fi
cat >> /var/spool/cron/crontabs/root << EOF
0 1 1 * * ${renew_cert_script} 2>> /var/log/acme_tiny.log
cat >> /etc/crontab << EOF
00 1 1 * * root /scripts/renew_cert.sh 2>> /var/log/acme_tiny.log
EOF
echo 'Created a crontab to auto renew the cert for letsencrypt.'
else
echo 'Found existing the script for renew the cert.'
echo 'Skip create the crontab for letscncrypt since maybe we have created before.'
echo 'Skip create the crontab for letscncrypt since maybe we have created before.'
fi

View file

@ -24,7 +24,7 @@ seafile_version = get_seafile_version()
installdir = get_install_dir()
topdir = dirname(installdir)
shared_seafiledir = '/shared/seafile'
ssl_dir = '/shared/seafile/ssl'
ssl_dir = '/shared/ssl'
generated_dir = '/bootstrap/generated'
def init_letsencrypt():
@ -45,7 +45,7 @@ def init_letsencrypt():
context
)
ssl_crt = '/shared/seafile/ssl/{}.crt'.format(domain)
ssl_crt = '/shared/ssl/{}.crt'.format(domain)
if exists(ssl_crt):
loginfo('Found existing cert file {}'.format(ssl_crt))
if cert_has_valid_days(ssl_crt, 30):
@ -61,8 +61,9 @@ def init_letsencrypt():
'https': False,
'domain': domain,
}
render_template('/templates/seafile.nginx.conf.template',
'/etc/nginx/sites-enabled/default', context)
if not os.path.isfile('/shared/nginx/conf/seafile.nginx.conf'):
render_template('/templates/seafile.nginx.conf.template',
'/etc/nginx/sites-enabled/seafile.nginx.conf', context)
call('nginx -s reload')
time.sleep(2)
@ -76,6 +77,7 @@ def init_letsencrypt():
call('/scripts/auto_renew_crt.sh {0} {1}'.format(ssl_dir, domain))
# Create a crontab to auto renew the cert for letsencrypt.
def generate_local_nginx_conf():
# Now create the final nginx configuratin
domain = get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com')
@ -83,12 +85,16 @@ def generate_local_nginx_conf():
'https': is_https(),
'domain': domain,
}
render_template(
'/templates/seafile.nginx.conf.template',
'/etc/nginx/sites-enabled/default',
context
)
if not os.path.isfile('/shared/nginx/conf/seafile.nginx.conf'):
render_template(
'/templates/seafile.nginx.conf.template',
'/etc/nginx/sites-enabled/seafile.nginx.conf',
context
)
nginx_etc_file = '/etc/nginx/sites-enabled/seafile.nginx.conf'
nginx_shared_file = '/shared/nginx/conf/seafile.nginx.conf'
call('mv {0} {1} && ln -sf {1} {0}'.format(nginx_etc_file, nginx_shared_file))
def is_https():
return get_conf('SEAFILE_SERVER_LETSENCRYPT', 'false').lower() == 'true'
@ -99,30 +105,6 @@ def parse_args():
return ap.parse_args()
def generate_seafevents_conf():
user = get_conf('MYSQL_USER', 'root')
passwd = get_conf('DB_ROOT_PASSWD', '')
if user != 'root':
passwd = get_conf('DB_USER_PASSWD', '123')
host = get_conf('DB_HOST', '127.0.0.1')
context = """
[DATABASE]
type=mysql
username=%s
password=%s
name=seahub_db
host=%s
[FILE HISTORY]
enabled = true
suffix=txt,pdf,md,doc,docs
""" % (user, passwd, host)
with open(join(topdir, 'conf', 'seafevents.conf'), 'a+') as fp:
fp.write('\n')
fp.write(context)
fp.write('\n')
def init_seafile_server():
version_stamp_file = get_version_stamp_file()
if exists(join(shared_seafiledir, 'seafile-data')):
@ -134,42 +116,30 @@ def init_seafile_server():
if not exists(latest_version_dir):
call('ln -sf ' + current_version_dir + ' ' + latest_version_dir)
loginfo('Skip running setup-seafile-mysql.py because there is existing seafile-data folder.')
log_dir = join(shared_seafiledir, 'logs')
if not exists(log_dir):
os.mkdir(log_dir)
files_to_link = ['conf', 'ccnet', 'seafile-data', 'seahub-data', 'pro-data', 'logs']
for fn in files_to_link:
src = join(shared_seafiledir, fn)
dst = join(topdir, fn)
if not exists(dst) and exists(src):
call('ln -sf ' + src + ' ' + dst)
return
loginfo('Now running setup-seafile-mysql.py in auto mode.')
env = {
'SERVER_NAME': 'seafile',
'SERVER_IP': get_conf('SEAFILE_SERVER_HOSTNAME', '127.0.0.1'),
'MYSQL_USER': get_conf('MYSQL_USER', 'root'),
'MYSQL_USER_PASSWD': get_conf('DB_USER_PASSWD', '123'),
'MYSQL_USER_HOST': get_conf('DB_HOST', '127.0.0.1'),
'MYSQL_HOST': get_conf('DB_HOST', '127.0.0.1'),
'SERVER_IP': get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com'),
'MYSQL_USER': 'seafile',
'MYSQL_USER_PASSWD': str(uuid.uuid4()),
'MYSQL_USER_HOST': '%.%.%.%',
'MYSQL_HOST': get_conf('DB_HOST','127.0.0.1'),
# Default MariaDB root user has empty password and can only connect from localhost.
'MYSQL_ROOT_PASSWD': get_conf('DB_ROOT_PASSWD', ''),
'USE_EXISTING_DB': get_conf('USE_EXISTING_DB', '0'),
'CCNET_DB': get_conf('CCNET_DB', 'ccnet_db'),
'SEAFILE_DB': get_conf('SEAFILE_DB', 'seafile_db'),
'SEAHUB_DB': get_conf('SEAHUB_DB', 'seahub_db')
}
# Change the script to allow mysql root password to be empty
call('''sed -i -e 's/if not mysql_root_passwd/if not mysql_root_passwd and "MYSQL_ROOT_PASSWD" not in os.environ/g' {}'''
.format(get_script('setup-seafile-mysql.py')))
# call('''sed -i -e 's/if not mysql_root_passwd/if not mysql_root_passwd and "MYSQL_ROOT_PASSWD" not in os.environ/g' {}'''
# .format(get_script('setup-seafile-mysql.py')))
# Change the script to disable check MYSQL_USER_HOST
call('''sed -i -e '/def validate_mysql_user_host(self, host)/a \ \ \ \ \ \ \ \ return host' {}'''
.format(get_script('setup-seafile-mysql.py')))
.format(get_script('setup-seafile-mysql.py')))
call('''sed -i -e '/def validate_mysql_host(self, host)/a \ \ \ \ \ \ \ \ return host' {}'''
.format(get_script('setup-seafile-mysql.py')))
.format(get_script('setup-seafile-mysql.py')))
setup_script = get_script('setup-seafile-mysql.sh')
call('{} auto -n seafile'.format(setup_script), env=env)
@ -178,22 +148,20 @@ def init_seafile_server():
proto = 'https' if is_https() else 'http'
with open(join(topdir, 'conf', 'seahub_settings.py'), 'a+') as fp:
fp.write('\n')
fp.write(
"""
CACHES = {
fp.write("""CACHES = {
'default': {
'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
'LOCATION': '%s:11211',
'LOCATION': 'memcached:11211',
},
'locmem': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
}
COMPRESS_CACHE_BACKEND = 'locmem'
FILE_SERVER_ROOT = '%s://%s/seafhttp'
""" % (get_conf('MEMCACHED', 'memcached'), proto, domain))
COMPRESS_CACHE_BACKEND = 'locmem'""")
fp.write('\n')
fp.write("TIME_ZONE = '{time_zone}'".format(time_zone=os.getenv('TIME_ZONE', default='Etc/UTC')))
fp.write("TIME_ZONE = '{time_zone}'".format(time_zone=os.getenv('TIME_ZONE',default='Etc/UTC')))
fp.write('\n')
fp.write('FILE_SERVER_ROOT = "{proto}://{domain}/seafhttp"'.format(proto=proto, domain=domain))
fp.write('\n')
# By default ccnet-server binds to the unix socket file
@ -208,14 +176,41 @@ FILE_SERVER_ROOT = '%s://%s/seafhttp'
fp.write('UNIX_SOCKET = /opt/seafile/ccnet.sock\n')
fp.write('\n')
# Disabled the Elasticsearch process on Seafile-container
# Connection to the Elasticsearch-container
if os.path.exists(join(topdir, 'conf', 'seafevents.conf')):
with open(join(topdir, 'conf', 'seafevents.conf'), 'r') as fp:
fp_lines = fp.readlines()
if '[INDEX FILES]\n' in fp_lines:
insert_index = fp_lines.index('[INDEX FILES]\n') + 1
insert_lines = ['es_port = 9200\n', 'es_host = elasticsearch\n', 'external_es_server = true\n']
for line in insert_lines:
fp_lines.insert(insert_index, line)
# office
if '[OFFICE CONVERTER]\n' in fp_lines:
insert_index = fp_lines.index('[OFFICE CONVERTER]\n') + 1
insert_lines = ['host = 127.0.0.1\n', 'port = 6000\n']
for line in insert_lines:
fp_lines.insert(insert_index, line)
with open(join(topdir, 'conf', 'seafevents.conf'), 'w') as fp:
fp.writelines(fp_lines)
# office
with open(join(topdir, 'conf', 'seahub_settings.py'), 'r') as fp:
fp_lines = fp.readlines()
if "OFFICE_CONVERTOR_ROOT = 'http://127.0.0.1:6000/'\n" not in fp_lines:
fp_lines.append("OFFICE_CONVERTOR_ROOT = 'http://127.0.0.1:6000/'\n")
with open(join(topdir, 'conf', 'seahub_settings.py'), 'w') as fp:
fp.writelines(fp_lines)
# After the setup script creates all the files inside the
# container, we need to move them to the shared volume
#
# e.g move "/opt/seafile/seafile-data" to "/shared/seafile/seafile-data"
log_dir = join(topdir, 'logs')
if not exists(log_dir):
os.mkdir(log_dir)
files_to_copy = ['conf', 'ccnet', 'seafile-data', 'seahub-data', 'pro-data', 'logs']
files_to_copy = ['conf', 'ccnet', 'seafile-data', 'seahub-data', 'pro-data']
for fn in files_to_copy:
src = join(topdir, fn)
dst = join(shared_seafiledir, fn)
@ -223,7 +218,5 @@ FILE_SERVER_ROOT = '%s://%s/seafhttp'
shutil.move(src, shared_seafiledir)
call('ln -sf ' + join(shared_seafiledir, fn) + ' ' + src)
generate_seafevents_conf()
loginfo('Updating version stamp')
update_version_stamp(os.environ['SEAFILE_VERSION'])

View file

@ -34,18 +34,21 @@ for d in ${dirs[*]}; do
fi
done
if [[ ! -e /shared/logs/seafile ]]; then
mkdir -p /shared/logs/seafile
if [[ -e /shared/logs/seafile ]]; then
mv /shared/logs/seafile /shared/seafile/logs
rm -rf /opt/seafile/logs && ln -sf /shared/seafile/logs /opt/seafile/
else
mkdir -p /shared/seafile/logs && ln -sf /shared/seafile/logs /opt/seafile/
fi
rm -rf /opt/seafile/logs && ln -sf /shared/logs/seafile/ /opt/seafile/logs
rm -rf /var/lib/mysql
if [[ ! -e /shared/db ]];then
mkdir -p /shared/db
fi
ln -sf /shared/db /var/lib/mysql
if [[ ! -e /shared/logs/var-log ]]; then
mv /var/log /shared/logs/var-log
mkdir -p /shared/logs/ && mv /var/log /shared/logs/var-log
fi
rm -rf /var/log && ln -sf /shared/logs/var-log /var/log
mkdir -p /shared/nginx/conf/
if [[ -e /shared/nginx/conf/seafile.nginx.conf ]]; then
rm -rf /etc/nginx/sites-enabled/seafile.nginx.conf && \
ln -sf /shared/nginx/conf/seafile.nginx.conf /etc/nginx/sites-enabled
fi

View file

@ -22,7 +22,7 @@ from bootstrap import init_seafile_server, is_https, init_letsencrypt, generate_
shared_seafiledir = '/shared/seafile'
ssl_dir = '/shared/seafile/ssl'
ssl_dir = '/shared/ssl'
generated_dir = '/bootstrap/generated'
installdir = get_install_dir()
topdir = dirname(installdir)

View file

@ -119,6 +119,33 @@ def fix_ccent_conf():
print('Fix ccnet conf success')
print('')
def fix_office_config():
seafevents_conf_path = '/shared/seafile/conf/seafevents.conf'
seahub_conf_path = '/shared/seafile/conf/seahub_settings.py'
if exists(seafevents_conf_path):
with open(seafevents_conf_path, 'r') as fp:
fp_lines = fp.readlines()
if '[OFFICE CONVERTER]\n' in fp_lines and 'port = 6000\n' not in fp_lines:
insert_index = fp_lines.index('[OFFICE CONVERTER]\n') + 1
insert_lines = ['host = 127.0.0.1\n', 'port = 6000\n']
for line in insert_lines:
fp_lines.insert(insert_index, line)
with open(seafevents_conf_path, 'w') as fp:
fp.writelines(fp_lines)
with open(seahub_conf_path, 'r') as fp:
fp_lines = fp.readlines()
if "OFFICE_CONVERTOR_ROOT = 'http://127.0.0.1:6000/'\n" not in fp_lines:
fp_lines.append("OFFICE_CONVERTOR_ROOT = 'http://127.0.0.1:6000/'\n")
with open(seahub_conf_path, 'w') as fp:
fp.writelines(fp_lines)
print('')
print('Fix office config success')
print('')
def check_upgrade():
fix_custom_dir()
fix_ccent_conf()
@ -141,6 +168,8 @@ def check_upgrade():
new_version = parse_upgrade_script_version(script)[1] + '.0'
run_script_and_update_version_stamp(script, new_version)
fix_office_config()
update_version_stamp(current_version)
def main():

View file

@ -268,10 +268,8 @@ def update_version_stamp(version, fn=get_version_stamp_file()):
def wait_for_mysql():
db_host = get_conf('DB_HOST', '127.0.0.1')
db_user = get_conf('MYSQL_USER', 'root')
db_user = 'root'
db_passwd = get_conf('DB_ROOT_PASSWD', '')
if db_user != 'root':
db_passwd = get_conf('DB_USER_PASSWD', '123')
while True:
try: