安装docker管理器

在宝塔软件列表,安装docker管理器:image.png
打开docker管理器,点击镜像加速
image.png
输入三个加速网址:
image.png

  1. https://cr.console.aliyun.com
  2. http://hub-mirror.c.163.com
  3. https://registry.docker-cn.com

点击获取镜像,输入

  1. onlyoffice/documentserver

镜像很大,需要很长的时间。

创建容器

我们将容器的数据存储在容器外部,所以,在/data目录上创建以下目录

  1. cd /data
  2. mkdir onlyoffice
  3. cd onlyoffice
  4. mkdir db
  5. mkdir data
  6. mkdir lib
  7. mkdir log

点击创建容器,容器端口80,映射到外部端口9002,要点击+号生效。目录映射如下:
/var/log/onlyoffice用于ONLYOFFICE文档日志
/var/www/onlyoffice/Data 证书
/var/lib/onlyoffice 用于文件缓存
/var/lib/postgresql 用于数据库

  1. /onlyoffice/log:/var/log/onlyoffice
  2. /onlyoffice/data:/var/www/onlyoffice/Data
  3. /onlyoffice/lib:/var/lib/onlyoffice
  4. /onlyoffice/db:/var/lib/postgresql

webwxgetmsgimg.jpg
内存配额,我们配个10GB即可。创建完成后,我们可以输入ip访问:

  1. http://10.239.55.250:9002/

出现如下界面表示连接成功:
image.png

创建样例

上面的页面底部提示创建样例的命令,我们在终端执行:

  1. sudo docker exec bf242d16a36e sudo supervisorctl start ds:example
  2. sudo docker exec bf242d16a36e sudo sed 's,autostart=false,autostart=true,' -i /etc/supervisor/conf.d/ds-example.conf

执行后,就可以点击底部按钮访问了:
image.png
访问样例:
image.png
上传一个excel试试,点击文件,访问结果:
image.png

设置中文

现在是英文界面,我们在首页点击左下角,设置为chinese:
image.png
这样就可以了。
image.png

故障排除

如果无法打开网址,可能是没有映射成功端口,很大的原因是创建容器输入端口,没有点+号。可执行以下命令查看:

  1. docker ps -a

webwxgetmsgimg (1).jpg
出现9002->80就是映射成功了。

外网访问

主服务器上安装了宝塔,解析域名bk.dzbfsj.com到宝塔一个站点,站点设置中加一个反代:
image.png
这样,外网就能输入:http://bk.dzbfsj.com:20080/访问了。

集成到Laravel Dcat admin

现在可以上传文件预览编辑了,但我们需要的是,在自己的系统中集成预览编辑功能,比如laravel的dcat admin后台。

