Support native docker run instead of using the launcher script (#47)

* didn't use launcher

* travis

* link error & update readme

* del launcher.ps1, del bootstrap func under launcher file

* [readme] password/plan b, add a new admin

* review
This commit is contained in:
zMingGit 2018-04-12 17:12:43 +08:00 committed by Shuai Lin
parent 22457f2327
commit 9c3fdcae32
23 changed files with 333 additions and 1329 deletions

149
README.dev.md Normal file
View file

@ -0,0 +1,149 @@
[![Build Status](https://secure.travis-ci.org/haiwen/seafile-docker.png?branch=master)](http://travis-ci.org/haiwen/seafile-docker)
### About
- [Docker](https://docker.com/) is an open source project to pack, ship and run any Linux application in a lighter weight, faster container than a traditional virtual machine.
- Docker makes it much easier to deploy [a Seafile server](https://github.com/haiwen/seafile) on your servers and keep it updated.
- The base image configures Seafile with the Seafile team's recommended optimal defaults.
### Getting Started
Generate seafile image, and run the image.
```
sudo git clone https://github.com/haiwen/seafile-docker.git /var/seafile/
cd /var/seafile/image
make base
make server
docker run -d --name seafile-server -v /root/seafile:/shared -p 80:80 seafileltd/seafile:6.2.1
```
Now visit `http://hostname` or `https://hostname` to open Seafile Web UI.
If you are not familiar with docker commands, refer to [docker documentation](https://docs.docker.com/engine/reference/commandline/cli/).
### How to use
#### Custom admin username and password
The default account is `me@example.com` and the password is `asecret`.
You must change the password when you first run the seafile server.
If you forget the admin password, you can add a new admin account and then go to the sysadmin panel to reset user password.
#### Domain
You can create `/shared/bootstrap.conf`, write the following lines.
[server]
server.hostname = seafile.example.com
And then restart service, nginx will update up config.
#### Modify configurations
The config files are under `shared/seafile/conf`. You can modify the configurations according to [Seafile manual](https://manual.seafile.com/)
After modification, run the new docker container:
```
docker rm -f seafile-server
docker run -d --name seafile-server -v /root/seafile:/shared -p 80:80 seafileltd/seafile:6.2.1
```
#### Find logs
The seafile logs are under `shared/logs/seafile`.
The system logs are under `shared/logs/var-log`.
#### Add a new Admin
Enter the command below.
```
docker exec -it seafile-server /opt/seafile/seafile-server-latest/reset-admin.sh
```
Enter the username and password according to the prompts.You now have a new admin account.
### Directory Structure
#### `/bootstrap`
This directory is for container definitions for your Seafile containers. You are in charge of this directory, it ships empty.
#### `/samples`
Sample container definitions you may use to bootstrap your environment. You can copy templates from here into the bootstrap directory.
#### `/shared`
Placeholder spot for shared volumes. You may elect to store certain persistent information outside of a container, in our case we keep various logfiles and upload directory outside. This allows you to rebuild containers easily without losing important information.
- /shared/db: This is the data directory for mysql server
- /shared/seafile: This is the directory for seafile server configuration and data.
- /shared/logs: This is the directory for logs.
- /shared/logs/var-log: This is the directory that would be mounted as `/var/log` inside the container. For example, you can find the nginx logs in `shared/logs/var-log/nginx/`.
- /shared/logs/seafile: This is the directory that would contain the log files of seafile server processes. For example, you can find seaf-server logs in `shared/logs/seafile/seafile.log`.
- /shared/ssl: This is directory for certificate, which does not exist by default.
- /shared/bootstrap.conf: This file does not exist by default. You can create it by your self, and write the configuration of files similar to the `samples` folder.
#### `/templates`
Various jinja2 templates used for seafile server configuration.
#### `/image`
Dockerfiles for Seafile.
The Docker repository will always contain the latest built version at: https://hub.docker.com/r/seafileltd/seafile/, you should not need to build the base image.
### Container Configuration
#### Let's encrypt SSL certificate
If you set `server.letsencrypt` to `true`, the bootstrap script would request a letsencrypt-signed SSL certificate for you.
```conf
server.letsencrypt = true
```
If you want to use your own SSL certificate:
- create a folder 'shared/ssl', and put your certificate and private key under the ssl directory.
- Assume your site name is "seafile.example.com", then your certificate must have the name "seafile.example.com.crt", and the private key must have the name "seafile.example.com.key".
### Upgrading Seafile Server
ensure same version of the repo, and run start command`docker run -d --name seafile-server -v /root/seafile:/shared -p 80:80 seafileltd/seafile:6.2.1 `, which would keep your seafile server up to date.
### Troubleshooting
You can run the command as "docker logs" or "docker exec" to find errors.
### Developing with Vagrant
If you are looking to make modifications to this repository, you can easily test
out your changes before committing, using the magic
of [Vagrant](http://vagrantup.com). Install Vagrant as
per
[the default instructions](http://docs.vagrantup.com/v2/installation/index.html),
and then run:
vagrant up
This will spawn a new Ubuntu VM, install Docker, and then await your
instructions. You can then SSH into the VM with `vagrant ssh`, become `root`
with `sudo -i`, and then you're right to go. Your live git repo is already
available at `/var/seafile`, so you can just `cd /var/seafile` and then start
running `launcher`.
### Special Thanks
Lots of the design of this repo is borrowed from the excellent [discourse-docker](https://github.com/discourse/discourse_docker) project. Thanks for their insipiration!
License
===
Apache

154
README.md
View file

@ -10,53 +10,80 @@
### Getting Started
The simplest way to get started is via the **samples/server.conf** template, which can be installed within several minutes.
Download seafile image, and run the image.
```
sudo git clone https://github.com/haiwen/seafile-docker.git /var/seafile/
cd /var/seafile/
sudo cp samples/server.conf bootstrap/bootstrap.conf
# Edit the options according to your use case
sudo vim bootstrap/bootstrap.conf
sudo ./launcher bootstrap
sudo ./launcher start
docker run -d --name seafile-server -v /opt/seafile-data:/shared -p 80:80 seafileltd/seafile:6.2.1
```
Now visit `http://hostname` or `https://hostname` to open Seafile Web UI.
### How to use
If you are not familiar with docker commands, refer to [docker documentation](https://docs.docker.com/engine/reference/commandline/cli/).
### More configuration option
#### Custom admin username and password
The default account is `me@example.com` and the password is `asecret`. It will be created when the container is first run.
The default values can also be changed by setting the container's environment variables
e.g.
docker run -d --name seafile-server -e "SEAFILE_ADMIN_EMAIL=me@example.com" -e "SEAFILE_ADMIN_PASSWORD=asecret" -v /opt/seafile-data:/shared -p 80:80 seafileltd/seafile:6.2.1
If you forget the admin password, you can add a new admin account and then go to the sysadmin panel to reset user password.
#### Domain
The default value is `seafile.example.com`, you can set environ to docker container.
e.g.
docker run -d --name seafile-server -e "SEAFILE_SERVER_HOSTNAME=seafile.example.com" -v /opt/seafile-data:/shared -p 80:80 seafileltd/seafile:6.2.1
And then nginx will update up config.
#### Let's encrypt SSL certificate
If you set `SEAFILE_SERVER_LETSENCRYPT` to `true`, the bootstrap script would request a letsencrypt-signed SSL certificate for you.
e.g.
docker run -d --name seafile-server -e "SEAFILE_SERVER_LETSENCRYPT=true" -v /opt/seafile-data:/shared -p 80:80 -p 443:443 seafileltd/seafile:6.2.1
If you want to use your own SSL certificate:
- create a folder 'shared/ssl', and put your certificate and private key under the ssl directory.
- Assume your site name is "seafile.example.com", then your certificate must have the name "seafile.example.com.crt", and the private key must have the name "seafile.example.com.key".
#### Modify configurations
The config files are under `shared/seafile/conf`. You can modify the configurations according to [Seafile manual](https://manual.seafile.com/)
After modification, restart the docker container:
After modification, run the new docker container:
```
sudo ./launcher restart
docker rm -fseafile-server
docker run -d --name seafile-server -v /root/seafile:/shared -p 80:80 seafileltd/seafile:6.2.1
```
#### Find logs
The logs are under `shared/logs/seafile`.
The seafile logs are under `shared/logs/seafile`.
#### Enable debug logs of launcher
The system logs are under `shared/logs/var-log`.
Pass `-v` to launcher script (for example `sudo ./launcher -v rebuild` would make it print more verbose information
#### Add a new Admin
Enter the command below.
```
docker exec -it seafile-server /opt/seafile/seafile-server-latest/reset-admin.sh
```
Enter the username and password according to the prompts.You now have a new admin account.
### Directory Structure
#### `/bootstrap`
This directory is for container definitions for your Seafile containers. You are in charge of this directory, it ships empty.
#### `/samples`
Sample container definitions you may use to bootstrap your environment. You can copy templates from here into the bootstrap directory.
#### `/shared`
Placeholder spot for shared volumes. You may elect to store certain persistent information outside of a container, in our case we keep various logfiles and upload directory outside. This allows you to rebuild containers easily without losing important information.
@ -66,84 +93,21 @@ Placeholder spot for shared volumes. You may elect to store certain persistent i
- /shared/logs: This is the directory for logs.
- /shared/logs/var-log: This is the directory that would be mounted as `/var/log` inside the container. For example, you can find the nginx logs in `shared/logs/var-log/nginx/`.
- /shared/logs/seafile: This is the directory that would contain the log files of seafile server processes. For example, you can find seaf-server logs in `shared/logs/seafile/seafile.log`.
- /shared/ssl: This is directory for certificate, which does not exist by default.
- /shared/bootstrap.conf: This file does not exist by default. You can create it by your self, and write the configuration of files similar to the `samples` folder.
#### `/templates`
Various jinja2 templates used for seafile server configuration.
#### `/image`
Dockerfiles for Seafile.
The Docker repository will always contain the latest built version at: https://hub.docker.com/r/seafileltd/seafile/, you should not need to build the base image.
### Launcher
The base directory contains a single bash script which is used to manage containers. You can use it to "bootstrap" a new container, enter, start, stop and destroy a container.
```
Usage: launcher COMMAND
Commands:
bootstrap: Bootstrap a container for the config based on a template
start: Start/initialize a container
stop: Stop a running container
restart: Restart a container
destroy: Stop and remove a container
enter: Use docker exec to enter a container
logs: Docker logs for container
rebuild: Rebuild a container (destroy old, bootstrap, start new)
gc: Start the seafile garbage collector (stops seafile, starts gc, restarts seafile)
```
If the environment variable "SUPERVISED" is set to true, the container won't be detached, allowing a process monitoring tool to manage the restart behaviour of the container.
### Container Configuration
#### port mapping:
```conf
server.port_mappings = 80:80,443:443
```
#### Let's encrypt SSL certificate
If you set `server.letsencrypt` to `true`, the bootstrap script would request a letsencrypt-signed SSL certificate for you.
```conf
server.letsencrypt = true
server.port_mappings = 80:80,443:443
```
If you want to use your own SSL certificate:
- create a folder 'shared/ssl', and put your certificate and private key under the ssl directory.
- Assume your site name is "seafile.example.com", then your certificate must have the name "seafile.example.com.crt", and the private key must have the name "seafile.example.com.key".
### Upgrading Seafile Server
If you are one of the users who use the launcher update. You can refer to [upgrade from old format](https://github.com/haiwen/seafile-docker/upgrade_from_old_format.md)
Simple run `sudo ./launcher rebuild`, which would keep your seafile server up to date.
ensure same version of the repo, and run start command
docker run -d --name seafile-server -v ${data_path}:/shared -p 80:80 seafileltd/seafile:6.2.1
which would keep your seafile server up to date.
### Troubleshooting
View the container logs: `sudo ./launcher logs`
Spawn a shell inside your container using `sudo ./launcher enter`. This is the most foolproof method if you have host root access.
### Developing with Vagrant
If you are looking to make modifications to this repository, you can easily test
out your changes before committing, using the magic
of [Vagrant](http://vagrantup.com). Install Vagrant as
per
[the default instructions](http://docs.vagrantup.com/v2/installation/index.html),
and then run:
vagrant up
This will spawn a new Ubuntu VM, install Docker, and then await your
instructions. You can then SSH into the VM with `vagrant ssh`, become `root`
with `sudo -i`, and then you're right to go. Your live git repo is already
available at `/var/seafile`, so you can just `cd /var/seafile` and then start
running `launcher`.
You can run the command as "docker logs" or "docker exec" to find errors.
### Special Thanks

View file

@ -55,13 +55,8 @@ Now run the following commands:
(Note that if you're using another drive than "C:", say "D:", you should change the "c:\\seafile" in the following commands to "d:\\seafile" instead.)
```sh
git clone https://github.com/haiwen/seafile-docker.git c:\seafile
cd c:\seafile
Copy-Item samples/server.conf bootstrap/bootstrap.conf
# Edit the options according to your use case
start notepad++ bootstrap/bootstrap.conf
.\launcher.ps1 bootstrap
.\launcher.ps1 start
docker pull seafileltd/seafile:6.2.1
docker run -d --name seafile-server -v /root/seafile:/shared -p 80:80 seafileltd/seafile:6.2.1
```
If you are not familiar with docker commands, refer to [docker documentation](https://docs.docker.com/engine/reference/commandline/cli/).

View file

@ -1,5 +1,6 @@
#!/bin/bash
version=6.2.3
set -e -x
@ -7,18 +8,15 @@ set -e -x
cd image
# pip install docker-squash
# make base squash-base server
make base
make server
)
sudo cp samples/server.conf bootstrap/bootstrap.conf
sudo ./launcher -v bootstrap
sudo ./launcher -v start && sleep 10
sudo ./launcher stop --skip-prereqs
sudo ./launcher start --docker-args "--memory 1g" && sleep 10
sudo ./launcher restart
sudo ./launcher -v rebuild
sudo ./launcher -v rebuild --docker-args "--memory 1g"
mkdir -p /opt/seafile-docker-data
docker run -d --name seafile-server -v /opt/seafile-docker-data:/shared -p 80:80 -p 443:443 seafileltd/seafile:$version
docker stop seafile-server
docker start seafile-server
docker restart seafile-server
if [[ $TRAVIS_TAG != "" ]]; then
ci/publish-image.sh

View file

@ -14,4 +14,10 @@ RUN mkdir -p /opt/seafile/ && \
curl -sSL -o - https://download.seadrive.org/seafile-server_${SEAFILE_VERSION}_x86-64.tar.gz \
| tar xzf - -C /opt/seafile/
ADD create_data_links.sh /etc/my_init.d/create_data_links.sh
ADD create_data_links.sh /etc/my_init.d/01_create_data_links.sh
COPY scripts /scripts
COPY templates /templates
COPY bootstrap.conf /opt/bootstrap.conf
CMD ["/sbin/my_init", "--", "/scripts/start.py"]

View file

@ -0,0 +1,8 @@
# If you edit this file, remember to run ./launcher rebuild
[server]
server.hostname = seafile.example.com
admin.email = me@example.com
admin.password = asecret
# uncomment the one lines below to use letsencrypt SSL certificate
# server.letsencrypt = true

View file

@ -1,6 +1,6 @@
#!/bin/bash
set -e
set -e
set -o pipefail
if [[ $SEAFILE_BOOTSRAP != "" ]]; then
@ -12,32 +12,50 @@ dirs=(
ccnet
seafile-data
seahub-data
bootstrap.conf
)
for d in ${dirs[*]}; do
src=/shared/seafile/$d
if [[ -e $src ]]; then
ln -sf $src /opt/seafile/
ln -sf $src /opt/seafile
fi
done
if [[ ! -e /shared/logs/seafile ]]; then
mkdir -p /shared/logs/seafile
fi
if [[ -e /shared/logs/seafile ]]; then
ln -sf /shared/logs/seafile/ /opt/seafile/logs
rm /opt/seafile/logs && ln -sf /shared/logs/seafile/ /opt/seafile/logs
fi
current_version_dir=/opt/seafile/seafile-server-${SEAFILE_VERSION}
latest_version_dir=/opt/seafile/seafile-server-latest
seahub_data_dir=/shared/seafile/seahub-data
if [[ ! -e ${latest_version_dir} ]]; then
ln -sf ${current_version_dir} ${latest_version_dir}
if [[ ! -e ${seahub_data_dir} ]]; then
mkdir -p ${seahub_data_dir}
fi
source_avatars_dir=${current_version_dir}/seahub/media/avatars
rm -rf $source_avatars_dir
ln -sf ${seahub_data_dir}/avatars $source_avatars_dir
if [[ ! -e ${seahub_data_dir}/avatars ]]; then
mv $source_avatars_dir ${seahub_data_dir}/avatars
fi
rm -rf $source_avatars_dir && ln -sf ${seahub_data_dir}/avatars $source_avatars_dir
source_custom_dir=${current_version_dir}/seahub/media/custom
rm -rf $source_custom_dir
mkdir -p ${seahub_data_dir}/custom
ln -sf ${seahub_data_dir}/custom $source_custom_dir
if [[ ! -e ${seahub_data_dir}/custom ]]; then
mkdir -p ${seahub_data_dir}/custom
fi
rm -rf $source_custom_dir && ln -sf ${seahub_data_dir}/custom $source_custom_dir
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
fi
rm -rf /var/log && ln -sf /shared/logs/var-log /var/log

View file

@ -17,7 +17,7 @@ from utils import (
call, get_conf, get_install_dir, loginfo,
get_script, render_template, get_seafile_version, eprint,
cert_has_valid_days, get_version_stamp_file, update_version_stamp,
wait_for_mysql, wait_for_nginx
wait_for_mysql, wait_for_nginx, read_version_stamp
)
seafile_version = get_seafile_version()
@ -34,7 +34,7 @@ def init_letsencrypt():
if not exists(ssl_dir):
os.mkdir(ssl_dir)
domain = get_conf('server.hostname')
domain = get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com')
context = {
'ssl_dir': ssl_dir,
'domain': domain,
@ -73,29 +73,20 @@ def init_letsencrypt():
def generate_local_nginx_conf():
# Now create the final nginx configuratin
domain = get_conf('server.hostname')
domain = get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com')
context = {
'https': is_https(),
'domain': domain,
}
render_template(
'/templates/seafile.nginx.conf.template',
join(generated_dir, 'seafile.nginx.conf'),
'/etc/nginx/sites-enabled/seafile.nginx.conf',
context
)
def is_https():
return get_conf('server.letsencrypt', '').lower() == 'true'
def generate_local_dockerfile():
loginfo('Generating local Dockerfile ...')
context = {
'seafile_version': seafile_version,
'https': is_https(),
'domain': get_conf('server.domain'),
}
render_template('/templates/Dockerfile.template', join(generated_dir, 'Dockerfile'), context)
return get_conf('SEAFILE_SERVER_LETSENCRYPT', 'false').lower() == 'true'
def parse_args():
ap = argparse.ArgumentParser()
@ -103,29 +94,23 @@ def parse_args():
return ap.parse_args()
def do_parse_ports():
"""
Parse the server.port_mappings option and print docker command line port
mapping flags like "-p 80:80 -p 443:443"
"""
# conf is like '80:80,443:443'
conf = get_conf('server.port_mappings', '').strip()
if conf:
sys.stdout.write(' '.join(['-p {}'.format(part.strip()) for part in conf.split(',')]))
sys.stdout.flush()
def init_seafile_server():
version_stamp_file = get_version_stamp_file()
if exists(join(shared_seafiledir, 'seafile-data')):
if not exists(version_stamp_file):
update_version_stamp(os.environ['SEAFILE_VERSION'])
# sysbol link unlink after docker finish.
latest_version_dir='/opt/seafile/seafile-server-latest'
current_version_dir='/opt/seafile/seafile-server-' + read_version_stamp()
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.')
return
loginfo('Now running setup-seafile-mysql.py in auto mode.')
env = {
'SERVER_NAME': 'seafile',
'SERVER_IP': get_conf('server.hostname'),
'SERVER_IP': get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com'),
'MYSQL_USER': 'seafile',
'MYSQL_USER_PASSWD': str(uuid.uuid4()),
'MYSQL_USER_HOST': '127.0.0.1',
@ -140,7 +125,7 @@ def init_seafile_server():
setup_script = get_script('setup-seafile-mysql.sh')
call('{} auto -n seafile'.format(setup_script), env=env)
domain = get_conf('server.hostname')
domain = get_conf('SEAFILE_SERVER_HOSTNAME', 'seafile.example.com')
proto = 'https' if is_https() else 'http'
with open(join(topdir, 'conf', 'seahub_settings.py'), 'a+') as fp:
fp.write('\n')
@ -165,32 +150,7 @@ def init_seafile_server():
dst = join(shared_seafiledir, fn)
if not exists(dst) and exists(src):
shutil.move(src, shared_seafiledir)
call('ln -sf ' + join(shared_seafiledir, fn) + ' ' + src)
loginfo('Updating version stamp')
update_version_stamp(os.environ['SEAFILE_VERSION'])
def main():
args = parse_args()
if args.parse_ports:
do_parse_ports()
return
if not exists(shared_seafiledir):
os.mkdir(shared_seafiledir)
if not exists(generated_dir):
os.mkdir(generated_dir)
generate_local_dockerfile()
if is_https():
init_letsencrypt()
generate_local_nginx_conf()
wait_for_mysql()
init_seafile_server()
loginfo('Generated local config.')
if __name__ == '__main__':
# TODO: validate the content of bootstrap.conf is valid
main()

View file

@ -17,7 +17,13 @@ from utils import (
call, get_conf, get_install_dir, get_script, get_command_output,
render_template, wait_for_mysql
)
from upgrade import check_upgrade
from bootstrap import init_seafile_server, is_https, init_letsencrypt, generate_local_nginx_conf
shared_seafiledir = '/shared/seafile'
ssl_dir = '/shared/ssl'
generated_dir = '/bootstrap/generated'
installdir = get_install_dir()
topdir = dirname(installdir)
@ -36,15 +42,30 @@ def watch_controller():
sys.exit(1)
def main():
if not exists(shared_seafiledir):
os.mkdir(shared_seafiledir)
if not exists(generated_dir):
os.makedirs(generated_dir)
if is_https():
init_letsencrypt()
generate_local_nginx_conf()
call('nginx -s reload')
wait_for_mysql()
init_seafile_server()
check_upgrade()
os.chdir(installdir)
admin_pw = {
'email': get_conf('admin.email'),
'password': get_conf('admin.password'),
'email': get_conf('SEAFILE_ADMIN_EMAIL', 'me@example.com'),
'password': get_conf('SEAFILE_ADMIN_PASSWORD', 'asecret'),
}
password_file = join(topdir, 'conf', 'admin.txt')
with open(password_file, 'w') as fp:
json.dump(admin_pw, fp)
wait_for_mysql()
try:
call('{} start'.format(get_script('seafile.sh')))

View file

@ -218,12 +218,8 @@ def get_script(script):
_config = None
def get_conf(key, default=None):
global _config
if _config is None:
_config = ConfigParser()
_config.read("/bootstrap/bootstrap.conf")
return _config.get("server", key) if _config.has_option("server", key) \
else default
key = key.upper()
return os.environ.get(key, default)
def _add_default_context(context):
default_context = {

440
launcher
View file

@ -1,432 +1,12 @@
#!/bin/bash
usage () {
echo "Usage: launcher COMMAND [--skip-prereqs] [--docker-args STRING]"
echo "Commands:"
echo " start: Start/initialize the container"
echo " stop: Stop a running container"
echo " restart: Restart the container"
echo " destroy: Stop and remove the container"
echo " enter: Open a shell to run commands inside the container"
echo " logs: View the Docker container logs"
echo " bootstrap: Bootstrap the container based on a template"
echo " rebuild: Rebuild the container (destroy old, bootstrap, start new)"
echo " gc: Start the seafile garbage collector (stops seafile, starts gc, restarts seafile)"
echo
echo "Options:"
echo " --skip-prereqs Don't check launcher prerequisites"
echo " --docker-args Extra arguments to pass when running docker"
exit 1
}
set -e
set -o pipefail
version=6.2.3
image=seafileltd/seafile:$version
local_image=local_seafile/server:latest
dockerdir=$(cd "$(dirname $0)"; pwd -P)
sharedir=$dockerdir/shared
installdir=/opt/seafile/seafile-server-$version
bootstrap_conf=$dockerdir/bootstrap/bootstrap.conf
version_stamp_file=$sharedir/seafile/seafile-data/current_version
cd $dockerdir
logdbg() {
if [[ $verbose == "true" ]]; then
loginfo "[debug] $1"
fi
}
loginfo() {
if [[ -t 1 ]]; then
>&2 printf "[$(date +'%Y-%m-%d %H:%M:%S')] \033[32m%s\033[m\n" "$1"
else
>&2 echo "[$(date +'%Y-%m-%d %H:%M:%S')] " "$1"
fi
}
install_docker() {
echo "---------------------------------------------------------------------------------"
echo "Docker is not installed, you will need to install Docker in order to run Launcher"
echo "See https://docs.docker.com/installation/"
echo "---------------------------------------------------------------------------------"
exit 1
}
err_and_quit () {
if [[ -t 1 ]]; then
>&2 printf "\n\n\033[33mError: %s\033[m\n\n" "$1"
else
>&2 echo "$1"
fi
exit 1
}
init_shared() {
mkdir -p $sharedir/{seafile,db}
mkdir -p $sharedir/logs/{seafile,var-log}
mkdir -p $sharedir/logs/var-log/nginx
touch $sharedir/logs/var-log/syslog
local bash_history=$sharedir/.bash_history
if [[ ! -e $bash_history ]]; then
touch $bash_history
fi
}
set_envs() {
envs=""
if [[ $verbose == "true" ]]; then
envs="$envs -e SEAFILE_DOCKER_VERBOSE=true"
fi
}
set_ports() {
ports=$(docker run $user_args --rm -it \
-v ${dockerdir}/scripts:/scripts \
-v ${dockerdir}/bootstrap:/bootstrap:ro \
$image \
/scripts/bootstrap.py --parse-ports)
}
set_bootstrap_volumes() {
local mounts
init_shared
mounts=(
$sharedir:/shared
$sharedir/logs/var-log:/var/log
$sharedir/db:/var/lib/mysql
$dockerdir/bootstrap:/bootstrap
$dockerdir/scripts:/scripts:ro
$dockerdir/templates:/templates:ro
$dockerdir/scripts/tmp/check_init_admin.py:$installdir/check_init_admin.py:ro
$sharedir/.bash_history:/root/.bash_history
)
volumes=""
local m
for m in ${mounts[*]}; do
volumes="$volumes -v $m"
done
}
set_volumes() {
local mounts
init_shared
mounts=(
$sharedir:/shared
$sharedir/logs/var-log:/var/log
$sharedir/db:/var/lib/mysql
$sharedir/.bash_history:/root/.bash_history
)
volumes=""
local m
for m in ${mounts[*]}; do
volumes="$volumes -v $m"
done
}
set_existing_container() {
existing=$(docker ps -a | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true)
}
bootstrap() {
if [[ ! -e $bootstrap_conf ]]; then
err_and_quit "The file $bootstrap_conf doesn't exist. Have you run seafile-server-setup?"
fi
docker history $image >/dev/null 2>&1 || {
loginfo "Pulling Seafile server image $version, this may take a while."
docker pull $image
loginfo "Seafile server image $version pulled. Now bootstrapping the server ..."
}
# First initialize seafile server and letsencrypt
set_envs
set_bootstrap_volumes
set_ports
docker run $user_args --rm -it --name seafile-bootstrap -e SEAFILE_BOOTSRAP=1 $envs $volumes $ports $image /sbin/my_init $quiet -- /scripts/bootstrap.py
loginfo "Now building the local docker image."
docker build -f bootstrap/generated/Dockerfile -t local_seafile/server:latest . >/dev/null
loginfo "Image built."
}
start() {
existing=$(docker ps | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true)
if [[ $existing != "" ]]; then
loginfo "Nothing to do, your container has already started!"
exit 0
fi
check_version_match
chmod 0700 $dockerdir/bootstrap $sharedir/seafile/conf
set_existing_container
if [[ $existing != "" ]]; then
loginfo "starting up existing container"
(
set -x
docker start seafile
)
exit 0
fi
set_envs
set_volumes
set_ports
local restart_policy attach_on_run
if [[ "${SUPERVISED}" = "true" ]]; then
restart_policy="--restart=no"
attach_on_run="-a stdout -a stderr"
else
attach_on_run="-d"
fi
loginfo "Starting up new seafile server container"
(
set -x
docker run $user_args $attach_on_run $restart_policy --name seafile -h seafile $envs $volumes $ports $local_image
)
}
ensure_container_running() {
set_existing_container
if [[ $existing == "" ]]; then
err_and_quit "seafile was not started !"
fi
}
stop() {
ensure_container_running
(
set -x
docker stop -t 10 seafile
)
}
enter() {
ensure_container_running
(
set -x
docker exec -it seafile /bin/bash
)
}
restart() {
stop
start
}
gc() {
ensure_container_running
(
loginfo "Stop seafile and start the garbage collector"
set +e +x
docker exec -it seafile /scripts/gc.sh
gc_error=$?
if [[ $gc_error -eq 0 ]]; then
loginfo "Garbage collector finished!"
else
err_and_quit "Garbage collector exited with code $gc_error"
fi
)
}
check_prereqs() {
if [[ $SKIP_PREREQS == "true" ]]; then
return 0
fi
# check docker
if ! which docker >/dev/null; then
install_docker
fi
# TODO: check git version
}
logs() {
ensure_container_running
(
set -x
docker logs --tail=20 -f seafile
)
}
destroy() {
(
set -x
docker stop -t 10 seafile || true
docker rm seafile
)
}
get_major_version() {
echo $1| awk -F . '{printf "%s.%s", $1, $2}'
}
check_version_match() {
local last_version last_major_version current_major_version
last_version=$(cat $version_stamp_file)
last_major_version=$(get_major_version $last_version)
current_major_version=$(get_major_version $version)
logdbg "Your version: ${last_version}, latest version: ${version}"
if [[ $last_major_version != "$current_major_version" ]]; then
loginfo "******* Major upgrade detected *******"
loginfo "You have $last_version, latest is $version"
loginfo "Please run './launcher rebuild' to upgrade"
exit 1
fi
}
check_upgrade() {
loginfo "Checking if there is major version upgrade"
local last_version last_major_version current_major_version
last_version=$(cat $version_stamp_file)
last_major_version=$(get_major_version $last_version)
current_major_version=$(get_major_version $version)
if [[ $last_major_version == "$current_major_version" ]]; then
return
else
loginfo "********************************"
loginfo "Major upgrade detected: You have $last_version, latest is $version"
loginfo "********************************"
# use_manual_upgrade=true
if [[ $use_manual_upgrade == "true" ]]; then
loginfo "Now you can run './launcher manual-upgrade' to do manual upgrade."
exit 0
else
loginfo "Going to launch the docker container for manual upgrade"
_launch_for_upgrade --auto
fi
fi
}
_launch_for_upgrade() {
local cmd
if [[ $1 == "--auto" ]]; then
cmd="/scripts/upgrade.py"
else
cmd="/bin/bash"
fi
set_envs
set_volumes
(
set -x
docker run $user_args \
-it --rm --name seafile-upgrade -h seafile \
$envs $volumes $local_image \
/sbin/my_init $quiet -- $cmd
)
}
rebuild() {
if [[ "$(git symbolic-ref --short HEAD)" == "master" ]]; then
loginfo "Ensuring launcher is up to date"
git remote update
LOCAL=$(git rev-parse @)
REMOTE=$(git rev-parse "@{u}")
BASE=$(git merge-base @ "@{u}")
if [[ $LOCAL = "$REMOTE" ]]; then
loginfo "Launcher is up-to-date"
elif [[ $LOCAL = "$BASE" ]]; then
loginfo "Updating Launcher"
git pull || (echo 'failed to update' && exit 1)
for (( i=${#BASH_ARGV[@]}-1,j=0; i>=0,j<${#BASH_ARGV[@]}; i--,j++ ))
do
args[$j]=${BASH_ARGV[$i]}
done
exec /bin/bash $0 "${args[@]}" # $@ is empty, because of shift at the beginning. Use BASH_ARGV instead.
elif [[ $REMOTE = "$BASE" ]]; then
loginfo "Your version of Launcher is ahead of origin"
else
loginfo "Launcher has diverged source, this is only expected in Dev mode"
fi
fi
set_existing_container
if [[ $existing != "" ]]; then
loginfo "Stopping old container"
(
set -x
docker stop -t 10 seafile
)
fi
bootstrap
loginfo "Rebuilt successfully."
if [[ $existing != "" ]]; then
loginfo "Removing old container"
(
set -x
docker rm seafile
)
fi
check_upgrade
start
loginfo "Your seafile server is now running."
exit 0
}
manual_upgrade() {
_launch_for_upgrade
loginfo "If you have manually upgraded the server, please update the version stamp by:"
loginfo
loginfo " echo $version | sudo tee $version_stamp_file"
loginfo " sudo ./launcher start"
loginfo
}
main() {
local action
while [[ $# -gt 0 ]]
do
case "$1" in
bootstrap|start|stop|restart|enter|destroy|logs|rebuild|manual-upgrade|gc)
action=${1//-/_} ; shift 1 ;;
-h|--help) ( usage ; exit 1) ; shift 1 ;;
-v|--verbose) verbose=true ; shift 1 ;;
--skip-prereqs) SKIP_PREREQS=true ; shift 1 ;;
--docker-args) user_args=$2 ; shift 2 ;;
--manual-upgrade) use_manual_upgrade=true ; shift 1 ;;
*) err_and_quit "Argument error. Please see help." ;;
esac
done
# By default we suppress the verbose logs like "Running
# /etc/my_init.d/99_mysql_setup.sh". Use "./launcher -v <cmd>" to enable
# printing of these verbose logs.
quiet="--quiet"
if [[ $verbose == "true" ]]; then
quiet=""
fi
"$action"
}
check_prereqs
main "$@"
echo "================================================================================================================================="
echo "The launcher script is now deprecated. Please see https://github.com/haiwen/seafile-docker/blob/master/upgrade_from_old_format.md"
echo "================================================================================================================================="
echo
echo "Or run this command directly:"
echo
echo " docker rm -f seafile"
echo " docker run -d -it --name seafile -v $(dirname $PWD)/shared:/shared -p 80:80 -p 443:443 seafileltd/server"
echo
echo "================================================================================================================================="

View file

@ -1,602 +0,0 @@
# -*- buffer-file-coding-system: utf-8-unix -*-
<#
This is the powershell version of the launcher script to be used on windows.
you should use it instead of the linux 'launcher' script.
#>
$ErrorActionPreference = "Stop"
$version = "6.2.3"
$image = "seafileltd/seafile:$version"
$local_image = "local_seafile/server:latest"
$dockerdir = $PSScriptRoot.Replace("\", "/")
$sharedir = "$dockerdir/shared"
$installdir = "/opt/seafile/seafile-server-$version"
$bootstrap_conf="$dockerdir/bootstrap/bootstrap.conf"
$version_stamp_file="$sharedir/seafile/seafile-data/current_version"
$bash_history="$sharedir/.bash_history"
function usage() {
Write-Host "Usage: launcher.ps1 COMMAND [-skipPrereqs]"
Write-Host "Commands:"
Write-Host " start: Start/initialize the container"
Write-Host " stop: Stop a running container"
Write-Host " restart: Restart the container"
Write-Host " destroy: Stop and remove the container"
Write-Host " enter: Open a shell to run commands inside the container"
Write-Host " logs: View the Docker container logs"
Write-Host " bootstrap: Bootstrap the container based on a template"
Write-Host " rebuild: Rebuild the container (destroy old, bootstrap, start new)"
Write-Host ""
Write-Host "Options:"
Write-Host " -skipPrereqs Don't check launcher prerequisites"
exit 1
}
function main() {
Param(
[Parameter(Position=1)]
[string]$action,
[switch]$skipPrereqs,
[switch]$v
)
$script:action = $action
$script:skipPrereqs = $skipPrereqs
# Always verbose before we reach a stable release.
$script:v = $true
$script:verbose = $script:v
check_is_system_supported
if (!$action) {
usage
}
# loginfo "action = $action"
if (!$skipPrereqs) {
check_prereqs
}
switch ($action) {
"bootstrap" { do_bootstrap }
"start" { do_start }
"stop" { do_stop }
"restart" { do_restart }
"enter" { do_enter }
"destroy" { do_destroy }
"logs" { do_logs }
"rebuild" { do_rebuild }
"manual-upgrade" { do_manual_upgrade }
default { usage }
}
}
<# A Powershell version of the following bash code:
[[ $a == "1" ]] || {
# do something else when a != 1
}
Use it like:
do_if_not { where.exe docker } { loginfo "docker program doesn't exist"}
Currently the first branch must be a subprocess call.
#>
function do_if_not([scriptblock]$block_1, [scriptblock]$block_2) {
$failed = $false
$global:LASTEXITCODE = $null
try {
& $block_1
} catch [System.Management.Automation.RemoteException] {
$failed = $true
}
if ($failed -or !($global:LASTEXITCODE -eq 0)) {
& $block_2
}
}
function do_if([scriptblock]$block_1, [scriptblock]$block_2) {
$failed = $false
$global:LASTEXITCODE = $null
try {
& $block_1
} catch [System.Management.Automation.RemoteException] {
$failed = $true
}
if (!($failed) -and ($global:LASTEXITCODE -eq 0)) {
& $block_2
}
}
<#
Mimics python's `subproess.check_output`: Run the given command, capture the
output, and terminate the script if the command fails. For example:
check_output docker run ...
Code borrowed from http://stackoverflow.com/a/11549817/1467959
#>
function check_output($cmd) {
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = $cmd
$pinfo.RedirectStandardError = $false
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.WorkingDirectory = $PSScriptRoot
if ($args) {
$pinfo.Arguments = $args
}
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$p.WaitForExit()
echo "$stdout"
if (!($p.ExitCode -eq 0)) {
err_and_quit "The command $cmd $args failed"
}
}
<#
Mimics python's `subprocess.check_call`: Run the given command, capture the
output, and terminate the script if the command fails. For example:
check_call docker run ...
#>
function check_call($cmd) {
if ($args) {
$process = Start-Process -NoNewWindow -Wait -FilePath "$cmd" -ArgumentList $args -PassThru
} else {
$process = Start-Process -NoNewWindow -Wait -FilePath "$cmd" -PassThru
}
if (!($process.ExitCode -eq 0)) {
if ($script:on_call_error) {
err_and_quit $script:on_call_error
$script:on_call_error = $null
} else {
err_and_quit "The command $cmd $args failed with code $LASTEXITCODE"
}
}
}
function get_date_str() {
Get-Date -format "yyyy-MM-dd hh:mm:ss"
}
function err_and_quit($msg) {
Write-Host -BackgroundColor Black -ForegroundColor Yellow -Object "[$(get_date_str)] Error: $msg"
exit 1
}
function logdbg($msg) {
if ($script:verbose) {
loginfo "[debug] $msg"
}
}
function loginfo($msg) {
Write-Host -ForegroundColor Green -Object "[$(get_date_str)] $msg"
}
function program_exists($exe) {
try {
Get-Command "$exe" -CommandType Application 2>&1>$null
} catch [CommandNotFoundException] {
}
return $?
}
function to_unix_path($path) {
$path -replace '^|\\+','/' -replace ':'
}
$sharedir_u = $(to_unix_path $sharedir)
$dockerdir_u = $(to_unix_path $dockerdir)
function check_prereqs() {
if (!(program_exists "git.exe")) {
err_and_quit "You need to install git first. Check https://git-scm.com/download/win".
}
if (!(program_exists "docker.exe")) {
err_and_quit "You need to install docker first. Check https://docs.docker.com/docker-for-windows/."
}
}
function check_is_system_supported() {
$ver = [Environment]::OSVersion
if (!($ver.Version.Major -eq 10)) {
err_and_quit "Only Windows 10 is supported."
}
}
function set_envs() {
$script:envs = @()
if ($script:v) {
$script:envs += "-e"
$script:envs += "SEAFILE_DOCKER_VERBOSE=true"
}
}
# Call powershell mkdir, but only create the directory when it doesn't exist
function makedir($path) {
if (!(Test-Path $path)) {
New-Item -ItemType "Directory" -Force -Path $path 2>&1>$null
}
}
function touch($path) {
if (!(Test-Path $path)) {
New-Item -ItemType "file" -Path $path 2>&1>$null
}
}
function init_shared() {
makedir "$sharedir/seafile"
makedir "$sharedir/db"
makedir "$sharedir/logs/seafile"
makedir "$sharedir/logs/var-log"
makedir "$sharedir/logs/var-log/nginx"
touch "$sharedir/logs/var-log/syslog"
touch $bash_history
}
function set_bootstrap_volumes() {
init_shared
$mounts = @(
"${sharedir_u}:/shared",
"${sharedir_u}/logs/var-log:/var/log",
"${sharedir_u}/db:/var/lib/mysql",
"${dockerdir_u}/bootstrap:/bootstrap",
"${dockerdir_u}/scripts:/scripts:ro",
"${dockerdir_u}/templates:/templates:ro",
"${dockerdir_u}/scripts/tmp/check_init_admin.py:$installdir/check_init_admin.py:ro",
"${sharedir_u}/.bash_history:/root/.bash_history"
)
$script:volumes = @()
foreach($m in $mounts) {
$script:volumes += "-v"
$script:volumes += "$m"
}
}
function set_volumes() {
init_shared
$mounts = @(
"${sharedir_u}:/shared",
"${sharedir_u}/logs/var-log:/var/log",
"${sharedir_u}/db:/var/lib/mysql",
"${sharedir_u}/.bash_history:/root/.bash_history"
)
$script:volumes=@()
foreach($m in $mounts) {
$script:volumes += "-v"
$script:volumes += "$m"
}
}
function set_ports() {
$ports = $(check_output "docker" "run" "--rm" "-it" `
"-v" "${dockerdir_u}/scripts:/scripts" `
"-v" "${dockerdir_u}/bootstrap:/bootstrap:ro" `
$image `
"/scripts/bootstrap.py" "--parse-ports")
# The output is like "-p 80:80 -p 443:443", we need to split it into an array
$script:ports = $(-split $ports)
}
function set_my_init() {
$script:my_init = @("/sbin/my_init")
if (!($script:v)) {
$script:my_init += "--quiet"
}
}
function parse_seafile_container([array]$lines) {
foreach($line in $lines) {
$fields = $(-split $line)
if ("seafile".Equals($fields[-1])) {
echo $fields[0]
break
}
}
## We can write it using more elegant "ForEach-Object" using the following
## code, but someone says that "break" works like "continue" in the
## ForEach-Object's script block.
##
## See ## http://stackoverflow.com/a/7763698/1467959
##
## Anway, we use a foreach loop to keep the code
## simple.
##
# $lines | ForEach-Object {
# $fields =$(-split $_)
# if ("seafile".Equals($fields[-1])) {
# echo $fields[0]
# break
# }
# }
}
# Equivalent of `docker ps | awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true`
function set_running_container() {
try {
$script:existing = $(parse_seafile_container $(check_output docker ps))
} catch [System.Management.Automation.RemoteException] {
$script:existing = ""
}
}
# Equivalent of `docker ps -a |awk '{ print $1, $(NF) }' | grep " seafile$" | awk '{ print $1 }' || true`
function set_existing_container() {
try {
$script:existing = $(parse_seafile_container $(docker ps -a))
} catch [System.Management.Automation.RemoteException] {
$script:existing = ""
}
}
function ensure_container_running() {
set_existing_container
if (!($script:existing)) {
err_and_quit "seafile was not started !"
}
}
function ignore_error($cmd) {
if ($args) {
Start-Process -NoNewWindow -Wait -FilePath "$cmd" -ArgumentList $args
} else {
Start-Process -NoNewWindow -Wait -FilePath "$cmd"
}
}
function remove_container($container) {
do_if { docker inspect $container 2>&1>$null } {
docker rm -f $container 2>&1>$null
}
}
function do_bootstrap() {
if (!(Test-Path $bootstrap_conf)) {
err_and_quit "The file $bootstrap_conf doesn't exist. Have you run seafile-server-setup?"
}
do_if_not { docker history $image 2>&1>$null } {
loginfo "Pulling Seafile server image $version, this may take a while."
check_call docker pull $image
loginfo "Seafile server image $version pulled. Now bootstrapping the server ..."
}
set_envs
set_bootstrap_volumes
set_ports
set_my_init
# loginfo "ports is $script:ports"
remove_container "seafile-bootstrap"
check_call "docker" "run" "--rm" "-it" "--name" "seafile-bootstrap" `
"-e" "SEAFILE_BOOTSRAP=1" `
@script:envs `
@script:volumes `
@script:ports `
$image `
@script:my_init "--" "/scripts/bootstrap.py"
# @script:my_init "--" "/bin/bash"
loginfo "Now building the local docker image."
check_call "docker" "build" "-f" "bootstrap/generated/Dockerfile" "-t" "local_seafile/server:latest" "." 2>$null
loginfo "Image built."
}
function do_start() {
set_running_container
if ($script:running) {
loginfo "Nothing to do, your container has already started!"
exit 0
}
check_version_match
set_existing_container
if ($script:existing) {
loginfo "starting up existing container"
check_call docker start seafile
exit 0
}
set_envs
set_volumes
set_ports
$attach_on_run = @()
$restart_policy = @()
if ("true".Equals($SUPERVISED)) {
$restart_policy = @("--restart=no")
$attach_on_run = @("-a", "stdout", "-a", "stderr")
} else {
$attach_on_run = @("-d")
}
loginfo "Starting up new seafile server container"
remove_container "seafile"
docker run @attach_on_run @restart_policy --name seafile -h seafile @envs @volumes @ports $local_image
}
function do_rebuild() {
$branch=(check_output git symbolic-ref --short HEAD).Trim()
if ("master".Equals($branch)) {
loginfo "Ensuring launcher is up to date"
check_call git remote update
$LOCAL=(check_output git rev-parse "@").Trim()
$REMOTE=(check_output git rev-parse "@{u}").Trim()
$BASE=(check_output git merge-base "@" "@{u}").Trim()
if ($LOCAL.Equals($REMOTE)) {
loginfo "Launcher is up-to-date"
} elseif ($LOCAL.Equals($BASE)) {
loginfo "Updating Launcher"
do_if_not { git pull } {
err_and_quit "failed to update"
}
$myself = Join-Path $PSScriptRoot $script:MyInvocation.MyCommand
$newargs = @($myself) + $script:args
# logdbg "Running: Start-Process -NoNewWindow -FilePath powershell.exe -ArgumentList $($newargs)"
Start-Process -NoNewWindow -FilePath powershell.exe -ArgumentList $newargs -Wait
exit 0
} elseif ($REMOTE.Equals($BASE)) {
loginfo "Your version of Launcher is ahead of origin"
} else {
loginfo "Launcher has diverged source, this is only expected in Dev mode"
}
}
set_existing_container
if ($script:existing) {
loginfo "Stopping old container"
check_call docker stop -t 10 seafile
}
do_bootstrap
loginfo "Rebuilt successfully."
if ($script:existing) {
loginfo "Removing old container"
check_call docker rm seafile
}
check_upgrade
do_start
loginfo "Your seafile server is now running."
}
function get_major_version($ver) {
echo "$($ver.Split(".")[0..1] -join ".")"
}
function check_version_match() {
$last_version=(Get-Content $version_stamp_file).Trim()
$last_major_version=$(get_major_version $last_version)
$current_major_version=$(get_major_version $version)
logdbg "Your version: ${last_version}, latest version: ${version}"
if (!($last_major_version.Equals($current_major_version))) {
loginfo "******* Major upgrade detected *******"
loginfo "You have $last_version, latest is $version"
loginfo "Please run './launcher.ps1 rebuild' to upgrade"
exit 1
}
}
function check_upgrade() {
loginfo "Checking if there is major version upgrade"
$last_version=(Get-Content $version_stamp_file).Trim()
$last_major_version=$(get_major_version $last_version)
$current_major_version=$(get_major_version $version)
if ($last_major_version.Equals($current_major_version)) {
return
} else {
loginfo "********************************"
loginfo "Major upgrade detected: You have $last_version, latest is $version"
loginfo "********************************"
# $use_manual_upgrade="true"
if ("true".Equals($use_manual_upgrade)) {
loginfo "Now you can run './launcher.ps1 manual-upgrade' to do manual upgrade."
exit 0
} else {
loginfo "Going to launch the docker container for manual upgrade"
_launch_for_upgrade -auto
}
}
}
function _launch_for_upgrade([switch]$auto) {
if ($auto) {
$script:on_call_error = 'Failed to upgrade to latest version. You can try run it manually by "./launcher.ps1 manual-upgrade"'
$cmd="/scripts/upgrade.py"
} else {
$script:on_call_error = "Upgrade failed"
$cmd="/bin/bash"
}
set_envs
set_volumes
remove_container seafile-upgrade
check_call docker run `
-it -rm --name seafile-upgrade -h seafile `
@script:envs @script:volumes $local_image `
@script:my_init -- $cmd
}
function do_manual_upgrade() {
_launch_for_upgrade
loginfo "If you have manually upgraded the server, please update the version stamp by:"
loginfo
loginfo " Set-Content -Path ""$version_stamp_file"" -Value $version"
loginfo " ./launcher.ps1 start"
loginfo
}
function do_stop() {
ensure_container_running
loginfo "Stopping seafile container"
check_call docker stop -t 10 seafile
}
function do_restart() {
do_stop
do_start
}
function do_enter() {
ensure_container_running
loginfo "Launching a linux bash shell in the seafile container"
docker exec -it seafile /bin/bash
}
function do_destroy() {
loginfo "Stopping seafile container"
ignore_error docker stop -t 10 seafile
ignore_error docker rm seafile
}
function do_logs() {
ensure_container_running
docker logs --tail=20 -f seafile
}
main @args

View file

@ -6,4 +6,3 @@ admin.email = me@example.com
admin.password = asecret
server.letsencrypt = true
server.port_mappings = 80:80,443:443

View file

@ -4,7 +4,5 @@ server.hostname = seafile.example.com
admin.email = me@example.com
admin.password = asecret
# Comment out this line and uncomment the two lines below to use letsencrypt SSL certificate
server.port_mappings = 80:80
# uncomment the one lines below to use letsencrypt SSL certificate
# server.letsencrypt = true
# server.port_mappings = 80:80,443:443

View file

@ -1,107 +0,0 @@
#!/bin/bash
set -e
set -o pipefail
err_and_quit () {
printf "\n\n\033[33mError occured during setup. \nPlease fix possible issues and run the script again.\033[m\n\n"
exit 1
}
on_ctrl_c_pressed () {
printf "\n\n\033[33mYou have pressed Ctrl-C. Setup is interrupted.\033[m\n\n"
exit 1
}
# clean newly created ccnet/seafile configs when exit on SIGINT
trap on_ctrl_c_pressed 2
read_yes_no () {
printf "[yes|no] "
read yesno
while [[ "$yesno" != "yes" && "$yesno" != "no" ]]
do
printf "please answer [yes|no] "
read yesno
done
if [[ "$yesno" == "no" ]]; then
return 1
else
return 0
fi
}
ask_question () {
local question default key
question=$1
default=$2
key=$3
printf "$question"
printf "\n"
if [[ "$default" != "" && "$default" != "nodefault" ]]; then
printf "[default: $default] "
elif [[ "$key" != "" ]]; then
printf "[$key]: "
fi
}
get_server_name () {
local question="Host name for your seafile server?" default="seafile.example.com"
ask_question "$question" "seafile.example.com"
read server_name
if [[ "$server_name" == "" ]]; then
server_name=$default
elif [[ ! $server_name =~ ^[a-zA-Z0-9_-.]+$ ]]; then
printf "\n\033[33m${server_name}\033[m is not a valid name.\n"
get_server_name
fi
echo
}
# echo "Please specify the email address and password for the seahub administrator."
# echo "You can use them to login as admin on your seahub website."
# echo
get_admin_email () {
local question="Admin email address for your seafile server?" default="me@example.com"
ask_question "$question" "$default"
read admin_email
if [[ "$admin_email" == "" ]]; then
admin_email=$default
elif [[ ! $admin_email =~ ^.+@.*\..+$ ]]; then
echo "$admin_email is not a valid email address"
get_admin_email
fi
}
get_admin_passwd () {
local question="Admin password for your seafile server?"
ask_question "$question" "nodefault" "seahub admin password"
read -s admin_passwd
echo
question="Please enter the password again:"
ask_question "$question" "nodefault" "seahub admin password again"
read -s admin_passwd_again
echo
if [[ "$admin_passwd" != "$admin_passwd_again" ]]; then
printf "\033[33mThe passwords didn't match.\033[m"
get_admin_passwd
elif [[ "$admin_passwd" == "" ]]; then
echo "Password cannot be empty."
get_admin_passwd
fi
}
get_server_name
get_admin_email
get_admin_passwd
cat >bootstrap/bootstrap.conf<<EOF
[server]
server.hostname = $server_name
admin.email = $admin_email
admin.password = $admin_passwd
EOF
./launcher bootstrap && ./launcher start

View file

@ -0,0 +1,21 @@
Follow these steps:
1. Stop the old container.
2. Delete the old container.
3. Delete the old images.
4. Clone the latest docker project.
5. Build the new images.
6. Run the new container.
e.g.
Assume your old project path is /opt/seafile-docker, so your data path is /opt/seafile-docker/shared.
docker stop seafile
docker rm seafile
docker rmi $(image id)
git cloen https://github.com/haiwen/seafile-docker.git
cd images && make base && make server
docker run -it --name seafile -v /opt/seafile-docker/shared:/shared -p 80:80 -p 443:443 seafileltd/seafile:6.2.3
Congratulations, you've upgraded to a new version.