From 24203d375f5ee734bc31e5ec81b2c52bbd0a5643 Mon Sep 17 00:00:00 2001 From: dede Date: Tue, 23 May 2023 22:24:36 +0200 Subject: [PATCH] initial commit (untested) --- data/.gitkeep | 0 docker-compose.override.yml | 15 +++++ docker-compose.yml | 53 +++++++++++++++++ env.sample | 18 ++++++ seafile.nginx.conf.template | 113 ++++++++++++++++++++++++++++++++++++ setup.sh | 71 ++++++++++++++++++++++ 6 files changed, 270 insertions(+) create mode 100644 data/.gitkeep create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml create mode 100644 env.sample create mode 100644 seafile.nginx.conf.template create mode 100755 setup.sh diff --git a/data/.gitkeep b/data/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..42a6110 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,15 @@ +version: '2.0' +volumes: + seafile-db: + driver: local + driver_opts: + type: none + o: bind + device: ${APP_DATA_DIRECTORY:-./data}/db + + seafile-data: + driver: local + driver_opts: + type: none + o: bind + device: ${APP_DATA_DIRECTORY:-./data}/app diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..dc39d2c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,53 @@ +version: '2.0' +services: + db: + image: mariadb:10.6 + container_name: seafile-mysql + environment: + - MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD + - MYSQL_LOG_CONSOLE=true + volumes: + - seafile-db:/var/lib/mysql # Requested, specifies the path to MySQL data persistent store. + networks: + - seafile-net + + memcached: + image: memcached:1.6.18 + container_name: seafile-memcached + entrypoint: memcached -m 256 + networks: + - seafile-net + + seafile: + image: seafileltd/seafile-mc:latest + container_name: seafile + volumes: + - seafile-data:/shared # Requested, specifies the path to Seafile data persistent store. + - ./seafile.nginx.conf.template:/templates/seafile.nginx.conf.template + environment: + - DB_HOST=db + - DB_ROOT_PASSWD=$MYSQL_ROOT_PASSWORD + - TIME_ZONE=$TIME_ZONE + - SEAFILE_ADMIN_EMAIL=$SEAFILE_ADMIN_EMAIL + - SEAFILE_ADMIN_PASSWORD=$SEAFILE_ADMIN_PASSWORD + - SEAFILE_SERVER_LETSENCRYPT=false + - SEAFILE_SERVER_HOSTNAME=$APP_HOSTNAME + - VIRTUAL_HOST=$APP_HOSTNAME + - VIRTUAL_PORT=$APP_PORT + - LETSENCRYPT_HOST=$APP_HOSTNAME + depends_on: + - db + - memcached + networks: + - seafile-net + - proxy-net + +networks: + seafile-net: + proxy-net: + external: true + name: $PROXYNET + +volumes: + seafile-db: + seafile-data: diff --git a/env.sample b/env.sample new file mode 100644 index 0000000..4c179ae --- /dev/null +++ b/env.sample @@ -0,0 +1,18 @@ +# Requested, the value shuold be root's password of MySQL service. +MYSQL_ROOT_PASSWORD= + +# Optional, default is UTC. Should be uncomment and set to your local time zone. +TIME_ZONE=Europe/Berlin + +# Specifies Seafile admin user, default is 'me@example.com'. +SEAFILE_ADMIN_EMAIL=me@example.com + +# Specifies Seafile admin password, default is 'asecret'. +SEAFILE_ADMIN_PASSWORD= + +# Specifies your host name if https is enabled. +APP_HOSTNAME=seafile.example.com +APP_PORT=80 +#APP_DATA_DIRECTORY=./data + +PROXYNET=proxynet diff --git a/seafile.nginx.conf.template b/seafile.nginx.conf.template new file mode 100644 index 0000000..d05d04d --- /dev/null +++ b/seafile.nginx.conf.template @@ -0,0 +1,113 @@ +# -*- 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; + 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 Forwarded "for=$proxy_add_x_forwarded_for;proto=$http_x_forwarded_proto"; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + #proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + #proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Real-IP $proxy_add_x_forwarded_for; + 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 /notification/ping { + proxy_pass http://127.0.0.1:8083/ping; + access_log /var/log/nginx/notification.access.log seafileformat; + error_log /var/log/nginx/notification.error.log; + } + + location /notification { + proxy_pass http://127.0.0.1:8083/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + access_log /var/log/nginx/notification.access.log seafileformat; + error_log /var/log/nginx/notification.error.log; + } + + location /seafdav { + proxy_pass http://127.0.0.1:8080; + 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-Host $server_name; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_read_timeout 1200s; + client_max_body_size 0; + + 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; + } + +{% if https -%} + # For letsencrypt + location /.well-known/acme-challenge/ { + alias /var/www/challenges/; + try_files $uri =404; + } +{% endif -%} +} diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..f6c653b --- /dev/null +++ b/setup.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# env setup script for seafile docker compose project +# 2023-01-06 by dede & dany + +echo "seafile docker compose setup" +echo "> env setup for seafile with docker compose..." + +# check for existing .env file to not break an existing setup +if [[ -f .env ]]; then + echo "> .env file already exists. setup will not run. either rename or delete it first." + exit 1 +elif [[ ! -f env.sample ]]; then + echo "> env.sample file is missing. cannot run." + exit 2 +fi + +# create .env file +echo -e "# file generated by ${0##*/} on $(date +"%F %H:%M") by $USER\n" > .env + +# step through the list of lines and ask for each key to use default value or set value +# for each line in configfile +while read -r -u 3 line; do + + # keep blank and comment lines + if [[ -z $line ]] || [[ $line == \#* ]]; then + echo "$line" >> .env + + # handle variable lines + else + # split line by '=' into key and value + readarray -d "=" -t currvar<<< "$line" + + # preset value with default + value=${currvar[1]::-1} + + # check if there's a password to generate + if [[ ${currvar[0]} =~ (PASS|PASSWORD|PWD|PASSWD)$ ]]; then + value=$(openssl rand -base64 29 | tr -d "=+/" | cut -c1-25) + fi + + # ask for user input + echo -n "please enter value for ${currvar[0]} [$value]: " + read -r userinput + + # set userinput as new value if any + if [ -n "$userinput" ]; then + value=$userinput + fi + + # check if there's a directory to create + if [[ ${currvar[0]} =~ (DIR|DIRECTORY)$ ]]; then + if [[ ! -d $value ]]; then + echo -n "do you want to create the directory? [Y/n]: " + read -r createdir + if [[ $createdir =~ ^([yY]|)$ ]]; then + mkdir -p "$value" + echo "directory created." + fi + else + echo "directory already exists." + if [ -n "$(ls -A "$value")" ]; then + echo "WATCH OUT! the directory is NOT empty. please ensure this is intended." + fi + fi + fi + + # now append the line + echo "${currvar[0]}=$value" >> .env + + fi +done 3< env.sample