创建文件管理器

  1. 创建后台路由:

    1. //档案存储
    2. $router->get('media', 'MediaController@index')->name('media-index');
    3. $router->get('media/download', 'MediaController@download')->name('media-download');
    4. $router->get('media/read', 'MediaController@read')->name('media-read');//在线阅读
    5. $router->get('media/edit', 'MediaController@edit')->name('media-edit');//在线编辑
    6. $router->delete('media/delete', 'MediaController@delete')->name('media-delete');
    7. $router->put('media/move', 'MediaController@move')->name('media-move');
    8. $router->post('media/upload', 'MediaController@upload')->name('media-upload');
    9. $router->post('media/folder', 'MediaController@newFolder')->name('media-new-folder');
  2. 创建控制器MediaManager.php: ```php <?php

namespace App\Admin\Controllers;

use App\Admin\Metrics\Examples; use App\Http\Controllers\Controller; use Dcat\Admin\Http\Controllers\Dashboard; use Dcat\Admin\Layout\Column; use Dcat\Admin\Layout\Content; use Dcat\Admin\Layout\Row; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\File; //use Dcat\Admin\Exception\Handler; use Illuminate\Http\UploadedFile; use Illuminate\Http\Request; use Dcat\Admin\Http\JsonResponse; use Admin;

class MediaManager extends Controller {

protected $path = '/';

protected $storage;

protected $fileTypes = [
    'image' => 'png|jpg|jpeg|tmp|gif',
    'word'  => 'doc|docx',
    'xls'   => 'xls|xlsx',
    'ppt'   => 'ppt|pptx',
    'pdf'   => 'pdf',
    'code'  => 'php|js|java|python|ruby|go|c|cpp|sql|m|h|json|html|aspx',
    'zip'   => 'zip|tar\.gz|rar|rpm',
    'txt'   => 'txt|pac|log|md',
    'audio' => 'mp3|wav|flac|3pg|aa|aac|ape|au|m4a|mpc|ogg',
    'video' => 'mkv|rmvb|flv|mp4|avi|wmv|rm|asf|mpeg',
];


public function __construct($path = '/')
{
    $this->path = $path;

    $this->initStorage();
}

private function initStorage()
{
    $disk = config('admin.upload.disk');

    $this->storage = Storage::disk($disk);

    if (!$this->storage->getDriver()->getAdapter() instanceof Local) {
        return JsonResponse::make()->error('只能管理本地文件');
    }
}

public function ls()
{
    if (!$this->exists()) {
        return [];
    }

    $files = $this->storage->files($this->path);

    $directories = $this->storage->directories($this->path);

    return $this->formatDirectories($directories)
        ->merge($this->formatFiles($files))
        ->sort(function ($item) {
            return $item['name'];
        })->all();
}

public function getFullPath($path)
{
    return $this->storage->getDriver()->getAdapter()->applyPathPrefix($path);
}

public function download()
{
    $fullPath = $this->getFullPath($this->path);

    if (File::isFile($fullPath)) {
        return response()->download($fullPath);
    }

    return response('', 404);
}

public function delete($path)
{
    $paths = is_array($path) ? $path : func_get_args();

    foreach ($paths as $path) {
        $fullPath = $this->getFullPath($path);

        if (is_file($fullPath)) {
            $this->storage->delete($path);
        } else {
            $this->storage->deleteDirectory($path);
        }
    }

    return true;
}

public function move($new)
{
    return $this->storage->move($this->path, $new);
}

/**
 * @param UploadedFile[] $files
 * @param string         $dir
 *
 * @return mixed
 */
public function upload($files = [])
{
    foreach ($files as $file) {
        $this->storage->putFileAs($this->path, $file, $file->getClientOriginalName());
    }

    return true;
}

public function newFolder($name)
{
    $path = rtrim($this->path, '/').'/'.trim($name, '/');

    return $this->storage->makeDirectory($path);
}

public function exists()
{
    $path = $this->getFullPath($this->path);

    return file_exists($path);
}

/**
 * @return array
 */
public function urls()
{
    return [
        'path'       => $this->path,
        'index'      => admin_route('media-index'),
        'move'       => admin_route('media-move'),
        'delete'     => admin_route('media-delete'),
        'upload'     => admin_route('media-upload'),
        'new-folder' => admin_route('media-new-folder'),
    ];
}

public function formatFiles($files = [])
{
    $files = array_map(function ($file) {
        return [
            'download'  => admin_route('media-download', compact('file')),
            'icon'      => '',
            'name'      => $file,
            'preview'   => $this->getFilePreview($file),
            'isDir'     => false,
            'size'      => $this->getFilesize($file),
            'link'      => admin_route('media-download', compact('file')),
            'read'      => admin_route('media-read', compact('file')),
            'edit'      => admin_route('media-edit', compact('file')),
            'url'       => $this->storage->url($file),
            'time'      => $this->getFileChangeTime($file),
        ];
    }, $files);

    return collect($files);
}

public function formatDirectories($dirs = [])
{
    $url = admin_route('media-index', ['path' => '__path__', 'view' => request('view')]);

    $preview = "<a href=\"$url\"><span class=\"file-icon text-aqua\"><i class=\"fa fa-folder\"></i></span></a>";

    $dirs = array_map(function ($dir) use ($preview) {
        return [
            'download'  => '',
            'icon'      => '',
            'name'      => $dir,
            'preview'   => str_replace('__path__', $dir, $preview),
            'isDir'     => true,
            'size'      => '',
            'link'      => admin_route('media-index', ['path' => '/'.trim($dir, '/'), 'view' => request('view')]),
            'read'      => admin_route('media-index', ['path' => '/'.trim($dir, '/'), 'view' => request('view')]),
            'edit'      => admin_route('media-index', ['path' => '/'.trim($dir, '/'), 'view' => request('view')]),
            'url'       => $this->storage->url($dir),
            'time'      => $this->getFileChangeTime($dir),
        ];
    }, $dirs);

    return collect($dirs);
}

public function navigation()
{
    $folders = explode('/', $this->path);

    $folders = array_filter($folders);

    $path = '';

    $navigation = [];

    foreach ($folders as $folder) {
        $path = rtrim($path, '/').'/'.$folder;

        $navigation[] = [
            'name'  => $folder,
            'url'   => admin_route('media-index', ['path' => $path]),
        ];
    }

    return $navigation;
}

public function getFilePreview($file)
{
    switch ($this->detectFileType($file)) {
        case 'image':

            if ($this->storage->getDriver()->getConfig()->has('url')) {
                $url = $this->storage->url($file);
                $preview = "<span class=\"file-icon has-img\"><img src=\"$url\" alt=\"Attachment\"></span>";
            } else {
                $preview = '<span class="file-icon"><i class="fa fa-file-image-o"></i></span>';
            }
            break;

        case 'pdf':
            $preview = '<span class="file-icon"><i class="fa fa-file-pdf-o"></i></span>';
            break;

        case 'zip':
            $preview = '<span class="file-icon"><i class="fa fa-file-zip-o"></i></span>';
            break;

        case 'word':
            $preview = '<span class="file-icon"><i class="fa fa-file-word-o"></i></span>';
            break;

        case 'ppt':
            $preview = '<span class="file-icon"><i class="fa fa-file-powerpoint-o"></i></span>';
            break;

        case 'xls':
            $preview = '<span class="file-icon"><i class="fa fa-file-excel-o"></i></span>';
            break;

        case 'txt':
            $preview = '<span class="file-icon"><i class="fa fa-file-text-o"></i></span>';
            break;

        case 'code':
            $preview = '<span class="file-icon"><i class="fa fa-code"></i></span>';
            break;

        default:
            $preview = '<span class="file-icon"><i class="fa fa-file"></i></span>';
    }

    return $preview;
}

public function detectFileType($file)
{
    $extension = File::extension($file);

    foreach ($this->fileTypes as $type => $regex) {
        if (preg_match("/^($regex)$/i", $extension) !== 0) {
            return $type;
        }
    }

    return false;
}

public function getFilesize($file)
{
    $bytes = filesize($this->getFullPath($file));

    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];

    for ($i = 0; $bytes > 1024; $i++) {
        $bytes /= 1024;
    }

    return round($bytes, 2).' '.$units[$i];
}

public function getFileChangeTime($file)
{
    $time = filectime($this->getFullPath($file));

    return date('Y-m-d H:i:s', $time);
}

} ```

  1. 创建控制器MediaController.php,其中read和edit方法是新增的用于对接onlyoffice: