Installer Nextcloud avec docker-compose sur Debian 10 avec Nginx en reverse-proxy¶
1. Installer nginx¶
Nginx est un serveur web, comme Apache.
Nous allons l'utiliser comme reverse-proxy, c'est-à-dire qu'il renverra les requêtes d'un autre serveur, que nous installerons aux côtés de wordpress.
Ainsi nous pourrons utiliser le serveur de notre choix pour notre web-application Wordpress (Apache ou Nginx).
On installe Nginx à partir des dépôts Debian, de façon à avoir une version stable, avec l'apport des correctifs de sécurité, et qui ne sera jamais cassé par une modification du système.
sudo apt update
sudo apt upgrade
sudo apt install nginx
Dans votre navigateur, en tapant dabs la barre d'adresse http://IP_DU_SERVEUR
, vous devriez accéder à la page d'accueil de nginx
2. Installation de docker¶
2.1 Installation des dépendances¶
sudo apt update
sudo apt -y install apt-transport-https ca-certificates curl gnupg2 software-properties-common
2.2 Installation de la clé du dépôt Docker¶
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
2.3 Ajout du dépôt docker dans le sources.list¶
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/debian \
$(lsb_release -cs) \
stable"
2.4 Mise à jour de la liste des paquets et installation de docker¶
sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io
2.5 Ajout de l'utilisateur dans le groupe docker pour utiliser docker sans sudo¶
sudo usermod -aG docker $USER
newgrp docker
3. Installation de Docker-Compose¶
3.1 Téléchargement de Docker-Compose¶
curl -s https://api.github.com/repos/docker/compose/releases/latest \
| grep browser_download_url \
| grep docker-compose-linux-x86_64 \
| cut -d '"' -f 4 \
| wget -qi -
3.2 Mise en place de l'exécutable¶
chmod +x docker-compose-linux-x86_64 && sudo mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose
sudo systemctl restart docker
3.3 Auto-complétion pour Bash¶
sudo mkdir -p /etc/bash_completion.d
sudo curl -L https://raw.githubusercontent.com/docker/compose/master/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
source /etc/bash_completion.d/docker-compose
Docker et Docker-compose sont maintenant installés
4. Mise en place de Nextcloud, collabora, etherpad, coturn, redis avec docker-compose¶
4.1 Création d'un dossier pour le projet¶
mkdir nextcloud && cd nextcloud
4.2 Fichiers de configuration pour nextcloud¶
Nous avons besoin de créer les fichiers suivants pour qu'ils soient utilisés par l'image de nextcloud:
4.2.1 config.php¶
config.php
<?php
$CONFIG = array (
'htaccess.RewriteBase' => '/',
'memcache.local' => '\\OC\\Memcache\\APCu',
'apps_paths' =>
array (
0 =>
array (
'path' => '/var/www/html/apps',
'url' => '/apps',
'writable' => false,
),
1 =>
array (
'path' => '/var/www/html/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
'memcache.distributed' => '\\OC\\Memcache\\Redis',
'memcache.locking' => '\\OC\\Memcache\\Redis',
'redis' =>
array (
'host' => 'redisnext',
'port' => 6379,
'password' => false,
),
'trusted_domains' =>
array (
0 => 'nextcloud.mondomaine.fr',
1 => 'nextcloud',
),
'trusted_proxies' =>
array (
0 => '172.17.0.1',
1 => '172.22.0.1',
2 => '172.23.0.1',
3 => '172.21.0.1',
),
'skeletondirectory' => '',
'datadirectory' => '/data',
'dbtype' => 'mysql',
'overwrite.cli.url' => 'https://nextcloud.mondomaine.fr',
'dbname' => 'dbnext',
'dbhost' => 'databasenext',
'dbport' => '',
'dbtableprefix' => 'oc_',
'mysql.utf8mb4' => true,
'dbuser' => 'nextclouduser',
'dbpassword' => 'azdqsdokpokpokds098098',
'installed' => true,
'loglevel' => 2,
'maintenance' => false,
'app_install_overwrite' =>
array (
0 => 'dashboard',
1 => 'files_clipboard',
2 => 'afterlogic',
3 => 'ownpad',
),
'mail_from_address' => 'contact',
'mail_smtpmode' => 'smtp',
'mail_sendmailmode' => 'smtp',
'mail_domain' => 'mondomaine.fr',
'mail_smtphost' => 'mail.mymailprovider.net',
'mail_smtpsecure' => 'tls',
'mail_smtpport' => '587',
'mail_smtpauthtype' => 'LOGIN',
'mail_smtpauth' => 1,
'mail_smtpname' => 'contact@mondomaine.fr',
'mail_smtppassword' => 'MYSMTPPASSWORD',
'has_rebuilt_cache' => true,
'overwriteprotocol' => 'https',
'theme' => '',
'default_language' => 'fr',
'default_locale' => 'fr_FR',
'defaultapp' => 'files',
);
4.2.2 Internal.php¶
Internal.php
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
* @author cetra3 <peter@parashift.com.au>
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author MartB <mart.b@outlook.de>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <robin@icewind.nl>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Victor Dubiniuk <dubiniuk@owncloud.com>
*
* @license AGPL-3.0
*
* This code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License, version 3,
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
*/
namespace OC\Session;
use OC\Authentication\Exceptions\InvalidTokenException;
use OC\Authentication\Token\IProvider;
use OCP\Session\Exceptions\SessionNotAvailableException;
/**
* Class Internal
*
* wrap php's internal session handling into the Session interface
*
* @package OC\Session
*/
class Internal extends Session {
/**
* @param string $name
* @throws \Exception
*/
public function __construct(string $name) {
set_error_handler([$this, 'trapError']);
$this->invoke('session_name', [$name]);
try {
$this->startSession();
} catch (\Exception $e) {
setcookie($this->invoke('session_name'), '', -1, \OC::$WEBROOT ?: '/');
}
restore_error_handler();
if (!isset($_SESSION)) {
throw new \Exception('Failed to start session');
}
}
/**
* @param string $key
* @param integer $value
*/
public function set(string $key, $value) {
$this->validateSession();
$_SESSION[$key] = $value;
}
/**
* @param string $key
* @return mixed
*/
public function get(string $key) {
if (!$this->exists($key)) {
return null;
}
return $_SESSION[$key];
}
/**
* @param string $key
* @return bool
*/
public function exists(string $key): bool {
return isset($_SESSION[$key]);
}
/**
* @param string $key
*/
public function remove(string $key) {
if (isset($_SESSION[$key])) {
unset($_SESSION[$key]);
}
}
public function clear() {
$this->invoke('session_unset');
$this->regenerateId();
$_SESSION = [];
}
public function close() {
$this->invoke('session_write_close');
parent::close();
}
/**
* Wrapper around session_regenerate_id
*
* @param bool $deleteOldSession Whether to delete the old associated session file or not.
* @param bool $updateToken Wheater to update the associated auth token
* @return void
*/
public function regenerateId(bool $deleteOldSession = true, bool $updateToken = false) {
$oldId = null;
if ($updateToken) {
// Get the old id to update the token
try {
$oldId = $this->getId();
} catch (SessionNotAvailableException $e) {
// We can't update a token if there is no previous id
$updateToken = false;
}
}
try {
@session_regenerate_id($deleteOldSession);
} catch (\Error $e) {
$this->trapError($e->getCode(), $e->getMessage());
}
if ($updateToken) {
// Get the new id to update the token
$newId = $this->getId();
/** @var IProvider $tokenProvider */
$tokenProvider = \OC::$server->query(IProvider::class);
try {
$tokenProvider->renewSessionToken($oldId, $newId);
} catch (InvalidTokenException $e) {
// Just ignore
}
}
}
/**
* Wrapper around session_id
*
* @return string
* @throws SessionNotAvailableException
* @since 9.1.0
*/
public function getId(): string {
$id = $this->invoke('session_id', [], true);
if ($id === '') {
throw new SessionNotAvailableException();
}
return $id;
}
/**
* @throws \Exception
*/
public function reopen() {
throw new \Exception('The session cannot be reopened - reopen() is ony to be used in unit testing.');
}
/**
* @param int $errorNumber
* @param string $errorString
* @throws \ErrorException
*/
public function trapError(int $errorNumber, string $errorString) {
throw new \ErrorException($errorString);
}
/**
* @throws \Exception
*/
private function validateSession() {
if ($this->sessionClosed) {
throw new SessionNotAvailableException('Session has been closed - no further changes to the session are allowed');
}
}
/**
* @param string $functionName the full session_* function name
* @param array $parameters
* @param bool $silence whether to suppress warnings
* @throws \ErrorException via trapError
* @return mixed
*/
private function invoke(string $functionName, array $parameters = [], bool $silence = false) {
try {
if ($silence) {
return @call_user_func_array($functionName, $parameters);
} else {
return call_user_func_array($functionName, $parameters);
}
} catch (\Error $e) {
$this->trapError($e->getCode(), $e->getMessage());
}
}
private function startSession() {
if (PHP_VERSION_ID < 70300) {
$this->invoke('session_start');
} else {
$this->invoke('session_start', [['cookie_samesite' => 'Lax']]);
}
}
}
4.2.3 mimetypemapping.json¶
mimetypemapping.json
{
"drawio": ["application/x-drawio"],
"pad": ["application/x-ownpad"],
"calc": ["application/x-ownpad"],
"3gp": ["video/3gpp"],
"7z": ["application/x-7z-compressed"],
"accdb": ["application/msaccess"],
"ai": ["application/illustrator"],
"apk": ["application/vnd.android.package-archive"],
"arw": ["image/x-dcraw"],
"avi": ["video/x-msvideo"],
"bash": ["text/x-shellscript"],
"bat": ["application/x-msdos-program"],
"blend": ["application/x-blender"],
"bin": ["application/x-bin"],
"bmp": ["image/bmp"],
"bpg": ["image/bpg"],
"bz2": ["application/x-bzip2"],
"cb7": ["application/comicbook+7z"],
"cba": ["application/comicbook+ace"],
"cbr": ["application/comicbook+rar"],
"cbt": ["application/comicbook+tar"],
"cbtc": ["application/comicbook+truecrypt"],
"cbz": ["application/comicbook+zip"],
"cc": ["text/x-c"],
"cdr": ["application/coreldraw"],
"class": ["application/java"],
"cmd": ["application/cmd"],
"cnf": ["text/plain"],
"conf": ["text/plain"],
"cpp": ["text/x-c++src"],
"cr2": ["image/x-dcraw"],
"css": ["text/css"],
"csv": ["text/csv"],
"cvbdl": ["application/x-cbr"],
"c": ["text/x-c"],
"c++": ["text/x-c++src"],
"dcr": ["image/x-dcraw"],
"deb": ["application/x-deb"],
"dng": ["image/x-dcraw"],
"doc": ["application/msword"],
"docm": ["application/vnd.ms-word.document.macroEnabled.12"],
"docx": ["application/vnd.openxmlformats-officedocument.wordprocessingml.document"],
"dot": ["application/msword"],
"dotx": ["application/vnd.openxmlformats-officedocument.wordprocessingml.template"],
"dv": ["video/dv"],
"eot": ["application/vnd.ms-fontobject"],
"epub": ["application/epub+zip"],
"eps": ["application/postscript"],
"erf": ["image/x-dcraw"],
"exe": ["application/x-ms-dos-executable"],
"fb2": ["application/x-fictionbook+xml", "text/plain"],
"flac": ["audio/flac"],
"flv": ["video/x-flv"],
"gif": ["image/gif"],
"gpx": ["application/gpx+xml"],
"gz": ["application/x-gzip"],
"gzip": ["application/x-gzip"],
"h": ["text/x-h"],
"heic": ["image/heic"],
"heif": ["image/heif"],
"hh": ["text/x-h"],
"hpp": ["text/x-h"],
"htaccess": ["text/plain"],
"html": ["text/html", "text/plain"],
"htm": ["text/html", "text/plain"],
"ical": ["text/calendar"],
"ics": ["text/calendar"],
"iiq": ["image/x-dcraw"],
"impress": ["text/impress"],
"java": ["text/x-java-source"],
"jp2": ["image/jp2"],
"jpeg": ["image/jpeg"],
"jpg": ["image/jpeg"],
"jps": ["image/jpeg"],
"js": ["application/javascript", "text/plain"],
"json": ["application/json", "text/plain"],
"k25": ["image/x-dcraw"],
"kdbx": ["application/x-kdbx"],
"kdc": ["image/x-dcraw"],
"key": ["application/x-iwork-keynote-sffkey"],
"keynote": ["application/x-iwork-keynote-sffkey"],
"km": ["application/km"],
"kml": ["application/vnd.google-earth.kml+xml"],
"kmz": ["application/vnd.google-earth.kmz"],
"kra": ["application/x-krita"],
"ldif": ["text/x-ldif"],
"lwp": ["application/vnd.lotus-wordpro"],
"m2t": ["video/mp2t"],
"m3u": ["audio/mpegurl"],
"m3u8": ["audio/mpegurl"],
"m4a": ["audio/mp4"],
"m4b": ["audio/m4b"],
"m4v": ["video/mp4"],
"markdown": ["text/markdown"],
"mdown": ["text/markdown"],
"md": ["text/markdown"],
"mdb": ["application/msaccess"],
"mdwn": ["text/markdown"],
"mkd": ["text/markdown"],
"mef": ["image/x-dcraw"],
"mkv": ["video/x-matroska"],
"mm": ["application/x-freemind"],
"mobi": ["application/x-mobipocket-ebook"],
"mov": ["video/quicktime"],
"mp3": ["audio/mpeg"],
"mp4": ["video/mp4"],
"mpeg": ["video/mpeg"],
"mpg": ["video/mpeg"],
"mpo": ["image/jpeg"],
"msi": ["application/x-msi"],
"mts": ["video/MP2T"],
"mt2s": ["video/MP2T"],
"nef": ["image/x-dcraw"],
"numbers": ["application/x-iwork-numbers-sffnumbers"],
"odf": ["application/vnd.oasis.opendocument.formula"],
"odg": ["application/vnd.oasis.opendocument.graphics"],
"odp": ["application/vnd.oasis.opendocument.presentation"],
"ods": ["application/vnd.oasis.opendocument.spreadsheet"],
"odt": ["application/vnd.oasis.opendocument.text"],
"oga": ["audio/ogg"],
"ogg": ["audio/ogg"],
"ogv": ["video/ogg"],
"one": ["application/msonenote"],
"opus": ["audio/ogg"],
"orf": ["image/x-dcraw"],
"otf": ["application/font-sfnt"],
"pages": ["application/x-iwork-pages-sffpages"],
"pdf": ["application/pdf"],
"pfb": ["application/x-font"],
"pef": ["image/x-dcraw"],
"php": ["application/x-php"],
"pl": ["application/x-perl"],
"pls": ["audio/x-scpls"],
"png": ["image/png"],
"pot": ["application/vnd.ms-powerpoint"],
"potm": ["application/vnd.ms-powerpoint.template.macroEnabled.12"],
"potx": ["application/vnd.openxmlformats-officedocument.presentationml.template"],
"ppa": ["application/vnd.ms-powerpoint"],
"ppam": ["application/vnd.ms-powerpoint.addin.macroEnabled.12"],
"pps": ["application/vnd.ms-powerpoint"],
"ppsm": ["application/vnd.ms-powerpoint.slideshow.macroEnabled.12"],
"ppsx": ["application/vnd.openxmlformats-officedocument.presentationml.slideshow"],
"ppt": ["application/vnd.ms-powerpoint"],
"pptm": ["application/vnd.ms-powerpoint.presentation.macroEnabled.12"],
"pptx": ["application/vnd.openxmlformats-officedocument.presentationml.presentation"],
"ps": ["application/postscript"],
"psd": ["application/x-photoshop"],
"py": ["text/x-python"],
"raf": ["image/x-dcraw"],
"rar": ["application/x-rar-compressed"], "reveal": ["text/reveal"],
"rss": ["application/rss+xml"],
"rtf": ["text/rtf"],
"rw2": ["image/x-dcraw"],
"schema": ["text/plain"],
"sgf": ["application/sgf"],
"sh-lib": ["text/x-shellscript"],
"sh": ["text/x-shellscript"],
"srf": ["image/x-dcraw"],
"sr2": ["image/x-dcraw"],
"svg": ["image/svg+xml", "text/plain"],
"swf": ["application/x-shockwave-flash", "application/octet-stream"],
"tar": ["application/x-tar"],
"tar.bz2": ["application/x-bzip2"],
"tar.gz": ["application/x-compressed"],
"tbz2": ["application/x-bzip2"],
"tcx": ["application/vnd.garmin.tcx+xml"],
"tex": ["application/x-tex"],
"tgz": ["application/x-compressed"],
"tiff": ["image/tiff"],
"tif": ["image/tiff"],
"ttf": ["application/font-sfnt"],
"txt": ["text/plain"],
"vcard": ["text/vcard"],
"vcf": ["text/vcard"],
"vob": ["video/dvd"],
"vsd": ["application/vnd.visio"],
"vsdm": ["application/vnd.ms-visio.drawing.macroEnabled.12"],
"vsdx": ["application/vnd.ms-visio.drawing"],
"vssm": ["application/vnd.ms-visio.stencil.macroEnabled.12"],
"vssx": ["application/vnd.ms-visio.stencil"],
"vstm": ["application/vnd.ms-visio.template.macroEnabled.12"],
"vstx": ["application/vnd.ms-visio.template"],
"wav": ["audio/wav"],
"webm": ["video/webm"],
"webp": ["image/webp"],
"woff": ["application/font-woff"],
"wpd": ["application/vnd.wordperfect"],
"wmv": ["video/x-ms-wmv"],
"xcf": ["application/x-gimp"],
"xla": ["application/vnd.ms-excel"],
"xlam": ["application/vnd.ms-excel.addin.macroEnabled.12"],
"xls": ["application/vnd.ms-excel"],
"xlsb": ["application/vnd.ms-excel.sheet.binary.macroEnabled.12"],
"xlsm": ["application/vnd.ms-excel.sheet.macroEnabled.12"],
"xlsx": ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"],
"xlt": ["application/vnd.ms-excel"],
"xltm": ["application/vnd.ms-excel.template.macroEnabled.12"],
"xltx": ["application/vnd.openxmlformats-officedocument.spreadsheetml.template"],
"xmind": ["application/vnd.xmind.workbook"],
"xml": ["application/xml", "text/plain"],
"xrf": ["image/x-dcraw"],
"yaml": ["application/yaml", "text/plain"],
"yml": ["application/yaml", "text/plain"],
"zip": ["application/zip"],
"url": ["application/internet-shortcut"],
"webloc": ["application/internet-shortcut"]
}
4.2.4 Création des dossiers pour les volumes permanents¶
sudo mkdir /data/nextcloud/{data,config,apps,mysql} -p
sudo chown -R www-data:root /data/nextcloud
sudo chown -R 999:root /data/nextcloud/mysql
4.3 Fichiers de configuration pour Redis¶
4.3.1 redis.conf¶
redis.conf
requirepass aeazddokpokqsd7676
4.3.2 redis.config.php¶
redis.config.php
<?php
if (getenv('REDIS_HOST')) {
$CONFIG = array (
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => getenv('REDIS_HOST'),
'password' => getenv('REDIS_HOST_PASSWORD'),
),
);
if (getenv('REDIS_HOST_PORT') !== false) {
$CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT');
} elseif (getenv('REDIS_HOST')[0] != '/') {
$CONFIG['redis']['port'] = 6379;
}
}
4.4 Fichiers de configuration pour etherpad¶
4.4.1 Dockerfile¶
Nous allons compiler une image d'etherpad en suivant les instructions de Dockerfile:
Dockerfile
# Etherpad Lite Dockerfile
#
# https://github.com/ether/etherpad-lite
#
# Author: muxator
FROM node:10-buster-slim
LABEL maintainer="Etherpad team, https://github.com/ether/etherpad-lite"
# plugins to install while building the container. By default no plugins are
# installed.
# If given a value, it has to be a space-separated, quoted list of plugin names.
#
# EXAMPLE:
# ETHERPAD_PLUGINS="ep_codepad ep_author_neat"
ARG ETHERPAD_PLUGINS=
# By default, Etherpad container is built and run in "production" mode. This is
# leaner (development dependencies are not installed) and runs faster (among
# other things, assets are minified & compressed).
ENV NODE_ENV=production
# Follow the principle of least privilege: run as unprivileged user.
#
# Running as non-root enables running this image in platforms like OpenShift
# that do not allow images running as root.
RUN useradd --uid 5001 --create-home etherpad
RUN mkdir /opt/etherpad-lite && chown etherpad:0 /opt/etherpad-lite
USER etherpad
WORKDIR /opt/etherpad-lite
COPY --chown=etherpad:0 ./ ./
# install node dependencies for Etherpad
RUN bin/installDeps.sh && \
rm -rf ~/.npm/_cacache
# Install the plugins, if ETHERPAD_PLUGINS is not empty.
#
# Bash trick: in the for loop ${ETHERPAD_PLUGINS} is NOT quoted, in order to be
# able to split at spaces.
RUN for PLUGIN_NAME in ${ETHERPAD_PLUGINS}; do npm install "${PLUGIN_NAME}"; done
# Copy the configuration file.
COPY --chown=etherpad:0 ./settings.json.docker /opt/etherpad-lite/settings.json
# Fix permissions for root group
RUN chmod -R g=u .
EXPOSE 9001
CMD ["node", "node_modules/ep_etherpad-lite/node/server.js"]
4.5 Copie du projet etherpad sur github¶
git clone https://github.com/ether/etherpad-lite.git
4.6 Création du fichier de configuration docker-compose.yml:¶
Ce fichier de configuration va déployer une image docker de nextcloud avec collabora et etherpad, avec la base de données mariadb, redis et coturn.
docker-compose.yml
services:
nextcloud:
image: nextcloud:19
depends_on:
- databasenext
- redisnext
extra_hosts:
- nextcloud.mondomaine.fr:$IP_DU_SERVEUR
- collabora.mondomaine.fr:$IP_DU_SERVEUR
- pad.mondomaine.fr:$IP_DU_SERVEUR
environment:
- NEXTCLOUD_DATA_DIR=/data
- VIRTUAL_HOST=nexctloud.mondomaine.fr
- VIRTUAL_NETWORK=proxy-ssl
- VIRTUAL_PORT=80
- MYSQL_DATABASE=dbnext
- MYSQL_USER=nextclouduser
- MYSQL_PASSWORD=azdqsdokpokpokds098098
- MYSQL_HOST=databasenext
- REDIS_HOST=redisnext
- REDIS_HOST_PASSWORD=aeazddokpokqsd7676
ports:
- "127.0.0.1:8889:80"
volumes:
- ncdata-data:/data
- ncdata-config:/var/www/html/config
- ncdata-apps:/var/www/html/custom_apps
# - ./Internal.php:/var/www/html/lib/private/Session/Internal.php
networks:
- default
- back
databasenext:
image: mariadb
restart: always
environment:
- MYSQL_ROOT_PASSWORD=DZAJpokpdzaDOPA56667
- MYSQL_USER=nextclouduser
- MYSQL_DATABASE=dbnext
- MYSQL_PASSWORD=azdqsdokpokpokds098098
#- MYSQL_INITDB_SKIP_TZINFO=1
volumes:
- ncdata-mysql:/var/lib/mysql
networks:
- back
redisnext:
image: redis
networks:
- back
volumes:
- ./redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf
coturn:
image: instrumentisto/coturn
container_name: nextcloud-coturn
restart: unless-stopped
ports:
- "3478:3478/tcp"
- "3478:3478/udp"
networks:
- back
command:
- -n
- --log-file=stdout
- --min-port=49160
- --max-port=49200
- --realm=nextcloud.mondomaine.fr
- --use-auth-secret
- --static-auth-secret=mysecreteasy
- --cert=/etc/letsencrypt/live/nextcloud.mondomaine.fr/fullchain.pem
- --pkey=/etc/letsencrypt/live/nextcloud.mondomaine.fr/privkey.pem
collabora:
image: collabora/code
container_name: nextcloud-collabora
restart: unless-stopped
extra_hosts:
- nextcloud.mondomaine.fr:217.70.188.81
- collabora.mondomaine.fr:217.70.188.81
networks:
- back
ports:
- 127.0.0.1:9980:9980
environment:
- domain=nextcloud.mondomaine.fr
- dictionaries=fr,en
cap_add:
- MKNOD
tty: true
paddb:
restart: always
image: "postgres:10"
environment:
- POSTGRES_DB=etherpad
- POSTGRES_USER=etherpad
- POSTGRES_PASSWORD=changeme
networks:
- app
etherpad:
build:
context: ./etherpad-lite
ports:
- 9001:9001
networks:
- app
networks:
back:
app:
volumes:
ncdata-mysql:
driver_opts:
type: none
device: /data/nextcloud/mysql
o: bind
ncdata-data:
driver_opts:
type: none
device: /data/nextcloud/data
o: bind
ncdata-config:
driver_opts:
type: none
device: /data/nextcloud/config
o: bind
ncdata-apps:
driver_opts:
type: none
device: /data/nextcloud/apps
o: bind
Il ne reste plus qu'à démarrer les conteneurs:
docker-compose up --build -d
5. Installation de SSL pour Nginx avec Let's Encrypt¶
Let's encrypt est un service qui permet de générer gratuitement un certificat SSL pour le domaine de notre choix.
sudo apt install python3-acme python3-certbot python3-mock python3-openssl python3-pkg-resources python3-pyparsing python3-zope.interface
sudo apt install python3-certbot-nginx
sudo certbot certonly -d nextcloud.mondomaine.fr
sudo certbot certonly -d collabora.mondomaine.fr
sudo certbot certonly -d pad.mondomaine.fr
Les certificats sont alors crés dans /etc/letsencrypt/nextcloud.mondomaine.fr
!
6. Configuration du **Server Bloc Nginx ** pour nextcloud.mondomaine.fr¶
On peut maintenant créer le fichier de configuration nginx dans /etc/nginx/sites-available/nextcloud.mondomaine.fr.conf:
nextcloud.mondomaine.fr.conf
upstream nextcloud{
server 127.0.0.1:8889;
}
server {
if ($host = nextcloud.mondomaine.fr) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name nextcloud.mondomaine.fr;
location /.well-known {
alias /var/www/nextcloud.mondomaine.fr/.well-known;
}
location / {
rewrite ^/(.*)$ https://$host/$1 permanent;
}
}
server {
listen 443 ssl;
server_name nextcloud.mondomaine.fr;
proxy_read_timeout 720s;
proxy_connect_timeout 720s;
proxy_send_timeout 720s;
proxy_set_header X-Forwarded-Host $host;
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 Host $host;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Upload limit and security
client_max_body_size 10000m;
server_tokens off;
# SSL parameters
ssl on;
ssl_certificate /etc/letsencrypt/live/nextcloud.mondomaine.fr/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/nextcloud.mondomaine.fr/privkey.pem; # managed by Certbot
ssl_session_timeout 30m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
# ssl_prefer_server_ciphers on;
# log
access_log /var/log/nginx/nextcloud.access.log;
error_log /var/log/nginx/nextcloud.error.log;
# Redirect requests to nextcloud backend server
location / {
proxy_redirect off;
proxy_pass http://nextcloud;
}
rewrite ^/.well-known/webfinger /public.php?service=webfinger last;
location /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
location /.well-known/acme-challenge {
alias /var/www/nextcloud.mondomaine.fr/.well-known/acme-challenge;
}
# location ^/(.*\.php(/.*)?$ {
# proxy_pass fcgi://127.0.0.1:6379/var/www/html/$1;
# }
# common gzip
gzip_types text/css text/less text/plain text/xml application/xml application/json application/javascript;
gzip on;
}
Pour activer ce fichier de configuration, on créé un lien symbolique vers le dossier sites-enabled:
sudo ln -s /etc/nginx/sites-available/wordpress.mondomaine.fr.conf /etc/nginx/sites-enabled/
7. Configuration du Server Bloc Nginx pour pad.mondomaine.fr¶
On peut maintenant créer le fichier de configuration nginx dans /etc/nginx/sites-available/pad.mondomaine.fr.conf:
pad.mondomaine.fr.conf
upstream pad {
server 127.0.0.1:9001;
}
server {
server_name pad.mondomaine.fr
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/pad.mondomaine.fr/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/pad.mondomaine.fr/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
proxy_pass http://pad;
proxy_redirect off;
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 https;
}
}
server {
if ($host = pad.mondomaine.fr) {
return 301 https://$host$request_uri;
} # managed by Certbot
location / {
rewrite ^/(.*)$ https://$host/$1 permanent;
}
listen 80;
listen [::]:80;
server_name pad.mondomaine.fr;
return 404; # managed by Certbot
}
Pour activer ce fichier de configuration, on créé un lien symbolique vers le dossier sites-enabled:
sudo ln -s /etc/nginx/sites-available/pad.mondomaine.fr.conf /etc/nginx/sites-enabled/
8. Configuration du Server Bloc Nginx pour collabora.mondomaine.fr¶
On peut maintenant créer le fichier de configuration nginx dans /etc/nginx/sites-available/collabora.mondomaine.fr.conf:
collabora.mondomaine.fr.conf
upstream collabora{
server 127.0.0.1:9980;
}
server {
listen 443 ssl;
server_name collabora.mondomaine.fr;
ssl on;
ssl_certificate /etc/letsencrypt/live/collabora.mondomaine.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/collabora.mondomaine.fr/privkey.pem;
# static files
location ^~ /loleaflet {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# WOPI discovery URL
location ^~ /hosting/discovery {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# Capabilities
location ^~ /hosting/capabilities {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# main websocket
location ~ ^/lool/(.*)/ws$ {
proxy_pass https://localhost:9980;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_read_timeout 36000s;
}
# download, presentation and image upload
location ~ ^/lool {
proxy_pass https://localhost:9980;
proxy_set_header Host $http_host;
}
# Admin Console websocket
location ^~ /lool/adminws {
proxy_pass https://localhost:9980;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $http_host;
proxy_read_timeout 36000s;
}
}
Pour activer ce fichier de configuration, on créé un lien symbolique vers le dossier sites-enabled:
sudo ln -s /etc/nginx/sites-available/collabora.mondomaine.fr.conf /etc/nginx/sites-enabled/
On recharge la configuration de Nginx:
sudo systemctl reload nginx.service
Et voilà, votre site est accessible à https://nextcloud.mondomaine.fr
!
Plus d'infos sur la configuration de Nginx
Plus d'infos sur le guide Nginx de Linode
9. Configuration des applications dans Nextcloud¶
9.1 Configuration de etherpad¶
Il est nécessaire de récupérer la API KEY générée par etherpad: docker-compose exec pad bash cat APIKEY.txt
On la saisit ensuite dans Nextcloud: Settings > Administration > Additional settings
10. Mise à jour Nextcloud (Docker)¶
10.1 Vérifier la version en production¶
Avant chaque update checker dans les paramètres de base si des indices de table bdd manques ou autre. (voir: 6. Indices de table manquants)
10.2 étapes¶
10.2.1 stopper la stack¶
docker-compose down
10.2.2 modifier l'image docker de Nextcloud¶
nano docker-compose.yml
Modifier la version d'image vers la version immédiatement supérieure dans le docker-compose.yml
20 -> 21, 21 -> 22
10.2.3 Relancer la stack¶
docker compose up -d
10.2.4 Mettre le container nextcloud web en mode maintenance¶
Mettre Nextcloud en mode maintenance:
docker exec -u www-data <nextcloud-container> php occ maintenance:mode --on
Lancer l'update:
docker exec -u www-data <nextcloud-container> php occ upgrade
Désactiver le mode maintenance:
docker exec -u www-data <nextcloud-container> php occ maintenance:mode --off
10.2.5 Vérifier les logs¶
Après une mise à jour, vérifier les logs docker pour d'éventuelles erreurs sur des champs de base de donnée ou indices manquants:
docker logs <nextcloud-database-container>
10.2.6 Indices de table manquants¶
Ajouter les indices de table manquants
docker exec --user www-data -it <nextcloud-database-container> /var/www/html/occ db:add-missing-indices
Modifier le type de champs d'un indice d'une table" (optionnel)
Se connecter dans le conteneur:
docker exec -it <nextcloud-database-container> bash
se connecter en tant que user nextcloud:
mariadb -u <nextcloud-user> -p
# saisir le password du user nextcloud
10.2.7 cron job¶
crontab -e
crontab
*/5 * * * * docker exec -u www-data <NOM_DU_CONTAINER> php -f cron.php
10.2.8 Commande générique pour ajouter des colonnes manquantes à certaines tables de la BDD¶
docker exec --user www-data -it <NOM_DU_CONTAINER> /var/www/html/occ <COMMANDE-DB>
Crontab (pour nettoyer Nextcloud régulierement)
crontab -e
*/5 * * * * docker exec -u www-data <NOM_DU_CONTAINER> php -f cron.php