yannstatic/static/2023/09/02/Nginx-PHP-MariaDB-Nextcloud_Hub.html

3415 lines
287 KiB
HTML
Raw Permalink Normal View History

2024-10-31 20:18:37 +01:00
<!DOCTYPE html><html lang="fr">
<head><meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"><title>Nginx PHP MariaDB Nextcloud Hub - YannStatic</title>
<meta name="description" content="Nextcloud est une suite de logiciels client-serveur permettant de créer et dutiliser des services dhébergement de fichiers.">
<link rel="canonical" href="https://static.rnmkcy.eu/2023/09/02/Nginx-PHP-MariaDB-Nextcloud_Hub.html"><link rel="alternate" type="application/rss+xml" title="YannStatic" href="/feed.xml">
<!-- - include head/favicon.html - -->
<link rel="shortcut icon" type="image/png" href="/assets/favicon/favicon.png"><link rel="stylesheet" href="/assets/css/main.css"><link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.13/css/all.css" ><!-- start custom head snippets --><link rel="stylesheet" href="/assets/css/expand.css">
<!-- end custom head snippets --><script>(function() {
window.isArray = function(val) {
return Object.prototype.toString.call(val) === '[object Array]';
};
window.isString = function(val) {
return typeof val === 'string';
};
window.hasEvent = function(event) {
return 'on'.concat(event) in window.document;
};
window.isOverallScroller = function(node) {
return node === document.documentElement || node === document.body || node === window;
};
window.isFormElement = function(node) {
var tagName = node.tagName;
return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
};
window.pageLoad = (function () {
var loaded = false, cbs = [];
window.addEventListener('load', function () {
var i;
loaded = true;
if (cbs.length > 0) {
for (i = 0; i < cbs.length; i++) {
cbs[i]();
}
}
});
return {
then: function(cb) {
cb && (loaded ? cb() : (cbs.push(cb)));
}
};
})();
})();
(function() {
window.throttle = function(func, wait) {
var args, result, thisArg, timeoutId, lastCalled = 0;
function trailingCall() {
lastCalled = new Date;
timeoutId = null;
result = func.apply(thisArg, args);
}
return function() {
var now = new Date,
remaining = wait - (now - lastCalled);
args = arguments;
thisArg = this;
if (remaining <= 0) {
clearTimeout(timeoutId);
timeoutId = null;
lastCalled = now;
result = func.apply(thisArg, args);
} else if (!timeoutId) {
timeoutId = setTimeout(trailingCall, remaining);
}
return result;
};
};
})();
(function() {
var Set = (function() {
var add = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (data[i] === item) {
return;
}
}
this.size ++;
data.push(item);
return data;
};
var Set = function(data) {
this.size = 0;
this._data = [];
var i;
if (data.length > 0) {
for (i = 0; i < data.length; i++) {
add.call(this, data[i]);
}
}
};
Set.prototype.add = add;
Set.prototype.get = function(index) { return this._data[index]; };
Set.prototype.has = function(item) {
var i, data = this._data;
for (i = 0; i < data.length; i++) {
if (this.get(i) === item) {
return true;
}
}
return false;
};
Set.prototype.is = function(map) {
if (map._data.length !== this._data.length) { return false; }
var i, j, flag, tData = this._data, mData = map._data;
for (i = 0; i < tData.length; i++) {
for (flag = false, j = 0; j < mData.length; j++) {
if (tData[i] === mData[j]) {
flag = true;
break;
}
}
if (!flag) { return false; }
}
return true;
};
Set.prototype.values = function() {
return this._data;
};
return Set;
})();
window.Lazyload = (function(doc) {
var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
var createNode = function(name, attrs) {
var node = doc.createElement(name), attr;
for (attr in attrs) {
if (attrs.hasOwnProperty(attr)) {
node.setAttribute(attr, attrs[attr]);
}
}
return node;
};
var end = function(type, url) {
var s, q, qi, cbs, i, j, cur, val, flag;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
s[url] = true;
for (i = 0; i < q.length; i++) {
cur = q[i];
if (cur.urls.has(url)) {
qi = cur, val = qi.urls.values();
qi && (cbs = qi.callbacks);
for (flag = true, j = 0; j < val.length; j++) {
cur = val[j];
if (!s[cur]) {
flag = false;
}
}
if (flag && cbs && cbs.length > 0) {
for (j = 0; j < cbs.length; j++) {
cbs[j].call(context);
}
qi.load = true;
}
}
}
}
};
var load = function(type, urls, callback) {
var s, q, qi, node, i, cur,
_urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
if (type === 'js' || type ==='css') {
s = sources[type], q = queue[type];
for (i = 0; i < q.length; i++) {
cur = q[i];
if (_urls.is(cur.urls)) {
qi = cur;
break;
}
}
val = _urls.values();
if (qi) {
callback && (qi.load || qi.callbacks.push(callback));
callback && (qi.load && callback());
} else {
q.push({
urls: _urls,
callbacks: callback ? [callback] : [],
load: false
});
for (i = 0; i < val.length; i++) {
node = null, url = val[i];
if (s[url] === undefined) {
(type === 'js' ) && (node = createNode('script', { src: url }));
(type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
if (node) {
node.onload = (function(type, url) {
return function() {
end(type, url);
};
})(type, url);
(doc.head || doc.body).appendChild(node);
s[url] = false;
}
}
}
}
}
};
return {
js: function(url, callback) {
load('js', url, callback);
},
css: function(url, callback) {
load('css', url, callback);
}
};
})(this.document);
})();
</script><script>
(function() {
var TEXT_VARIABLES = {
version: '2.2.6',
sources: {
font_awesome: 'https://use.fontawesome.com/releases/v5.0.13/css/all.css',
jquery: '/assets/js/jquery.min.js',
leancloud_js_sdk: '//cdn.jsdelivr.net/npm/leancloud-storage@3.13.2/dist/av-min.js',
chart: 'https://cdn.bootcss.com/Chart.js/2.7.2/Chart.bundle.min.js',
gitalk: {
js: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.js',
css: 'https://cdn.bootcss.com/gitalk/1.2.2/gitalk.min.css'
},
valine: 'https://unpkg.com/valine/dist/Valine.min.js'
},
site: {
toc: {
selectors: 'h1,h2,h3'
}
},
paths: {
search_js: '/assets/search.js'
}
};
window.TEXT_VARIABLES = TEXT_VARIABLES;
})();
</script>
</head>
<body>
<div class="root" data-is-touch="false">
<div class="layout--page js-page-root"><!----><div class="page__main js-page-main page__viewport hide-footer has-aside has-aside cell cell--auto">
<div class="page__main-inner"><div class="page__header d-print-none"><header class="header"><div class="main">
<div class="header__title">
<div class="header__brand"><svg id="svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="400" height="478.9473684210526" viewBox="0, 0, 400,478.9473684210526"><g id="svgg"><path id="path0" d="M308.400 56.805 C 306.970 56.966,303.280 57.385,300.200 57.738 C 290.906 58.803,278.299 59.676,269.200 59.887 L 260.600 60.085 259.400 61.171 C 258.010 62.428,256.198 63.600,255.645 63.600 C 255.070 63.600,252.887 65.897,252.598 66.806 C 252.460 67.243,252.206 67.600,252.034 67.600 C 251.397 67.600,247.206 71.509,247.202 72.107 C 247.201 72.275,246.390 73.190,245.400 74.138 C 243.961 75.517,243.598 76.137,243.592 77.231 C 243.579 79.293,241.785 83.966,240.470 85.364 C 239.176 86.740,238.522 88.365,237.991 91.521 C 237.631 93.665,236.114 97.200,235.554 97.200 C 234.938 97.200,232.737 102.354,232.450 104.472 C 232.158 106.625,230.879 109.226,229.535 110.400 C 228.933 110.926,228.171 113.162,226.434 119.500 C 226.178 120.435,225.795 121.200,225.584 121.200 C 225.373 121.200,225.200 121.476,225.200 121.813 C 225.200 122.149,224.885 122.541,224.500 122.683 C 223.606 123.013,223.214 123.593,223.204 124.600 C 223.183 126.555,220.763 132.911,219.410 134.562 C 218.443 135.742,217.876 136.956,217.599 138.440 C 217.041 141.424,215.177 146.434,214.532 146.681 C 214.240 146.794,214.000 147.055,214.000 147.261 C 214.000 147.467,213.550 148.086,213.000 148.636 C 212.450 149.186,212.000 149.893,212.000 150.208 C 212.000 151.386,208.441 154.450,207.597 153.998 C 206.319 153.315,204.913 150.379,204.633 147.811 C 204.365 145.357,202.848 142.147,201.759 141.729 C 200.967 141.425,199.200 137.451,199.200 135.974 C 199.200 134.629,198.435 133.224,196.660 131.311 C 195.363 129.913,194.572 128.123,193.870 125.000 C 193.623 123.900,193.236 122.793,193.010 122.540 C 190.863 120.133,190.147 118.880,188.978 115.481 C 188.100 112.928,187.151 111.003,186.254 109.955 C 185.358 108.908,184.518 107.204,183.847 105.073 C 183.280 103.273,182.497 101.329,182.108 100.753 C 181.719 100.177,180.904 98.997,180.298 98.131 C 179.693 97.265,178.939 95.576,178.624 94.378 C 178.041 92.159,177.125 90.326,175.023 87.168 C 174.375 86.196,173.619 84.539,173.342 83.486 C 172.800 81.429,171.529 79.567,170.131 78.785 C 169.654 78.517,168.697 77.511,168.006 76.549 C 167.316 75.587,166.594 74.800,166.402 74.800 C 166.210 74.800,164.869 73.633,163.421 72.206 C 160.103 68.936,161.107 69.109,146.550 69.301 C 133.437 69.474,128.581 70.162,126.618 72.124 C 126.248 72.495,125.462 72.904,124.872 73.033 C 124.282 73.163,123.088 73.536,122.219 73.863 C 121.349 74.191,119.028 74.638,117.061 74.858 C 113.514 75.254,109.970 76.350,108.782 77.419 C 107.652 78.436,100.146 80.400,97.388 80.400 C 95.775 80.400,93.167 81.360,91.200 82.679 C 90.430 83.195,89.113 83.804,88.274 84.031 C 85.875 84.681,78.799 90.910,74.400 96.243 L 73.400 97.456 73.455 106.028 C 73.526 117.055,74.527 121.238,77.820 124.263 C 78.919 125.273,80.400 127.902,80.400 128.842 C 80.400 129.202,81.075 130.256,81.900 131.186 C 83.563 133.059,85.497 136.346,86.039 138.216 C 86.233 138.886,87.203 140.207,88.196 141.153 C 89.188 142.098,90.000 143.104,90.000 143.388 C 90.000 144.337,92.129 148.594,92.869 149.123 C 93.271 149.410,93.600 149.831,93.600 150.059 C 93.600 150.286,93.932 150.771,94.337 151.136 C 94.743 151.501,95.598 153.004,96.237 154.475 C 96.877 155.947,97.760 157.351,98.200 157.596 C 98.640 157.841,99.900 159.943,101.000 162.267 C 102.207 164.817,103.327 166.644,103.825 166.876 C 104.278 167.087,105.065 168.101,105.573 169.130 C 107.658 173.348,108.097 174.093,110.006 176.647 C 111.103 178.114,112.000 179.725,112.000 180.227 C 112.000 181.048,113.425 183.163,114.678 184.200 C 115.295 184.711,117.396 188.733,117.720 190.022 C 117.855 190.562,118.603 191.633,119.381 192.402 C 120.160 193.171,121.496 195.258,122.351 197.039 C 123.206 198.820,124.167 200.378,124.487 200.501 C 124.807 200.624,125.953 202.496,127.034 204.662 C 128.114 206.828,129.676 209.299,130.505 210.153 C 131.333 211.007,132.124 212.177,132.262 212.753 C 132.618 214.239,134.291 217.048,136.288 219.5
" href="/">YannStatic</a></div><!--<button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button>--><!-- <li><button class="button button--secondary button--circle search-button js-search-toggle"><i class="fas fa-search"></i></button></li> -->
<!-- Champ de recherche -->
<div id="searchbox" class="search search--dark" style="visibility: visible">
<div class="main">
<div class="search__header"></div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<!-- <div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div> -->
</div>
</div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
//searchResultTemplate: '<li><a href="https://static.rnmkcy.eu{url}">{date}&nbsp;{title}</a></li>'
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a></li>'
})
</script>
<!-- Fin déclaration champ de recherche --></div><nav class="navigation">
<ul><li class="navigation__item"><a href="/archive.html">Etiquettes</a></li><li class="navigation__item"><a href="/htmldoc.html">Documents</a></li><li class="navigation__item"><a href="/liens_ttrss.html">Liens</a></li><li class="navigation__item"><a href="/aide-jekyll-text-theme.html">Aide</a></li></ul>
</nav></div>
</header>
</div><div class="page__content"><div class ="main"><div class="grid grid--reverse">
<div class="col-main cell cell--auto"><!-- start custom main top snippet --><div id="results-container" class="search-result js-search-result"></div><!-- end custom main top snippet -->
<article itemscope itemtype="http://schema.org/Article"><div class="article__header"><header><h1 style="color:Tomato;">Nginx PHP MariaDB Nextcloud Hub</h1></header></div><meta itemprop="headline" content="Nginx PHP MariaDB Nextcloud Hub"><div class="article__info clearfix"><ul class="left-col menu"><li>
2024-11-08 14:10:33 +01:00
<a class="button button--secondary button--pill button--sm" style="color:#00FFFF" href="/archive.html?tag=nextcloud">nextcloud</a>
2024-10-31 20:18:37 +01:00
</li></ul><ul class="right-col menu"><li>
<i class="far fa-calendar-alt"></i>&nbsp;<span title="Création" style="color:#FF00FF">&nbsp;2&nbsp;sept.&nbsp;2023</span>
2024-11-21 17:20:33 +01:00
<span title="Modification" style="color:#00FF7F">16&nbsp;nov.&nbsp;&nbsp;2024</span></li></ul></div><meta itemprop="datePublished" content="2024-11-16T00:00:00+01:00">
2024-10-31 20:18:37 +01:00
<meta itemprop="keywords" content="nextcloud"><div class="js-article-content">
<div class="layout--article"><!-- start custom article top snippet -->
<style>
#myBtn {
display: none;
position: fixed;
bottom: 10px;
right: 10px;
z-index: 99;
font-size: 12px;
font-weight: bold;
border: none;
outline: none;
background-color: white;
color: black;
cursor: pointer;
padding: 5px;
border-radius: 4px;
}
#myBtn:hover {
background-color: #555;
}
</style>
<button onclick="topFunction()" id="myBtn" title="Haut de page">&#8679;</button>
<script>
//Get the button
var mybutton = document.getElementById("myBtn");
// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};
function scrollFunction() {
if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
mybutton.style.display = "block";
} else {
mybutton.style.display = "none";
}
}
// When the user clicks on the button, scroll to the top of the document
function topFunction() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
}
</script>
<!-- end custom article top snippet -->
<div class="article__content" itemprop="articleBody"><details>
<summary><b>Afficher/cacher Sommaire</b></summary>
<!-- affichage sommaire -->
<div class="toc-aside js-toc-root"></div>
</details><p><em>Nextcloud est une suite de logiciels client-serveur permettant de créer et dutiliser des services dhébergement de fichiers.</em><br />
<img src="/images/nextcloud-logo.png" alt="" height="150" /></p>
<p>Le nouveau design introduit avec les versions Nextcloud Hub repose sur 4 principes :</p>
<ol>
<li>laccent sur le contenu</li>
<li>la facilité dutilisation</li>
<li>une plus grande accessibilité</li>
<li>possibilité de sapproprier le design.</li>
</ol>
<h1 id="nginx-php-mariadb-et-domaine">Nginx Php MariaDb et Domaine</h1>
<p><img src="/images/nginx-logo-a.png" alt="" height="60" /> <img src="/images/php8-logo.png" alt="" height="60" /> <img src="/images/mariadb-logo-a.png" alt="" height="60" /> <img src="/images/dns-logo-a.png" alt="" height="60" /></p>
<h2 id="nginx">Nginx</h2>
<p>https://techexpert.tips/fr/nginx-fr/</p>
<h3 id="paquet-nginx-extras">Paquet nginx-extras</h3>
<p>Nginx extras</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install nginx-extras
</code></pre></div></div>
<p>Si installation après compilation<br />
<a href="https://www.abyssproject.net/2022/05/archivage-de-mon-script-de-build-nginx-et-comment-repasser-sous-nginx-extras/">Archivage de mon script de build NGINX (et comment repasser sous nginx-extras)</a></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># en mode su
apt -o Dpkg::Options::="--force-confnew" install nginx-extras -y
rm /usr/local/lib/x86_64-linux-gnu/perl/5.36.0/nginx.pm
systemctl restart nginx
</code></pre></div></div>
<p>Dans le cas dune installation correcte, voici la structure</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/etc/nginx/
├── conf.d
├── fastcgi.conf
├── fastcgi_params
├── koi-utf
├── koi-win
├── mime.types
├── modules-available
├── modules-enabled
│   ├── 10-mod-http-ndk.conf -&gt; /usr/share/nginx/modules-available/mod-http-ndk.conf
│   ├── 50-mod-http-auth-pam.conf -&gt; /usr/share/nginx/modules-available/mod-http-auth-pam.conf
│   ├── 50-mod-http-cache-purge.conf -&gt; /usr/share/nginx/modules-available/mod-http-cache-purge.conf
│   ├── 50-mod-http-dav-ext.conf -&gt; /usr/share/nginx/modules-available/mod-http-dav-ext.conf
│   ├── 50-mod-http-echo.conf -&gt; /usr/share/nginx/modules-available/mod-http-echo.conf
│   ├── 50-mod-http-fancyindex.conf -&gt; /usr/share/nginx/modules-available/mod-http-fancyindex.conf
│   ├── 50-mod-http-geoip2.conf -&gt; /usr/share/nginx/modules-available/mod-http-geoip2.conf
│   ├── 50-mod-http-geoip.conf -&gt; /usr/share/nginx/modules-available/mod-http-geoip.conf
│   ├── 50-mod-http-headers-more-filter.conf -&gt; /usr/share/nginx/modules-available/mod-http-headers-more-filter.conf
│   ├── 50-mod-http-image-filter.conf -&gt; /usr/share/nginx/modules-available/mod-http-image-filter.conf
│   ├── 50-mod-http-lua.conf -&gt; /usr/share/nginx/modules-available/mod-http-lua.conf
│   ├── 50-mod-http-perl.conf -&gt; /usr/share/nginx/modules-available/mod-http-perl.conf
│   ├── 50-mod-http-subs-filter.conf -&gt; /usr/share/nginx/modules-available/mod-http-subs-filter.conf
│   ├── 50-mod-http-uploadprogress.conf -&gt; /usr/share/nginx/modules-available/mod-http-uploadprogress.conf
│   ├── 50-mod-http-upstream-fair.conf -&gt; /usr/share/nginx/modules-available/mod-http-upstream-fair.conf
│   ├── 50-mod-http-xslt-filter.conf -&gt; /usr/share/nginx/modules-available/mod-http-xslt-filter.conf
│   ├── 50-mod-mail.conf -&gt; /usr/share/nginx/modules-available/mod-mail.conf
│   ├── 50-mod-nchan.conf -&gt; /usr/share/nginx/modules-available/mod-nchan.conf
│   ├── 50-mod-stream.conf -&gt; /usr/share/nginx/modules-available/mod-stream.conf
│   ├── 70-mod-stream-geoip2.conf -&gt; /usr/share/nginx/modules-available/mod-stream-geoip2.conf
│   └── 70-mod-stream-geoip.conf -&gt; /usr/share/nginx/modules-available/mod-stream-geoip.conf
├── nginx.conf
├── proxy_params
├── scgi_params
├── sites-available
│   └── default
├── sites-enabled
│   └── default -&gt; /etc/nginx/sites-available/default
├── snippets
│   ├── fastcgi-php.conf
│   └── snakeoil.conf
├── uwsgi_params
└── win-utf
</code></pre></div></div>
<p>Supprimer la configuration active par défaut et recharger nginx</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo rm /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
</code></pre></div></div>
<p>Fichier /etc/nginx/nginx.conf</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> types_hash_max_size 2048;
variables_hash_max_size 2048;
</code></pre></div></div>
<h3 id="nginx-traitement-demande">nginx traitement demande</h3>
<h4 id="serveurs-virtuels-basés-sur-le-nom">Serveurs virtuels basés sur le nom</h4>
<p>nginx décide dabord quel serveur doit traiter la requête. Commençons par une configuration simple où les trois serveurs virtuels écoutent sur le port *:80 :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80;
server_name example.org www.example.org;
...
}
server {
listen 80;
server_name example.net www.example.net;
...
}
server {
listen 80;
server_name example.com www.example.com;
...
}
</code></pre></div></div>
<p>Dans cette configuration, nginx teste uniquement le champ den-tête « Host » de la requête pour déterminer vers quel serveur la requête doit être acheminée.<br />
Si sa valeur ne correspond à aucun nom de serveur ou si la requête ne contient pas du tout ce champ den-tête, alors nginx acheminera la requête vers le serveur par défaut pour ce port.<br />
Dans la configuration ci-dessus, le serveur par défaut est le premier, ce qui correspond au comportement par défaut standard de nginx. Il peut également être défini explicitement quel serveur doit être par défaut, avec le paramètre <code class="language-plaintext highlighter-rouge">default_server</code> dans la directive découte :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80 default_server;
server_name example.net www.example.net;
...
}
</code></pre></div></div>
<blockquote>
<p>Notez que le serveur par défaut est une propriété du port découte et non du nom du serveur.</p>
</blockquote>
<h4 id="comment-empêcher-le-traitement-des-demandes-avec-des-noms-de-serveur-non-définis">Comment empêcher le traitement des demandes avec des noms de serveur non définis</h4>
<p>Si les requêtes sans le champ den-tête «Hosts» ne doivent pas être autorisées, un serveur qui supprime simplement les requêtes peut être défini :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80;
server_name "";
return 444;
}
</code></pre></div></div>
<p>Ici, le nom du serveur est défini sur une chaîne vide qui correspondra aux requêtes sans le champ den-tête « Host », et un code non standard spécial nginx 444 est renvoyé pour fermer la connexion.</p>
<p class="info">Depuis la version 0.8.48, il sagit du paramètre par défaut pour le nom du serveur, donc le server_name “” peut être omis. Dans les versions antérieures, le nom dhôte de la machine était utilisé comme nom de serveur par défaut.</p>
<p><strong>Un code détat 444</strong> indique généralement que le serveur na pas renvoyé de réponse au client et a fermé la connexion. Cela peut se produire pour plusieurs raisons, notamment</p>
<ul>
<li>Le serveur ou le réseau peut rencontrer un problème temporaire ou permanent qui lempêche de répondre à la demande du client.</li>
<li>Le client peut avoir fait une demande que le serveur nest pas en mesure de traiter ou qui enfreint les règles du serveur, ce qui amène ce dernier à mettre fin à la connexion.</li>
<li>Un pare-feu ou un logiciel de sécurité peut bloquer la demande ou la réponse, ce qui entraîne la fermeture de la connexion sans réponse.</li>
</ul>
<h4 id="serveurs-virtuels-mixtes-basés-sur-le-nom-et-basés-sur-ip">Serveurs virtuels mixtes basés sur le nom et basés sur IP</h4>
<p>Regardons une configuration plus complexe où certains serveurs virtuels écoutent sur différentes adresses :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80;
server_name example.com www.example.com;
...
}
</code></pre></div></div>
<p>Dans cette configuration, nginx teste dabord ladresse IP et le port de la requête par rapport aux directives découte des blocs serveur . Il teste ensuite le champ den-tête « Host » de la requête par rapport aux entrées server_name des blocs de serveur qui correspondent à ladresse IP et au port. Si le nom du serveur nest pas trouvé, la requête sera traitée par le serveur par défaut. Par exemple, une requête www.example.com reçue sur le port 192.168.1.1:80 sera traitée par le serveur par défaut du port 192.168.1.1:80, cest à dire par le premier serveur, puisquil ny a pas de définition www.example.com pour ce port.</p>
<p>Comme déjà indiqué, un serveur par défaut est une propriété du port découte, et différents serveurs par défaut peuvent être définis pour différents ports :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 192.168.1.1:80;
server_name example.org www.example.org;
...
}
server {
listen 192.168.1.1:80 default_server;
server_name example.net www.example.net;
...
}
server {
listen 192.168.1.2:80 default_server;
server_name example.com www.example.com;
...
}
</code></pre></div></div>
<h4 id="une-configuration-simple-de-site-php">Une configuration simple de site PHP</h4>
<p>Voyons maintenant comment nginx choisit un emplacement pour traiter une demande pour un site PHP simple et typique :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>server {
listen 80;
server_name example.org www.example.org;
root /data/www;
location / {
index index.html index.php;
}
location ~* \.(gif|jpg|png)$ {
expires 30d;
}
location ~ \.php$ {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME
$document_root$fastcgi_script_name;
include fastcgi_params;
}
}
</code></pre></div></div>
<p>nginx recherche dabord lemplacement de préfixe le plus spécifique donné par les chaînes littérales, quel que soit lordre indiqué. Dans la configuration ci-dessus, le seul emplacement du préfixe est «/ » et comme il correspond à toute demande, il sera utilisé en dernier recours. Ensuite, nginx vérifie les emplacements donnés par lexpression régulière dans lordre indiqué dans le fichier de configuration. La première expression correspondante arrête la recherche et nginx utilisera cet emplacement. Si aucune expression régulière ne correspond à une requête, nginx utilise lemplacement de préfixe le plus spécifique trouvé précédemment.</p>
<p>Notez que les emplacements de tous types testent uniquement une partie URI de la ligne de requête sans arguments. Cela est dû au fait que les arguments dans la chaîne de requête peuvent être donnés de plusieurs manières, par exemple :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/index.php?user=john&amp;page=1
/index.php?page=1&amp;user=john
</code></pre></div></div>
<p>De plus, nimporte qui peut demander nimporte quoi dans la chaîne de requête :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/index.php?page=1&amp;something+else&amp;user=john
</code></pre></div></div>
<p>Voyons maintenant comment les requêtes seraient traitées dans la configuration ci-dessus :</p>
<ul>
<li>
<table>
<tbody>
<tr>
<td>Une requête «/logo.gif » correspond /dabord à lemplacement du préfixe « », puis à lexpression régulière «.(gif</td>
<td>jpg</td>
<td>png)$ », elle est donc traitée par ce dernier emplacement. À laide de la directive «root /data/www », la demande est mappée au fichier /data/www/logo.gifet le fichier est envoyé au client.</td>
</tr>
</tbody>
</table>
</li>
<li>Une requête «/index.php » correspond également /dabord à lemplacement du préfixe « », puis à lexpression régulière «.(php)$ ». Par conséquent, elle est gérée par ce dernier emplacement et la requête est transmise à un serveur FastCGI écoutant sur localhost:9000. La directive fastcgi_param définit le paramètre FastCGI SCRIPT_FILENAMEsur «/data/www/index.php » et le serveur FastCGI exécute le fichier. La variable $document_rootest égale à la valeur de la directive racine et la variable $fastcgi_script_nameest égale à lURI de la requête, cest à dire «/index.php ».</li>
<li>Une requête «/about.html » correspond /uniquement à lemplacement du préfixe « » ; elle est donc traitée à cet emplacement. À laide de la directive «root /data/www », la demande est mappée au fichier /data/www/about.htmlet le fichier est envoyé au client.</li>
<li>Le traitement dune requête «/ » est plus complexe. Il correspond uniquement au préfixe demplacement «/ » et est donc géré par cet emplacement. Ensuite, la directive index teste lexistence de fichiers dindex en fonction de ses paramètres et de la root /data/wwwdirective « ». Si le fichier /data/www/index.htmlnexiste pas et que le fichier /data/www/index.phpexiste, alors la directive effectue une redirection interne vers «/index.php » et nginx recherche à nouveau les emplacements comme si la demande avait été envoyée par un client. Comme nous lavons vu précédemment, la requête redirigée sera finalement traitée par le serveur FastCGI.</li>
</ul>
<h2 id="php">PHP</h2>
<p>Pour installer la version de 8 de php, ajouter le dépôt sury.</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install</span> <span class="nt">-y</span> lsb-release apt-transport-https ca-certificates wget
<span class="nb">sudo </span>wget <span class="nt">-O</span> /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
<span class="nb">echo</span> <span class="s2">"deb https://packages.sury.org/php/ </span><span class="si">$(</span>lsb_release <span class="nt">-sc</span><span class="si">)</span><span class="s2"> main"</span> |sudo <span class="nb">tee</span> /etc/apt/sources.list.d/php.list
</code></pre></div></div>
<p>Mise à jour des dépôts :</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt update <span class="o">&amp;&amp;</span> <span class="nb">sudo </span>apt upgrade <span class="nt">-y</span>
</code></pre></div></div>
<h3 id="php83">PHP8.3</h3>
<p>Installation</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nt">-y</span> <span class="nb">install </span>php8.3 php8.3-fpm php8.3-sqlite3 php8.3-cli php8.3-gd php8.3-imap php8.3-mysql php8.3-soap php8.3-apcu php8.3-common php8.3-gmp php8.3-intl php8.3-opcache php8.3-xml php8.3-curl php8.3-igbinary php8.3-readline php8.3-zip php8.3-bcmath php8.3-imagick php8.3-mbstring php8.3-redis imagemagick libmagickcore-6.q16-6-extra php8.3-bz2 php8.3-smbclient
</code></pre></div></div>
2024-11-21 17:20:33 +01:00
<p><u>Le fichier php.ini CLI (Command Line Interface) est la configuration PHP qui s'applique lorsque vous exécutez des scripts PHP en ligne de commande</u>.(<a href="https://www.larevuegeek.com/articles/actualites-nextcloud-corrigier-lerreur-memcache-oc-memcache-apcu-not-available-for-local-cache-article643.html">Nextcloud : Corriger lerreur Memcache \OC\Memcache\APCu not available for local cache</a>)<br />
2024-10-31 20:18:37 +01:00
Pour assurer le fonctionnement optimal de Nextcloud, il peut être nécessaire dactiver lextension APCu dans ce fichier.(en mode su)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>echo "apc.enable_cli = 1" &gt;&gt; /etc/php/8.3/cli/php.ini
</code></pre></div></div>
<h2 id="mariadb">MariaDB</h2>
<p>Installer MariaDB :</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>mariadb-server
<span class="nb">sudo </span>mysql_secure_installation <span class="c"># Y à tout et nouveau mot de passe n</span>
</code></pre></div></div>
<p>Base nextcloud , en mode su</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">MOTPASSEDB</span><span class="o">=</span><span class="s2">"uXbPk3b2wG8llQl"</span>
mysql <span class="nt">-uroot</span> <span class="nt">-e</span> <span class="s2">"CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; </span><span class="se">\</span><span class="s2">
CREATE USER 'nextcloud'@'localhost' IDENTIFIED BY '</span><span class="nv">$MOTPASSEDB</span><span class="s2">'; </span><span class="se">\</span><span class="s2">
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'localhost' IDENTIFIED BY '</span><span class="nv">$MOTPASSEDB</span><span class="s2">'; FLUSH PRIVILEGES;"</span>
</code></pre></div></div>
<p>Pour info<br />
Effacer une base : <code class="language-plaintext highlighter-rouge">mysql -uroot -e 'DROP DATABASE nextcloud'</code><br />
Effacer un utilisateur : <code class="language-plaintext highlighter-rouge">mysql -uroot -e 'DROP USER "nextcloud"@"localhost";'</code></p>
<h2 id="sous-domaine-et-certificats">Sous-Domaine et certificats</h2>
<p><a href="/2017/08/31/Acme-Certficats-Serveurs.html">Serveur , installer et renouveler les certificats SSL Lets encrypt via Acme</a><br />
Disposer dun sous-domaine (ici cloud.rnmkcy.eu) avec des certficats SSL valides (Lets Encrypt)</p>
<h2 id="nextcloud-hub">Nextcloud Hub</h2>
<p><img src="/images/nextcloud_logo_128px.png" alt="" /><br />
<a href="https://docs.nextcloud.com/server/latest/user_manual/fr/">Manuel utilisateur Nextcloud</a></p>
<p><em>Référence: <a href="https://nextcloud.com/install/">Nextcloud Install</a></em></p>
<h3 id="dernière-version-nextcloud">Dernière version Nextcloud</h3>
<p>en mode super utilisateur</p>
<p>Lien des versions Nextcloud server <a href="https://download.nextcloud.com/server/releases/">https://download.nextcloud.com/server/releases/</a><br />
On choisit “latest” dans la version<br />
<img src="/images/nextcloud-latest.png" alt="" /></p>
<p>Installer</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># mode su</span>
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
<span class="c"># checksum et vérification</span>
<span class="c">#wget https://download.nextcloud.com/server/releases/latest.tar.bz2.sha256</span>
<span class="c">#sha256sum -c latest.tar.bz2.sha256 &lt; latest.tar.bz2 </span>
<span class="c"># Décompression, déplacement et effacement</span>
<span class="nb">tar</span> <span class="nt">-xvf</span> latest.tar.bz2
<span class="nb">mv </span>nextcloud /var/www/
<span class="nb">rm </span>latest.tar.bz2
<span class="c"># Utilisateur nextcloud et droits</span>
useradd <span class="nt">-r</span> nextcloud
<span class="nb">chown</span> <span class="nt">-R</span> nextcloud:www-data /var/www/nextcloud
<span class="nb">chmod</span> <span class="nt">-R</span> o-rwx /var/www/nextcloud
<span class="c"># Nextcloud data</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> /srv/nextcloud-data/
<span class="nb">chown</span> <span class="nt">-R</span> nextcloud:nextcloud /srv/nextcloud-data/
<span class="nb">chmod</span> <span class="nt">-R</span> o-rwx /srv/nextcloud-data/
</code></pre></div></div>
<h3 id="pool-php-fpm-nextcloud">Pool PHP-FPM Nextcloud</h3>
<p><u>Pool PHP-FPM 8.3</u> Nextcloud : <code class="language-plaintext highlighter-rouge">/etc/php/8.3/fpm/pool.d/nextcloud.conf</code><br />
en mode su</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cat</span> <span class="o">&gt;</span> /etc/php/8.3/fpm/pool.d/nextcloud.conf <span class="o">&lt;&lt;</span> <span class="no">EOF</span><span class="sh">
[nextcloud]
user = nextcloud
group = nextcloud
chdir = /var/www/nextcloud
listen = /var/run/php/php8.3-fpm-nextcloud.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 16
pm.max_requests = 500
request_terminate_timeout = 1d
pm.start_servers = 6
pm.min_spare_servers = 5
pm.max_spare_servers = 8
; Additional php.ini defines, specific to this pool of workers.
env[PATH] = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
php_admin_value[memory_limit] = 512M
php_value[upload_max_filesize] = 10G
php_value[post_max_size] = 10G
php_value[default_charset] = UTF-8
; OPcache is already activated by default
; php_value[opcache.enable]=1
; The following parameters are nevertheless recommended for Nextcloud
; see here: https://docs.nextcloud.com/server/15/admin_manual/installation/server_tuning.html#enable-php-opcache
php_value[opcache.enable_cli]=1
2024-11-21 17:20:33 +01:00
php_value[opcache.interned_strings_buffer]=256
2024-10-31 20:18:37 +01:00
php_value[opcache.max_accelerated_files]=10000
php_value[opcache.memory_consumption]=512
php_value[opcache.save_comments]=1
php_value[opcache.revalidate_freq]=60
; https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/caching_configuration.html#id1
php_value[apc.enabled]=1
php_value[apc.enable_cli]=1
</span><span class="no">EOF
</span></code></pre></div></div>
<p>Avec ldap</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>apt install php8.3-ldap
</code></pre></div></div>
<p>Relancer le service</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl restart php8.3-fpm
</code></pre></div></div>
<h3 id="nextcloud-nginx-headerssslhstsocsp">Nextcloud Nginx headers,SSL,HSTS,OCSP</h3>
<p><a href="/2022/10/22/Nginx_headers_SSL_HSTS_OCSP.html">Nginx headers,SSL,HSTS,OCSP</a></p>
<p>Versions<br />
<code class="language-plaintext highlighter-rouge">nginx -v</code> : nginx version: nginx/1.22.1<br />
<code class="language-plaintext highlighter-rouge">openssl version</code> : OpenSSL 3.0.13 30 Jan 2024 (Library: OpenSSL 3.0.13 30 Jan 2024)<br />
<a href="https://ssl-config.mozilla.org/#server=nginx&amp;version=1.24.0&amp;config=modern&amp;openssl=1.1.1n&amp;guideline=5.7">SSL Configuration Generator</a></p>
<p>Créer en conséquence le fichier le fichier <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/security.conf.inc</code> ci-dessous suivant le résultat de la requête précédente</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ssl_certificate /etc/ssl/private/rnmkcy.eu-fullchain.pem;
ssl_certificate_key /etc/ssl/private/rnmkcy.eu-key.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# modern configuration
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
# HSTS (ngx_http_headers_module is required) (63072000 seconds)
#add_header Strict-Transport-Security "max-age=63072000" always;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# verify chain of trust of OCSP response using Root CA and Intermediate certs
ssl_trusted_certificate /etc/ssl/private/rnmkcy.eu-fullchain.pem;
# replace with the IP address of your resolver
resolver 1.1.1.1 9.9.9.9 valid=300s;
resolver_timeout 5s;
</code></pre></div></div>
<p>Si vous avez installé un résolveur en local , remplacer <code class="language-plaintext highlighter-rouge">1.1.1.1 9.9.9.9</code> par <code class="language-plaintext highlighter-rouge">127.0.0.1</code><br />
Remplacer rnmkcy.eu par le nom du domaine souhaité</p>
<h3 id="nextcloud-vhost-nginx">Nextcloud Vhost nginx</h3>
2024-11-21 17:20:33 +01:00
<p>Exemple avec domaine <strong>cloud.rnmkcy.eu</strong></p>
2024-10-31 20:18:37 +01:00
2024-11-21 17:20:33 +01:00
<p>Nexcloud sur le domaine cloud.rnmkcy.eu avec certificats Lets Encrypt</p>
2024-10-31 20:18:37 +01:00
2024-11-21 17:20:33 +01:00
<p><code class="language-plaintext warning highlighter-rouge">ATTENTION !!! Remplacer rnmkcy.eu par le nom de votre domaine</code></p>
<p>Le fichier de configuration web cloud.rnmkcy.eu.conf <code class="language-plaintext highlighter-rouge">/etc/nginx/conf.d/cloud.rnmkcy.eu.conf</code></p>
2024-10-31 20:18:37 +01:00
<details>
2024-11-21 17:20:33 +01:00
<summary><b>Etendre Réduire cloud.rnmkcy.eu.conf</b></summary>
2024-10-31 20:18:37 +01:00
<figure class="highlight"><pre><code class="language-nginx" data-lang="nginx">
<span class="k">upstream</span> <span class="s">php-handler</span> <span class="p">{</span>
<span class="kn">server</span> <span class="s">unix:/var/run/php/php8.3-fpm-nextcloud.sock</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">listen</span> <span class="s">[::]:80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">cloud.rnmkcy.eu</span><span class="p">;</span>
<span class="c1"># enforce https</span>
<span class="kn">return</span> <span class="mi">301</span> <span class="s">https://</span><span class="nv">$server_name</span><span class="p">:</span><span class="mi">443</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
<span class="kn">listen</span> <span class="s">[::]:443</span> <span class="s">ssl</span> <span class="s">http2</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">cloud.rnmkcy.eu</span><span class="p">;</span>
<span class="kn">include</span> <span class="n">/etc/nginx/conf.d/security.conf.inc</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"Strict-Transport-Security</span> <span class="p">:</span> <span class="s">max-age=63072000</span><span class="p">;</span> <span class="kn">includeSubDomains</span><span class="p">;</span> <span class="kn">preload"</span><span class="p">;</span>
<span class="c1"># include snippets/authelia-location.conf; # Authelia auth endpoint</span>
<span class="kn">location</span> <span class="s">^~</span> <span class="n">/.well-known</span> <span class="p">{</span>
<span class="c1"># The following 6 rules are borrowed from `.htaccess`</span>
<span class="c1"># The following 2 rules are only needed for the user_webfinger app.</span>
<span class="c1"># Uncomment it if you're planning to use this app.</span>
<span class="c1">#rewrite ^/\.well-known/host-meta\.json /public.php?service=host-meta-json last;</span>
<span class="c1">#rewrite ^/\.well-known/host-meta /public.php?service=host-meta last;</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/.well-known/carddav</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">301</span> <span class="n">/remote.php/dav/</span><span class="p">;</span> <span class="p">}</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/.well-known/caldav</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">301</span> <span class="n">/remote.php/dav/</span><span class="p">;</span> <span class="p">}</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/.well-known/webfinger</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">301</span> <span class="n">/index.php</span><span class="nv">$uri</span><span class="p">;</span> <span class="p">}</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/.well-known/nodeinfo</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">301</span> <span class="n">/index.php</span><span class="nv">$uri</span><span class="p">;</span> <span class="p">}</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">#sub_path_only rewrite ^/$ / permanent;</span>
<span class="kn">location</span> <span class="s">^~</span> <span class="n">/</span> <span class="p">{</span>
<span class="c1"># Path to source</span>
<span class="kn">alias</span> <span class="n">/var/www/nextcloud/</span><span class="p">;</span>
<span class="c1"># Set max upload size</span>
<span class="kn">client_max_body_size</span> <span class="mi">10G</span><span class="p">;</span>
<span class="kn">fastcgi_buffers</span> <span class="mi">64</span> <span class="mi">4K</span><span class="p">;</span>
<span class="c1"># Enable gzip but do not remove ETag headers</span>
<span class="kn">gzip</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_vary</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">gzip_comp_level</span> <span class="mi">4</span><span class="p">;</span>
<span class="kn">gzip_min_length</span> <span class="mi">256</span><span class="p">;</span>
<span class="kn">gzip_proxied</span> <span class="s">expired</span> <span class="s">no-cache</span> <span class="s">no-store</span> <span class="s">private</span> <span class="s">no_last_modified</span> <span class="s">no_etag</span> <span class="s">auth</span><span class="p">;</span>
<span class="kn">gzip_types</span> <span class="nc">application/atom</span><span class="s">+xml</span> <span class="nc">application/javascript</span> <span class="nc">application/json</span> <span class="nc">application/ld</span><span class="s">+json</span> <span class="nc">application/manifest</span><span class="s">+json</span> <span class="nc">application/rss</span><span class="s">+xml</span> <span class="nc">application/vnd</span><span class="s">.geo+json</span> <span class="nc">application/vnd</span><span class="s">.ms-fontobject</span> <span class="nc">application/x-font-ttf</span> <span class="nc">application/x-web-app-manifest</span><span class="s">+json</span> <span class="nc">application/xhtml</span><span class="s">+xml</span> <span class="nc">application/xml</span> <span class="nc">font/opentype</span> <span class="nc">image/bmp</span> <span class="nc">image/svg</span><span class="s">+xml</span> <span class="nc">image/x-icon</span> <span class="nc">text/cache-manifest</span> <span class="nc">text/css</span> <span class="nc">text/plain</span> <span class="nc">text/vcard</span> <span class="nc">text/vnd</span><span class="s">.rim.location.xloc</span> <span class="nc">text/vtt</span> <span class="nc">text/x-component</span> <span class="nc">text/x-cross-domain-policy</span><span class="p">;</span>
<span class="c1"># Pagespeed is not supported by Nextcloud, so if your server is built</span>
<span class="c1"># with the `ngx_pagespeed` module, uncomment this line to disable it.</span>
<span class="c1">#pagespeed off;</span>
<span class="c1"># The settings allows you to optimize the HTTP2 bandwitdth.</span>
<span class="c1"># See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/</span>
<span class="c1"># for tunning hints</span>
<span class="kn">client_body_buffer_size</span> <span class="mi">512k</span><span class="p">;</span>
<span class="c1"># HTTP response headers borrowed from Nextcloud `.htaccess`</span>
<span class="c1">#more_set_headers "Strict-Transport-Security: max-age=15768000; includeSubDomains; preload;";</span>
<span class="kn">more_set_headers</span> <span class="s">"Referrer-Policy:</span> <span class="s">no-referrer"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-Content-Type-Options:</span> <span class="s">nosniff"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-Download-Options:</span> <span class="s">noopen"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-Frame-Options:</span> <span class="s">SAMEORIGIN"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-Permitted-Cross-Domain-Policies:</span> <span class="s">none"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-Robots-Tag:</span> <span class="s">noindex,</span> <span class="s">nofollow"</span><span class="p">;</span>
<span class="kn">more_set_headers</span> <span class="s">"X-XSS-Protection:</span> <span class="mi">1</span><span class="p">;</span> <span class="kn">mode=block"</span><span class="p">;</span>
<span class="c1"># Remove X-Powered-By, which is an information leak</span>
<span class="kn">fastcgi_hide_header</span> <span class="s">X-Powered-By</span><span class="p">;</span>
<span class="c1"># Specify how to handle directories -- specifying `/nextcloud/index.php$request_uri`</span>
<span class="c1"># here as the fallback means that Nginx always exhibits the desired behaviour</span>
<span class="c1"># when a client requests a path that corresponds to a directory that exists</span>
<span class="c1"># on the server. In particular, if that directory contains an index.php file,</span>
<span class="c1"># that file is correctly served; if it doesn't, then the request is passed to</span>
<span class="c1"># the front-end controller. This consistent behaviour means that we don't need</span>
<span class="c1"># to specify custom rules for certain paths (e.g. images and other assets,</span>
<span class="c1"># `/updater`, `/ocm-provider`, `/ocs-provider`), and thus</span>
<span class="c1"># `try_files $uri $uri/ /nextcloud/index.php$request_uri`</span>
<span class="c1"># always provides the desired behaviour.</span>
<span class="kn">index</span> <span class="s">index.php</span> <span class="s">index.html</span> <span class="n">/index.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="c1"># Rule borrowed from `.htaccess` to handle Microsoft DAV clients</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">if</span> <span class="s">(</span> <span class="nv">$http_user_agent</span> <span class="p">~</span> <span class="sr">^DavClnt</span> <span class="s">)</span> <span class="p">{</span>
<span class="kn">return</span> <span class="mi">302</span> <span class="n">/remote.php/webdav/</span><span class="nv">$is_args$args</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">=</span> <span class="n">/robots.txt</span> <span class="p">{</span>
<span class="kn">allow</span> <span class="s">all</span><span class="p">;</span>
<span class="kn">log_not_found</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Rules borrowed from `.htaccess` to hide certain paths from clients</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">404</span><span class="p">;</span> <span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(?:\.|autotest|occ|issue|indie|db_|console)</span> <span class="p">{</span> <span class="kn">return</span> <span class="mi">404</span><span class="p">;</span> <span class="p">}</span>
<span class="c1"># Ensure this block, which passes PHP files to the PHP process, is above the blocks</span>
<span class="c1"># which handle static assets (as seen below). If this block is not declared first,</span>
<span class="c1"># then Nginx will encounter an infinite rewriting loop when it prepends</span>
<span class="c1"># `/nextcloud/index.php` to the URI, resulting in a HTTP 500 error response.</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php(?:$|/)</span> <span class="p">{</span>
<span class="c1"># Required for legacy support</span>
<span class="kn">rewrite</span> <span class="s">^/(?!index|remote|public|cron|core</span><span class="err">\</span><span class="n">/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy|.+\/richdocumentscode_arm64\/proxy</span><span class="s">)</span> <span class="n">/index.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="kn">fastcgi_split_path_info</span> <span class="s">^(.+?</span><span class="err">\</span><span class="s">.php)(/.*)</span>$<span class="p">;</span>
<span class="kn">set</span> <span class="nv">$path_info</span> <span class="nv">$fastcgi_path_info</span><span class="p">;</span>
<span class="kn">try_files</span> <span class="nv">$fastcgi_script_name</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="nv">$request_filename</span><span class="p">;</span>
<span class="kn">fastcgi_split_path_info</span> <span class="s">^(.+</span><span class="err">\</span><span class="s">.php)(/.+)</span>$<span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">HTTPS</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">modHeadersAvailable</span> <span class="s">true</span><span class="p">;</span> <span class="c1"># Avoid sending the security headers twice</span>
<span class="kn">fastcgi_param</span> <span class="s">front_controller_active</span> <span class="s">true</span><span class="p">;</span> <span class="c1"># Enable pretty urls</span>
<span class="kn">fastcgi_param</span> <span class="s">HTTP_ACCEPT_ENCODING</span> <span class="s">""</span><span class="p">;</span> <span class="c1"># Disable encoding of nextcloud response to inject ynh scripts</span>
<span class="kn">fastcgi_pass</span> <span class="s">php-handler</span><span class="p">;</span>
<span class="kn">fastcgi_intercept_errors</span> <span class="no">on</span><span class="p">;</span>
<span class="kn">fastcgi_request_buffering</span> <span class="no">off</span><span class="p">;</span>
<span class="kn">fastcgi_read_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">fastcgi_send_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">fastcgi_connect_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">proxy_connect_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">proxy_send_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">proxy_read_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="kn">send_timeout</span> <span class="mi">600</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">^/(?:updater|ocs-provider)(?:$|/)</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span><span class="n">/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># Serve static files</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="n">/</span> <span class="n">/index.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="kn">expires</span> <span class="mi">6M</span><span class="p">;</span> <span class="c1"># Cache-Control policy borrowed from `.htaccess`</span>
<span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span> <span class="c1"># Optional: Don't log access to assets</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.wasm$</span> <span class="p">{</span>
<span class="kn">default_type</span> <span class="nc">application/wasm</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.woff2?$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="n">/</span> <span class="n">/index.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="kn">expires</span> <span class="s">7d</span><span class="p">;</span> <span class="c1"># Cache-Control policy borrowed from `.htaccess`</span>
<span class="kn">access_log</span> <span class="no">off</span><span class="p">;</span> <span class="c1"># Optional: Don't log access to assets</span>
<span class="p">}</span>
<span class="c1"># Rule borrowed from `.htaccess`</span>
<span class="kn">location</span> <span class="n">/remote</span> <span class="p">{</span>
<span class="kn">return</span> <span class="mi">301</span> <span class="n">/remote.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">/</span> <span class="p">{</span>
<span class="kn">if</span> <span class="s">(</span><span class="nv">$request_method</span> <span class="p">~</span> <span class="sr">^(PUT|DELETE|PATCH|PROPFIND|PROPPATCH)$)</span> <span class="p">{</span>
<span class="kn">rewrite</span> <span class="s">^</span> <span class="n">/index.php</span><span class="nv">$request_uri</span> <span class="s">last</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="n">/</span> <span class="n">/index.php</span><span class="nv">$request_uri</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1"># include snippets/authelia-authrequest.conf; # Protect this endpoint</span>
<span class="p">}</span>
<span class="kn">access_log</span> <span class="n">/var/log/nginx/cloud.rnmkcy.eu-access.log</span><span class="p">;</span>
<span class="kn">error_log</span> <span class="n">/var/log/nginx/cloud.rnmkcy.eu-error.log</span><span class="p">;</span>
<span class="p">}</span></code></pre></figure>
</details>
<p>Vérifier et recharger nginx : <code class="language-plaintext highlighter-rouge">nginx -t &amp;&amp; systemctl reload nginx</code></p>
<h3 id="nextcloud-nginx-mimes">Nextcloud Nginx mimes</h3>
<p><code class="language-plaintext warning highlighter-rouge">Les sections Activité et Logging dans le cadre de ladministration affiche des pages vierges</code></p>
<p>Cest une indication que votre serveur web nest pas configuré pour gérer correctement les fichiers mjs.</p>
<p>Il faut modifier le fichier “mime.types” situé dans <code class="language-plaintext highlighter-rouge">/etc/nginx/</code>, remplaçer la ligne suivante:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>application/javascript js;
</code></pre></div></div>
<p>par</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>application/javascript js mjs;
</code></pre></div></div>
<p>Puis redémarrer Nginx et php-fpm.</p>
<h2 id="paramétrage-nextcloud">Paramétrage Nextcloud</h2>
<h3 id="finaliser-installation-nextcloud">Finaliser installation Nextcloud</h3>
<p><code class="language-plaintext warning highlighter-rouge">Tout est paramétré avec le domaine ouestyan.fr qu'il faut remplacer par votre domaine</code></p>
<p>Ouvrir le lien <a href="https://cloud.rnmkcy.eu">https://cloud.rnmkcy.eu</a><br />
Créer un compte administrateur et son mot de passe<br />
Renseigner les éléments de la base mysql<br />
<img src="/images/cloud.rnmkcy.eu02.png" alt="" width="200" /> <img src="/images/cloud.ouestyan.fr04.png" alt="" width="400" /><br />
<img src="/images/cloud.rnmkcy.eu03.png" alt="" /></p>
<p>Se déconnecter…<br />
<img src="/images/cloud.rnmkcy.eu04.png" alt="" /></p>
<p><strong>Modifier le fichier /var/www/nextcloud/config/config.php</strong><br />
Ajouter <code class="language-plaintext highlighter-rouge">'default_phone_region' =&gt; 'FR',</code> et les lignes suivantes dans le fichier <code class="language-plaintext highlighter-rouge">/var/www/nextcloud/config/config.php</code> avant le tag de fin de fichier <code class="language-plaintext highlighter-rouge">);</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 'default_locale' =&gt; 'fr_FR',
'default_phone_region' =&gt; 'FR',
'filelocking.enabled' =&gt; true,
'memcache.locking' =&gt; '\OC\Memcache\Redis',
'memcache.local' =&gt; '\\OC\\Memcache\\APCu',
'redis' =&gt; array(
'host' =&gt; 'localhost',
'port' =&gt; 6379,
'timeout' =&gt; 0.0,
'password' =&gt; '',
),
</code></pre></div></div>
<p>Messagerie pour notifications</p>
<p>Serveur de messagerie, ajouter les lignes dans le fichier <code class="language-plaintext highlighter-rouge">/var/www/nextcloud/config/config.php</code> avant le tag de fin de fichier <code class="language-plaintext highlighter-rouge">);</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 'mail_from_address' =&gt; 'yann',
'mail_smtpmode' =&gt; 'smtp',
'mail_sendmailmode' =&gt; 'smtp',
'mail_domain' =&gt; 'rnmkcy.eu',
'mail_smtphost' =&gt; 'rnmkcy.eu',
'mail_smtpport' =&gt; '587',
'mail_smtpauth' =&gt; 1,
'mail_smtpname' =&gt; 'yann@rnmkcy.eu',
'mail_smtppassword' =&gt; 'mot_passe_yann',
</code></pre></div></div>
<p><strong>Nextcloud Travaux cron</strong><br />
Vous pouvez programmer des tâches cron de trois façons : en utilisant <strong>AJAX</strong>, <strong>Webcron</strong> ou <strong>cron</strong>.<br />
La méthode recommandée est <strong>cron</strong>&lt;/u&gt;.</p>
<p class="info">Note : Il nest pas obligatoire de sélectionner loption Cron dans le menu dadministration pour les travaux en arrière-plan, car une fois que cron.php est exécuté à partir de la ligne de commande ou du service cron, il sera automatiquement réglé sur Cron.<br />
<img src="/images/cloud_xoyaz_xyz06.png" alt="" width="600" /></p>
<p><strong>Nextcloud maintenance_window_start</strong></p>
<p class="warning">Le paramètre <code class="language-plaintext highlighter-rouge">maintenance_window_start</code> nest pris en compte quen mode cron.</p>
<p>Dans le fichier config/config.php, vous pouvez spécifier cette configuration. Certaines tâches de fond ne sexécutent quune fois par jour. Lorsquune heure est définie (le fuseau horaire est UTC) pour cette configuration, les tâches darrière-plan qui sannoncent comme non sensibles au temps seront retardées pendant les heures “ouvrables” et ne sexécuteront que dans les 4 heures suivant lheure donnée. Ceci est par exemple utilisé pour lexpiration des activités, la formation aux connexions suspectes et les vérifications de mise à jour.</p>
<p class="info">Une valeur de 1, par exemple, nexécutera ces tâches darrière-plan quentre 01h00 UTC et 05h00 UTC.</p>
<p>Ajouter le paramètre au fichier <code class="language-plaintext highlighter-rouge">/var/www/nextcloud/config/config.php</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> 'maintenance_window_start' =&gt; 1,
</code></pre></div></div>
<h3 id="lldap---gestion-des-utilisateurs">LLDAP - Gestion des utilisateurs</h3>
<p><a href="/2024/03/05/Light_LDAP_simple_serveur_authentification.html#clients-lldap">Clients LLDAP</a></p>
<p>Préalable, le module php8.x-ldap doit être installé<br />
Ouvrir nextcloud avec “admin”, “Applications mises en avant” et Activer LDAP puis Télécharger et activer pour que lapplication apparaisse dans les “Applications actives”<br />
<img src="/images/cloud.rnmkcy.eu05.png" alt="" /><br />
Ensuite ouvrir “Paramètres dadministration” , “Intégration LDAP/AD”<br />
<img src="/images/cloud.rnmkcy.eu06.png" alt="" /></p>
<ol>
<li>Host: 127.0.0.1</li>
<li>Port: 3890</li>
<li>Utilisateur DN : uid=admin,ou=people,dc=rnmkcy,dc=eu</li>
<li>Mot de passe admin LLDAP</li>
<li>DN de base: dc=rnmkcy,dc=eu</li>
<li>Clic Continuer</li>
</ol>
<p>On va modifier la requête en ajoutant<br />
<code class="language-plaintext highlighter-rouge">(|(objectclass=inetOrgPerson) (memberOf=cn=nextcloud_users,ou=groups,dc=rnmkcy,dc=eu))</code><br />
<img src="/images/cloud.rnmkcy.eu07.png" alt="" /> <br />
Il saffiche “9 utilisateurs trouvés”<br />
La configuration LLDAP est terminée</p>
<p>Gestion des utilisateurs, ouvrir nextcloud avec admin , puis “Utilisateurs”<br />
Créer un groupe Utilisateurs et y affecter les comptes concernés<br />
<img src="/images/cloud.rnmkcy.eu11.png" alt="" /></p>
<p>Se déconnecter, puis se reconnecter avec le nouvel administrateur “yann” et supprimer “admin” , lutilisateur qui a servi à linstallation de nextcloud<br />
<img src="/images/cloud.rnmkcy.eu12.png" alt="" /></p>
<h2 id="applications-nextcloud">Applications Nextcloud</h2>
<h3 id="messagerie">Messagerie</h3>
<h4 id="mail">Mail</h4>
<p>Si vous avez installé un serveur mail, installer at activer lapplication <strong>mail</strong> de nextcloud<br />
<img src="/images/rnmkcy.eu-nexcloud20.png" alt="" /></p>
<h4 id="snappymail-inactif">SnappyMail (INACTIF)</h4>
<p><a href="/2024/01/12/SnappyMail.html#snappymail-nextcloud">SnappyMail Nextcloud</a></p>
<h3 id="contacts-et-calendrier">Contacts et Calendrier</h3>
<p>Télécharger et activer les applications <br />
<img src="/images/nextcloud-calcard01.png" alt="" /></p>
<p>Cliquer sur licône “Contact” <br />
<img src="/images/nextcloud-calcard02.png" alt="" width="600" /><br />
<img src="/images/nextcloud-calcard03.png" alt="" width="600" /><br />
<img src="/images/nextcloud-calcard04.png" alt="" width="600" /><br />
Pour le lien<br />
<img src="/images/nextcloud-calcard04a.png" alt="" width="600" /><br />
Lien interne utilisateur : <a href="https://cloud.rnmkcy.eu/remote.php/dav/addressbooks/users/dentifiant_hexa_utilisateur/contacts/">https://cloud.rnmkcy.eu/remote.php/dav/addressbooks/users/dentifiant_hexa_utilisateur/contacts/</a></p>
<p>Cliquer sur licône “Agenda” <br />
<img src="/images/nextcloud-calcard05.png" alt="" width="600" /><br />
<img src="/images/nextcloud-calcard06.png" alt="" width="600" /><br />
<img src="/images/nextcloud-calcard07.png" alt="" width="600" /></p>
<p>Pour les partages<br />
<img src="/images/nextcloud-calcard08.png" alt="" width="200" /><br />
Adresse caldav principal : <a href="https://cloud.rnmkcy.eu/remote.php/dav">https://cloud.rnmkcy.eu/remote.php/dav</a></p>
<p>Pour les clients android, thunderbird<br />
Cliquer sur le lien “Modifier et partager lagenda” de lutilisateur yann <br />
<img src="/images/nextcloud-calcard09.png" alt="" width="400" /><br />
Lien interne utilisateur : <a href="https://cloud.rnmkcy.eu/remote.php/dav/calendars/Identifiant_hexa_utilisateur/personal/">https://cloud.rnmkcy.eu/remote.php/dav/calendars/Identifiant_hexa_utilisateur/personal/</a></p>
<h3 id="login-mot-de-passe-application">Login mot de passe application</h3>
<p>Les applications clientes de nextcloud ne peuvent pas se connecter sur nextcloud avec une authentification à 2 facteurs, il faut créer un accès login + mot de passe<br />
Se connecter à Nextcloud puis : Personnel → Sécurité → Appareils &amp; sessions<br />
<img src="/images/nextcloud-mpappli01.png" alt="" /> <br />
Sauvegarder les 2 paramètres (utilisateur et mot de passe) pour une utilisation sur les applications clientes…</p>
<h3 id="nextcloud-music">Nextcloud Music</h3>
<p>« Music » est une application pour OwnCloud et Nextcloud qui joue à la fois le rôle de serveur de musique et celui de client Web.</p>
<p>Les principales fonctionnalités de Nextcloud Music sont :</p>
<ul>
<li>lindexation de la musique présente sur le stockage Nextcloud,</li>
<li>la navigation dans sa bibliothèque et lécoute de sa musique via une interface Web intégrée à Nextcloud,</li>
<li>et la fourniture dAPIs permettant à des applications tierces de sy connecter.</li>
</ul>
<p>« Smart playlist » est une sélection (aléatoire ?) de 100 titres que vous pouvez écouter en un clic. Contrairement aux autres playlists, la « Smart playlist » nest pas accessible en dehors de linterface Web, mais il est possible de lenregistrer vers une playlist régulière qui sera alors accessible aux applications tierces.</p>
<p>« Internet radio » et permet dajouter et découter des Web radio. Elle fonctionne bien, mais il est important de noter que si votre instance Nextcloud est accessible en HTTPS [elle devrait !], le flux de la radio devra impérativement utiliser ce protocole également. Il sagit-là dune limitation liée au navigateur, qui pour des raisons de sécurité empêche daccéder à des ressources HTTP depuis une page servie en HTTPS.</p>
<p>Et la dernière fonctionnalité permet de sabonner à des Podcast via des flux RSS.</p>
<p>Activer lapplication <strong>Music</strong><br />
<img src="/images/nextcloud-music01.png" alt="" /></p>
<p>Ouvrir lapplication “Music” et cliquer sur Settings<br />
<img src="/images/nextcloud-music02.png" alt="" /></p>
<p>Pour les applications android, un accès avec mot de passe<br />
<img src="/images/nextcloud-music03.png" alt="" /></p>
<p>Android <strong>Power Ampache 2</strong> (<a href="https://github.com/icefields/Power-Ampache-2">https://github.com/icefields/Power-Ampache-2</a>)<br />
<em>Power Ampache 2 est un client musical riche en fonctionnalités conçu pour Ampache, Nextcloud Music et les backends compatibles. Il offre toutes les fonctionnalités des autres lecteurs de musique grand public, tels que Spotify, YouTube Music et Apple Music, et bien plus encore. Avec Power Ampache 2, profitez « réellement » du téléchargement et de lexportation de fichiers musicaux, de laccès aux paroles, de la prise en charge de plusieurs comptes et dune expérience sans publicité et sans suivi.</em></p>
<ul>
<li>Listes de lecture générées uniques (smartlists)</li>
<li>“Spin it!” bouton pour générer une liste de lecture pour vous.</li>
<li>Mode sombre et clair avec couleurs dinterface adaptatives, ou choisissez/créez votre propre thème.</li>
<li>Prise en charge des touches multimédias</li>
<li>Chaque fonctionnalité Bluetooth est disponible dans lapplication.</li>
<li>Notifications de chansons avec commandes de lecture. Également sur lécran de verrouillage.</li>
<li>Collections dalbums, dartistes et de chansons</li>
<li>Recherche avancée</li>
<li>Mode hors ligne puissant</li>
<li>Créez, modifiez et partagez vos listes de lecture</li>
</ul>
<p><a href="https://f-droid.org/repo/luci.sixsixsix.powerampache2.fdroid_61.apk">Télécharger APK</a>, <a href="https://f-droid.org/repo/luci.sixsixsix.powerampache2.fdroid_61.apk.asc">Signature PGP</a></p>
<h3 id="office">Office</h3>
<h4 id="onlyoffice-inactif">OnlyOffice (INACTIF)</h4>
<p><a href="/2023/08/19/OnlyOffice_pour_YunoHost.html">OnlyOffice YunoHost, Nextcloud et Archlinux</a></p>
<h4 id="collabora-online-inactif">Collabora Online (INACTIF)</h4>
<p><a href="/2024/05/18/Collabora_Debian.html">Collabora</a></p>
<h3 id="nextcloud-webdav">Nextcloud WebDAV</h3>
<p><em>Dans le domaine des réseaux informatiques, davfs2 est un outil Linux permettant de se connecter à des partages WebDAV comme sil sagissait de disques locaux. Il sagit dun système de fichiers open-source sous licence GPL pour le montage de serveurs WebDAV. Il utilise lAPI du système de fichiers FUSE pour communiquer avec le noyau et la bibliothèque neon WebDAV pour communiquer avec le serveur web.</em></p>
<ul>
<li><a href="https://docs.nextcloud.com/server/latest/user_manual/fr/files/access_webdav.html">Accès aux fichiers Nextcloud avec WebDAV</a></li>
<li><a href="https://sleeplessbeastie.eu/2017/09/25/how-to-mount-webdav-share-using-systemd/">How to mount WebDAV share using systemd</a></li>
<li><a href="https://sleeplessbeastie.eu/2017/09/04/how-to-mount-webdav-share/">How to mount WebDAV share</a></li>
<li><a href="https://wiki.archlinux.org/title/Davfs2">davfs2 archwiki</a></li>
<li><a href="https://www.hagemann.ws/blog/linux-mount-webdav-share-using-fstab-and-davfs2.html">Linux: Mount WebDav-Share using fstab and davfs2</a></li>
</ul>
<h3 id="nextcloud-notes">Nextcloud Notes</h3>
<p><strong>Notes</strong><br />
Lapplication Notes est une application de prise de notes pour Nextcloud. Elle fournit des catégories pour une meilleure organisation et supporte le formatage en utilisant la syntaxe Markdown. Les notes sont sauvegardées comme des fichiers dans votre Nextcloud, vous pouvez donc les voir et les éditer avec nimporte quel client Nextcloud. De plus, une API REST séparée permet une intégration facile dans des applications tierces (actuellement, il existe des applications de notes pour Android, iOS et la console qui permettent un accès pratique à vos notes Nextcloud). Dautres fonctionnalités permettent de marquer des notes comme favorites.</p>
<p><strong>QOwnNotesAPI</strong></p>
<p><em>QOwnNotesAPI est lAPI Nextcloud/ownCloud pour QOwnNotes, le bloc-notes open source pour Linux, macOS et Windows, qui fonctionne avec lapplication de notes de Nextcloud/ownCloud.</em></p>
<p>Le seul but de cette application est de fournir un accès API à votre serveur Nextcloud/ownCloud pour votre installation de bureau QOwnNotes, vous ne pouvez pas utiliser cette application pour autre chose, si vous navez pas QOwnNotes installé sur votre ordinateur de bureau !</p>
<p>Archlinux QOwnNotes</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yay -S qownnotes
</code></pre></div></div>
<h2 id="mise-à-jour-nextcloud">Mise à jour Nextcloud</h2>
<p><img src="/images/nextcloud-maj01.png" alt="" width="500" /></p>
<h3 id="interface">Interface</h3>
<p>Cliquer sur <strong>Ouvrir linterface de mise à jour</strong><br />
<img src="/images/nextcloud-maj02.png" alt="" width="300" /><br />
<img src="/images/nextcloud-maj03.png" alt="" width="300" /><br />
<img src="/images/nextcloud-maj04.png" alt="" width="300" /><br />
Retour sur la page daccueil à la fin de la mise à jour</p>
<h3 id="manuellement">Manuellement</h3>
<p class="warning">Si vous effectuez une mise à niveau à partir dune version majeure précédente, veuillez dabord consulter les <a href="https://docs.nextcloud.com/server/latest/admin_manual/release_notes/index.html#critical-changes">modifications critiques (en)</a></p>
<p>Commencez toujours par effectuer une nouvelle sauvegarde et en désactivant toutes les applications tierces.</p>
<p>1 - Sauvegardez vos fichiers Nextcloud Server existants ,votre base de données, votre répertoire de données et <code class="language-plaintext highlighter-rouge">config.php</code>. (Voir <a href="https://docs.nextcloud.com/server/latest/admin_manual/maintenance/backup.html">Backup</a> , pour les informations de restauration, voir<a href="https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html"> Restoring backup</a> )</p>
<p>2 - Téléchargez et décompressez la dernière version de Nextcloud Server (fichier darchive) depuis <a href="https://download.nextcloud.com/server/releases/">https://download.nextcloud.com/server/releases/</a> dans un répertoire vide en dehors de votre installation actuelle.<br />
Pour décompresser votre nouvelle archive tar, exécutez : <code class="language-plaintext highlighter-rouge">unzip nextcloud-[version].zip</code> ou <code class="language-plaintext highlighter-rouge">tar -xjf nextcloud-[version].tar.bz2</code></p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> ~/temp
<span class="nb">cd</span> ~/temp
wget https://download.nextcloud.com/server/releases/latest-28.tar.bz2
<span class="nb">tar</span> <span class="nt">-xjf</span> latest-28.tar.bz2
</code></pre></div></div>
<p>3 - Arrêtez votre serveur Web.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl stop nginx
</code></pre></div></div>
<p>4 - Si vous exécutez une tâche cron pour la gestion interne de nextcloud, désactivez-la en commentant lentrée dans le fichier crontab.(Le proriétaire du dossier est www-data ou nextcloud (<code class="language-plaintext highlighter-rouge">ls -la /var/www</code>)</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#sudo crontab -u www-data -e</span>
<span class="nb">sudo </span>crontab <span class="nt">-u</span> nextcloud <span class="nt">-e</span>
<span class="c"># commenter</span>
<span class="c">#*/5 * * * * php -f /var/www/nextcloud/cron.php</span>
</code></pre></div></div>
<p>(Mettez un # au début de la ligne correspondante.)</p>
<p>5 - Renommez votre répertoire Nextcloud actuel, par exemple nextcloud-old.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo mv /var/www/nextcloud /var/www/nextcloud-old
</code></pre></div></div>
<p>6 - La décompression de la nouvelle archive crée un nouveau répertoire nextcloud rempli avec vos nouveaux fichiers serveur. Déplacez ce répertoire et son contenu vers lemplacement dorigine de votre ancien serveur. Par exemple <code class="language-plaintext highlighter-rouge">/var/www/</code>, pour quune fois de plus vous ayez <code class="language-plaintext highlighter-rouge">/var/www/nextcloud</code></p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo mv</span> ~/temp/nextcloud /var/www/
</code></pre></div></div>
<p>7 - Copiez le config/config.phpfichier de votre ancien répertoire Nextcloud vers votre nouveau répertoire Nextcloud.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo cp /var/www/nextcloud-old/config/config.php /var/www/nextcloud/config/
</code></pre></div></div>
<p>8 - Si vous conservez votre data/répertoire dans votre nextcloud/répertoire, copiez-le de votre ancienne version de Nextcloud vers votre nouveau nextcloud/. Si vous le conservez à lextérieur nextcloud/, vous navez rien à faire avec, car son emplacement est configuré dans votre fichier dorigine config.phpet aucune des étapes de mise à niveau ne le touche.</p>
<p>9 - Si vous utilisez une application tierce, il se peut quelle ne soit pas toujours disponible dans votre instance Nextcloud mise à niveau/nouvelle. Pour vérifier cela, comparez une liste des applications du nouveau nextcloud/apps/dossier à une liste des applications de votre dossier sauvegardé/ancien nextcloud/apps/. Si vous trouvez des applications tierces dans lancien dossier qui doivent se trouver dans linstance nouvelle/mise à niveau, copiez-les simplement et assurez-vous que les autorisations sont configurées comme indiqué ci-dessous.</p>
<p>10 - Si vous avez des dossiers dapplications supplémentaires comme par exemple nextcloud/apps-extras ou nextcloud/apps-external, assurez-vous de les transférer/conserver également dans le dossier mis à niveau.</p>
<p>11 - Si vous utilisez un thème tiers, assurez-vous de le copier de votre themes/répertoire vers votre nouveau. Il est possible que vous deviez y apporter quelques modifications après la mise à niveau.</p>
<p>12 - Ajustez la propriété et les autorisations des fichiers :</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># en mode su</span>
<span class="nb">sudo</span> <span class="nt">-s</span>
<span class="c"># si propriétaire www-data</span>
<span class="nb">chown </span>www-data:www-data <span class="nt">-R</span> /var/www/nextcloud
<span class="c"># si propriétaire nextcloud</span>
<span class="nb">chown </span>nextcloud:www-data <span class="nt">-R</span> /var/www/nextcloud
find /var/www/nextcloud/ <span class="nt">-type</span> d <span class="nt">-exec</span> <span class="nb">chmod </span>750 <span class="o">{}</span> <span class="se">\;</span>
find /var/www/nextcloud/ <span class="nt">-type</span> f <span class="nt">-exec</span> <span class="nb">chmod </span>640 <span class="o">{}</span> <span class="se">\;</span>
</code></pre></div></div>
<p>13 - Redémarrez votre serveur Web.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl start nginx
</code></pre></div></div>
<p>14 - Lancez maintenant la mise à niveau depuis la ligne de commande en utilisant occ</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-s</span>
<span class="nb">cd</span> /var/www/nextcloud
<span class="c"># si propriétaire www-data</span>
<span class="nb">sudo</span> <span class="nt">-u</span> www-data php occ upgrade
<span class="c"># si propriétaire nextcloud</span>
<span class="nb">sudo</span> <span class="nt">-u</span> nextcloud php occ upgrade
</code></pre></div></div>
<p>(!) cela DOIT être exécuté à partir de votre répertoire dinstallation nextcloud</p>
<p>15 - Lopération de mise à niveau prend de quelques minutes à quelques heures, selon la taille de votre installation. Une fois lopération terminée, vous verrez un message de réussite ou un message derreur qui vous indiquera où lerreur sest produite.</p>
<p>16 - Réactivez la tâche cron nextcloud. (Voir létape 4 ci-dessus.)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># si propriétaire www-data
sudo crontab -u www-data -e
# si propriétaire nextcloud
sudo crontab -u nextcloud -e
</code></pre></div></div>
<p>(Supprimez le # au début de la ligne correspondante dans le fichier crontab.)</p>
<p><strong>Connectez-vous</strong></p>
<ul>
<li>jetez un œil au bas de votre page dadministration pour vérifier le numéro de version.</li>
<li>Vérifiez vos autres paramètres pour vous assurer quils sont corrects.</li>
<li>Accédez à la page Applications et examinez les applications principales pour vous assurer que les bonnes sont activées.</li>
<li>Réactivez vos applications tierces.</li>
</ul>
<h2 id="partage">Partage</h2>
<h3 id="fédération-nextcloud">Fédération Nextcloud</h3>
<p>Un service est dit fédéré si deux usagers de ce service peuvent interagir sans utiliser le même prestataire de service.</p>
<p>Entre deux comptes sur des Nextcloud différents</p>
<p><em>carla (compte cloud.xoyize.xyz) souhaite partager le dossier Camera avec yann (compte cloud.rnmkcy.eu)</em></p>
<p><u>yann (compte cloud.rnmkcy.eu)</u></p>
<p>Il faut récupérer lID de fédération<br />
<img src="/images/nextcloud-federation05.png" alt="" /><br />
Du type <a href="mailto:5bcd25ef-356abc-a5@cloud.rnmkcy.eu">5bcd25ef-356abc-a5@cloud.rnmkcy.eu</a></p>
<p><u>carla (compte cloud.xoyize.xyz)</u></p>
<ol>
<li>Il faut cliquer sur le symbole de partage en bout de ligne du dossier <strong>Camera</strong><br />
<img src="/images/nextcloud-federation00.png" alt="" /></li>
<li>Puis saisir lidentifiant fédération Nextcloud de yann (compte cloud.rnmkcy.eu) <a href="mailto:5bcd25ef-356abc-a5@cloud.rnmkcy.eu">5bcd25ef-356abc-a5@cloud.rnmkcy.eu</a><br />
<img src="/images/nextcloud-federation01.png" alt="" /></li>
<li><strong>Autoriser la modification</strong> et <strong>Enregistrer</strong> <br />
<img src="/images/nextcloud-federation02.png" alt="" /></li>
</ol>
<p>Le partage est établi avec yann<br />
<img src="/images/nextcloud-federation03.png" alt="" /><br />
<img src="/images/nextcloud-federation04.png" alt="" /></p>
<p>Vérification sur <u>yann (compte cloud.rnmkcy.eu)</u><br />
Il faut aller dans les notifications et accepter le partage<br />
<img src="/images/nextcloud-federation06.png" alt="" /><br />
<img src="/images/nextcloud-federation07.png" alt="" /></p>
<h3 id="synchroniser-deux-serveurs-nextcloud">Synchroniser deux serveurs Nextcloud</h3>
<p>depuis deux sites différents</p>
<p>La synchronisation de deux serveurs multiples Nextcloud à partir de deux sites différents implique la mise en place dune fédération de serveur à serveur, qui permet aux deux instances de partager des fichiers, des dossiers et dautres données. Voici un guide étape par étape sur la façon dy parvenir :</p>
<p>Conditions requises :</p>
<ul>
<li>Deux instances Nextcloud, chacune installée sur un site différent.</li>
<li>URLs accessibles au public pour les deux instances.</li>
<li>Connectivité réseau entre les deux sites (accès internet ou connexion directe).</li>
</ul>
<p>Etapes pour synchroniser deux serveurs Nextcloud :</p>
<p>Activer lapplication Federation : Sur les deux instances Nextcloud, sassurer que lapplication “Federation” est activée. Cette application permet aux serveurs de communiquer et de partager des données.</p>
<p>Configurer le serveur de confiance sur la première instance Nextcloud (Site A) :</p>
<ul>
<li>Se connecter en tant quadministrateur.</li>
<li>Aller dans “Paramètres dadministration” &gt; “Administration” &gt; “Partage”.</li>
<li>Descendez jusquà la section “Serveurs de confiance” et cliquez sur “Ajouter un serveur de confiance”.</li>
<li>Entrez lURL de la deuxième instance Nextcloud (Site B) et générez un jeton.<br />
<img src="/images/nextcloud-federation08.png" alt="" /></li>
</ul>
<p>Configurer le serveur de confiance sur la deuxième instance (Site B)</p>
<ul>
<li>Se connecter en tant quadministrateur.</li>
<li>Aller dans “Paramètres dadministration” &gt; “Administration” &gt; “Partage”.</li>
<li>Descendez jusquà la section “Serveurs de confiance” et cliquez sur “Ajouter un serveur de confiance”.</li>
<li>Entrez lURL de la première instance Nextcloud (Site A)</li>
<li><img src="/images/nextcloud-federation09.png" alt="" /></li>
</ul>
<p>Lancez le partage<br />
Sur lune des instances (disons le site A) :</p>
<ul>
<li>Connectez-vous en tant quutilisateur.</li>
<li>Naviguez jusquau fichier ou dossier que vous souhaitez partager avec lautre instance (Site B).</li>
<li>Cliquez sur le bouton “Partager” et entrez ladresse e-mail dun utilisateur sur la deuxième instance (Site</li>
</ul>
<p>Choisissez les permissions appropriées (lecture seule, lecture/écriture, etc.).</p>
<ul>
<li>Cliquez sur “Partager”.</li>
</ul>
<p>Accepter linvitation au partage :<br />
Sur lautre instance (Site B) :</p>
<ul>
<li>Connectez-vous en tant quutilisateur ayant reçu linvitation de partage.</li>
<li>Vous devriez voir une notification ou une invitation de partage entrante. Acceptez le partage.</li>
</ul>
<p>Synchronisation des données :<br />
Une fois le partage accepté, les données seront synchronisées entre les deux instances. Les modifications effectuées sur une instance seront répercutées sur lautre. Notez que la synchronisation peut prendre un certain temps en fonction de la taille des données et de la bande passante disponible sur le réseau.</p>
<p>Surveiller et gérer :<br />
Vous pouvez surveiller létat des connexions de serveur à serveur et des fichiers partagés par le biais de linterface Nextcloud. Toute mise à jour ou modification sera propagée entre les deux instances.</p>
<p>Répéter pour dautres partages :<br />
Vous pouvez répéter le processus pour partager dautres fichiers et dossiers entre les deux instances.</p>
<p>Rappelez-vous que cette configuration nécessite que les deux instances disposent dune connectivité internet fiable ou dune connexion réseau dédiée entre les sites. Veillez également à ce que les deux instances soient à jour et correctement sécurisées afin de préserver lintégrité et la confidentialité des données partagées.</p>
<h2 id="nextcloud-authentification">Nextcloud Authentification</h2>
<h3 id="mot-de-passe-dapplication">Mot de passe dapplication</h3>
<p><em>créer un mot de passe dapplication afin de permettre à des applications de se connecter rapidement et de façon sécurisée à votre compte Nextcloud</em></p>
<p><img src="/images/mp-appli01.png" alt="" /><br />
<img src="/images/mp-appli02.png" alt="" /></p>
<p>En cas de problème, vous pouvez notamment en cliquant sur les trois points à côté de votre mot de passe dapplication<br />
<img src="/images/mp-appli03.png" alt="" /></p>
<ul>
<li><strong>Effacer lappareil</strong> commande leffacement à distance , ce qui ordonne à lappareil (sil a été volé par exemple) deffacer tous les fichiers de votre compte Nextcloud quil contient.</li>
<li><strong>Révoquer</strong> le mot de passe, ce qui le désactive et empêche toute connexion ultérieure par ce mot de passe à votre compte Nextcloud, sans aucun impact sur votre mot de passe principal Nextcloud, qui reste sûr.</li>
</ul>
<h3 id="connexion-mobile-android-à-un-compte-nextcloud">Connexion mobile Android à un compte Nextcloud</h3>
<p>Créer un mot de passe application, voir ci-dessus. Le mot de passe dapplication se nomme “Mobiles”</p>
<p>Sur votre mobile, installez lapplication Nextcloud, disponible sur le <a href="https://play.google.com/store/apps/details?id=com.nextcloud.client&amp;gl=US">Play Store</a> ou sur <a href="https://f-droid.org/en/packages/com.nextcloud.client/">F-Droid</a>.<br />
Lancez lapplication et cliquez sur Se connecter.<br />
<img src="/images/mp-appli04.png" alt="" height="400" /></p>
<p>Lapplication lance un navigateur, cliquez sur <strong>Authentification alternative en utilisant un mot de passe dapplication.</strong><br />
<img src="/images/mp-appli05.png" alt="" height="400" /> <img src="/images/mp-appli06.png" alt="" height="400" /><br />
Connexion établie<br />
<img src="/images/mp-appli07.png" alt="" height="400" /></p>
<h3 id="double-facteur---totp">Double facteur - TOTP</h3>
<p>Paramètres → Applications → Applications mises en avant <br />
<img src="/images/nextcloud_hub07.png" alt="" /><br />
Activer “Two-Factor TOTP Provider”</p>
<p>Paramètres → Administration settings → Sécurité dans la rubrique Administration <br />
<img src="/images/cloud.ouestyan.fr10a.png" alt="" /> <br />
Puis cliquer sur <strong>Enregistrer les modifications</strong></p>
<p>Aller ensuite sur Paramètres personnels → Sécurité dans la rubrique Personnel
<img src="/images/cloud.ouestyan.fr10b.png" alt="" /></p>
<p>Après avoir activé authentification TOTP (saisie du mot de passe)<br />
<img src="/images/cloud.ouestyan.fr11.png" alt="" /> <br />
Enter le <strong>secret TOTP</strong> dans le ou les applications TOPT <br />
Saisir le code de vérification générer par votre application et cliquer sur “Vérifier” <br />
Ensuite cliquer sur “Générer des codes de récupération”<br />
<img src="/images/cloud.ouestyan.fr11a.png" alt="" /></p>
<h3 id="double-facteur---clé-de-sécurité">Double facteur - Clé de sécurité</h3>
<p><em><img src="/images/yubikey5nfc.png" alt="" height="50" />YubiKey 5 Series Une gamme multiprotocole (FIDO2/WebAuthn, U2F, Smart Card, OpenPGP, OTP) qui est le premier choix des entreprises et qui prend en charge la fonction sans mot de passe</em></p>
<ol>
<li>La clé “Yubikey 5 NFC” est connectée sur un port USB de lordinateur</li>
<li>Nextcloud, Paramétrage “Personnel” -&gt; “Sécurité” -&gt; “Authentification à deux facteurs” cliquer sur “Ajouter une clé de sécurité”</li>
<li>Valider la prise en charge <img src="/images/yubikey-validation.png" alt="" /></li>
<li>Donner un nom :<br />
<img src="/images/nextcloud_hub06a1.png" alt="" /><br />
Faire la même opération avec les autres clés<br />
Se déconnecter de nextcloud</li>
</ol>
<h3 id="sans-mot-de-passe---webauthnn">Sans mot de passe - WebAuthnn</h3>
<p><em><img src="/images/yubikey5nfc.png" alt="" height="50" />YubiKey 5 Series Une gamme multiprotocole (FIDO2/WebAuthn, U2F, Smart Card, OpenPGP, OTP) qui est le premier choix des entreprises et qui prend en charge la fonction sans mot de passe</em></p>
<p><code class="language-plaintext warning highlighter-rouge">ATTENTION: Fonctionne uniquement sur les navigateurs Chrome, Firefox et Edge</code></p>
<p>Paramètres → Applications → Applications mises en avant <br />
<img src="/images/nextcloud_hub08.png" alt="" /><br />
Télécharger et activer lapplication <strong>Two-Factor WebAuthnn</strong></p>
<ol>
<li>La clé “Yubikey 5 NFC” est connectée sur un port USB de lordinateur</li>
<li>Nextcloud, Paramétrage “Personnel” -&gt; “Sécurité” -&gt; “Authentification sans mot de passe” cliquer sur “Ajouter un périphérique WebAuthnn”<br />
<img src="/images/nextcloud_hub10.png" alt="" /></li>
<li>Valider la prise en charge <img src="/images/yubikey-validation.png" alt="" /></li>
<li>Donner un nom :<br />
<img src="/images/nextcloud_hub06a.png" alt="" /><br />
Faire la même opération avec les autres clés<br />
Se déconnecter de nextcloud</li>
</ol>
<p><strong>Utilisation connexion sans mot de passe</strong><br />
Ouvrir Nextcloud<br />
<img src="/images/nextcloud_webauthnn01.png" alt="" /></p>
<p><img src="/images/nextcloud_webauthnn03a.png" alt="" /><br />
Saisir le nom utilisateur puis cliquer sur Se connecter<br />
<img src="/images/nextcloud_webauthnn03a1.png" alt="" /><br />
Ensuite vous aurez le message suivant, cliquer sur “Clé de sécurité”<br />
<img src="/images/nextcloud_webauthnn03.png" alt="" /></p>
<p><img src="/images/nextcloud_webauthnn03c.png" alt="" /></p>
<h4 id="firefox-linux-desktop">Firefox linux desktop</h4>
<p>ouvrir le lien https du cloud<br />
<img src="/images/nextcloud_hub06b.png" alt="" /> <img src="/images/nextcloud_hub06c.png" alt="" /><br />
<img src="/images/nextcloud_hub06d.png" alt="" /> -&gt; <img src="/images/yubikey-validation.png" alt="" /></p>
<p><img src="/images/nextcloud_hub06e.png" alt="" /></p>
<h4 id="firefox-android-mobile">Firefox android mobile</h4>
<p><em>Le fonctionnement de la clé NFC est utilisé</em></p>
<h2 id="nextcloud-sauvegarde-restauration">Nextcloud Sauvegarde Restauration</h2>
<h3 id="accès-boîte-de-stockage">Accès boîte de stockage</h3>
<p>Créer un accès à la boîte de stockage <code class="language-plaintext highlighter-rouge">u326239@u326239.your-storagebox.de</code> via sftp et un jeu de clé ed25519</p>
<p>Générer une paire de clé curve25519-sha256 (ECDH avec Curve25519 et SHA2)</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh-keygen -t ed25519 -o -a 100 -f ~/.ssh/bx11-xoyize.net
</code></pre></div></div>
<p>Ajouter la clé publique <code class="language-plaintext highlighter-rouge">bx11-xoyize.net.pub</code> au fichier <code class="language-plaintext highlighter-rouge">.ssh/authorized_keys</code> de la boîte de stockage</p>
<p>Tester la connexion, créer dossier xoyize.net et sortir</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sftp -P 23 -i ~/.ssh/bx11-xoyize.net u326239@u326239.your-storagebox.de
</code></pre></div></div>
<p>Première connexion</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>The authenticity of host '[u326239.your-storagebox.de]:23 ([2a01:4f8:261:59d3::2]:23)' can't be established.
ED25519 key fingerprint is SHA256:XqONwb1S0zuj5A1CDxpOSuD2hnAArV1A3wKY7Z3sdgM.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[u326239.your-storagebox.de]:23' (ED25519) to the list of known hosts.
Connected to u326239.your-storagebox.de.
sftp&gt; mkdir backup/xoyize.net
sftp&gt; exit
</code></pre></div></div>
<h3 id="sauvegarde-nextcloud">Sauvegarde nextcloud</h3>
<p>En mode su dans le dossier /var/www/nextcloud</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -s
cd /var/www/nextcloud
</code></pre></div></div>
<p><a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#">Using the occ command</a></p>
<p>Pour sauvegarder une installation Nextcloud, quatre choses principales</p>
<ul>
<li>Le dossier de configuration</li>
<li>Le dossier de données <strong>/srv/nextcloud-data/</strong></li>
<li>Le dossier thématique</li>
<li>La base de données</li>
</ul>
<p class="warning">ATTENTION : Utilisateur <strong>nextcloud</strong> au lieu de <strong>www-data</strong> pour les dossiers</p>
<p>Créer un dossier pour stocker le mot de passe de la base de données</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mkdir -p /home/yani/.local/share/nextcloud
echo "mot_passe_mysql_nextcloud" &gt; /home/yani/.local/share/nextcloud/dbpassword
</code></pre></div></div>
<p><strong>Mode maintenance</strong><br />
Le mode maintenance verrouille les sessions des utilisateurs connectés et empêche les nouvelles connexions afin déviter les incohérences de vos données. Vous devez exécuter occ comme utilisateur HTTP ou nextcloud</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u nextcloud php occ maintenance:mode --on
</code></pre></div></div>
<p>Renvoie <strong>Maintenance mode enabled</strong></p>
<p><strong>Sauvegarde dossiers</strong><br />
Il suffit de copier vos dossiers de configuration, de données et de thème (ou même votre dossier dinstallation et de données de Nextcloud) vers un endroit à lextérieur de votre environnement Nextcloud</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># dossier /var/www/nextcloud
rsync -Aavx --delete --rsync-path='rsync' -e 'ssh -p 23 -i /home/yani/.ssh/bx11-xoyize.net -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' /var/www/nextcloud u326239@u326239.your-storagebox.de:backup/xoyize.net/nextcloud-dirbkp_`date +"%Y%m%d"`/
# nextcloud data
rsync -Aavx --delete --rsync-path='rsync' -e 'ssh -p 23 -i /home/yani/.ssh/bx11-xoyize.net -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' /srv/nextcloud-data/ u326239@u326239.your-storagebox.de:backup/xoyize.net/nextcloud-databkp_`date +"%Y%m%d"`/
</code></pre></div></div>
<p><strong>Sauvegarde base de données MySql</strong></p>
<p>Pour un support 4 octets MySQL/MariaDB (Enabling MySQL Support 4 octets, nécessaire pour emoji), vous devrez ajouter <code class="language-plaintext highlighter-rouge">--default-character-set=utf8mb4</code></p>
<p>Syntaxe</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysqldump --single-transaction --default-character-set=utf8mb4 -h [serveur] -u [nom d'utilisateur] -p[mot de passe] [db_name] &gt; nextcloud-sqlbkp_`date +"%Y%m%d"`.bak
</code></pre></div></div>
<p>Commande</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># base mysql
mysqldump --single-transaction --default-character-set=utf8mb4 -h localhost -unextcloud -p`cat /home/yani/.local/share/nextcloud/dbpassword` nextcloud &gt; /home/yani/.local/share/nextcloud/nextcloud-sqlbkp_`date +"%Y%m%d"`.bak
# nextcloud database mariadb
rsync -Aavx --delete --rsync-path='rsync' -e 'ssh -p 23 -i /home/yani/.ssh/bx11-xoyize.net -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' /home/yani/.local/share/nextcloud/nextcloud-sqlbkp_`date +"%Y%m%d"`.bak u326239@u326239.your-storagebox.de:backup/xoyize.net/nextcloud-databkp_`date +"%Y%m%d"`/
</code></pre></div></div>
<h3 id="restauration-nextcloud">Restauration nextcloud</h3>
<p><a href="https://docs.nextcloud.com/server/latest/admin_manual/maintenance/restore.html">Restauration nextcloud</a></p>
<p><strong>Restaurer les dossiers</strong></p>
<p>Note : Ce guide suppose que votre sauvegarde précédente est appelée “nextcloud-dirbkp”</p>
<p>Il suffit de copier votre dossier de configuration et de données (ou même votre dossier dinstallation et de données Nextcloud) dans votre environnement Nextcloud. Vous pouvez utiliser cette commande:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rsync -Aax nextcloud-dirbkp/ nextcloud/
</code></pre></div></div>
<p><strong>Restaurer la base de données</strong></p>
<p>Attention<br />
Avant de restaurer une sauvegarde, vous devez vous assurer de supprimer toutes les tables de base de données existantes.</p>
<p>La manière la plus facile de le faire est de déposer et de recréer la base de données. SQLite le fait automatiquement.</p>
<p>MySQL est le moteur de base de données recommandé. Pour restaurer MySQL:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -e "DROP DATABASE nextcloud"
mysql -e "DROP USER 'nextcloud'@'localhost';"
mysql -e "CREATE DATABASE nextcloud"
</code></pre></div></div>
<p>Si vous utilisez UTF8 avec support multioctet (par exemple pour les emojis dans les noms de fichiers), utilisez:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -e "DROP DATABASE nextcloud"
mysql -e "CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci"
</code></pre></div></div>
<p>Note Ce guide suppose que votre sauvegarde précédente est appelée «nextcloud-sqlbkp.bak»</p>
<p>MySQL est le moteur de base de données recommandé. Pour restaurer MySQL:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mysql -h [serveur] -u [nom d'utilisateur] -p[mot de passe] [db_name]
</code></pre></div></div>
<h3 id="synchronisation-avec-les-clients">Synchronisation avec les clients</h3>
<p>après la récupération de données</p>
<p>Par défaut, le serveur Nextcloud est considéré comme la source pour les données. Si les données sur le serveur et le client diffèrent, les clients récupèrent par défaut les données sur le serveur.</p>
<p>Si la sauvegarde récupérée est dépassée, létat des clients peut être plus à jour que létat du serveur. Dans ce cas également assurez-vous de lancer la commande <code class="language-plaintext highlighter-rouge">maintenance:data-fingerprint</code> par la suite. Il modifie la logique de lalgorithme de synchronisation pour essayer de récupérer autant de données que possible. Les fichiers manquants sur le serveur sont donc récupérés auprès des clients et en cas de contenu différent les utilisateurs seront demandés.</p>
<p>Note:<br />
Lutilisation de la maintenance : lempreinte de données peut provoquer des dialogues de conflit et des difficultés à supprimer des fichiers sur le client. Par conséquent, il est seulement recommandé dempêcher la perte de données si la sauvegarde a été dépassée.</p>
<p>Si vous exécutez plusieurs serveurs dapplications, vous devrez vous assurer que les fichiers de configuration sont synchronisés entre eux de sorte que lempreinte de données actualisée est appliquée sur tous les cas.</p>
<h2 id="scripts-bash-sauvegarde-restauration-nextcloud">Scripts Bash Sauvegarde-Restauration Nextcloud</h2>
<p>Scripts Bash pour la sauvegarde/restauration de <a href="https://nextcloud.com/">Nextcloud</a>.</p>
<p>Il est basé sur une installation Nextcloud utilisant nginx et PostgreSQL/MariaDB (voir le tutoriel (allemand) <a href="https://decatec.de/home-server/nextcloud-auf-ubuntu-server-22-04-lts-mit-nginx-postgresql-mariadb-php-lets-encrypt-redis-und-fail2ban/">Nextcloud auf Ubuntu Server 22.04 LTS mit nginx, PostgreSQL/MariaDB, PHP, Lets Encrypt, Redis und Fail2ban</a>).<br />
<em>Les scripts peuvent également être utilisés lorsquApache est utilisé comme serveur Web.</em></p>
<h3 id="informations-générales">Informations générales</h3>
<p>Pour une sauvegarde complète de nimporte quelle instance Nextcloud, vous devrez sauvegarder ces éléments :</p>
<ul>
<li>Le répertoire de fichiers Nextcloud (généralement /var/www/nextcloud )</li>
<li>Le répertoire de données de Nextcloud (il est recommandé quil ne se trouve pas à la racine Web, donc par exemple /var/nextcloud_data )</li>
<li>La base de données Nextcloud</li>
<li>Eventuellement un stockage externe local monté dans Nextcloud</li>
</ul>
<p>Avec ces scripts, tous ces éléments peuvent être inclus dans une sauvegarde.</p>
<h3 id="exigences">Exigences</h3>
<ul>
<li><em>tar</em></li>
<li><em>pigz</em> (https://zlib.net/pigz/) lors de lutilisation de la compression de sauvegarde. Sil nest pas déjà installé, il peut être installé avec <code class="language-plaintext highlighter-rouge">apt install pigz</code> (Debian/Ubuntu).<br />
Sil nest pas disponible, vous pouvez utiliser un autre algorithme de compression (par exemple gzip)</li>
</ul>
<h3 id="remarques-importantes-sur-lutilisation-des-scripts">Remarques importantes sur lutilisation des scripts</h3>
<ul>
<li>Après avoir cloné ou téléchargé les scripts, ceux-ci doivent être configurés en exécutant le script setup.sh(voir ci-dessous).</li>
<li>Si vous ne souhaitez pas utiliser linstallation automatisée, vous pouvez également utiliser le fichier <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf.sample</code> comme point de départ. Assurez-vous simplement de renommer le fichier lorsque vous avez terminé (<code class="language-plaintext highlighter-rouge">cp NextcloudBackupRestore.conf.sample NextcloudBackupRestore.conf</code>)</li>
<li>Le fichier de configuration <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code> doit se trouver dans le même répertoire que les scripts de sauvegarde/restauration.</li>
<li>Les scripts supposent que le <u>répertoire de données de Nextcloud n'est pas un sous-répertoire de l'installation de Nextcloud</u> (répertoire de fichiers). La recommandation générale est que le répertoire de données ne doit pas se trouver quelque part dans le dossier Web de votre serveur Web (généralement <em>/var/www/</em>), mais dans un dossier différent (par exemple /var/nextcloud_data ). Pour plus dinformations, voir <a href="https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html#data-directory-location-label">ici</a>.</li>
<li>Cependant, si votre répertoire de données se trouve sous le répertoire de fichiers Nextcloud, vous devrez modifier la configuration du script (fichier <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code> après exécution <code class="language-plaintext highlighter-rouge">setup.sh</code>) afin que le répertoire de données ne fasse pas partie de la sauvegarde/restauration (sinon, il serait copié deux fois)</li>
<li>Les scripts sauvegardent uniquement le répertoire de données Nextcloud et peuvent sauvegarder un stockage externe local monté dans Nextcloud. Si vous disposez dun autre stockage externe monté dans Nextcloud (par exemple FTP), ces fichiers doivent être traités séparément.</li>
<li>Les scripts prennent en charge nginx et Apache comme serveur Web.</li>
<li>Les scripts prennent en charge MariaDB/MySQL et PostgreSQL comme base de données.</li>
<li>Vous devriez avoir activé la prise en charge de 4 octets (voir <a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_database/mysql_4byte_support.html">Nextcloud Administration Manual</a>) sur votre base de données Nextcloud. Sinon, lorsque vous navez pas activé le support 4 octets, vous devez éditer le script de restauration, afin que la base de données ne soit pas créée avec le support 4 octets activé (variable <code class="language-plaintext highlighter-rouge">dbNoMultibyte</code>).</li>
<li>Les scripts peuvent exclure le répertoire de données Nextcloud de la sauvegarde et de la restauration.
<strong>ATTENTION</strong> : Lexclusion du répertoire de données nest <strong>PAS RECOMMANDÉE</strong> car cela laisse la sauvegarde dans un état incohérent et peut entraîner une perte de données !</li>
</ul>
<h3 id="installation">Installation</h3>
<ol>
<li>Clonez le dépôt: <code class="language-plaintext highlighter-rouge">git clone https://codeberg.org/DecaTec/Nextcloud-Backup-Restore.git</code></li>
<li>Définir les autorisations:
<ul>
<li><code class="language-plaintext highlighter-rouge">chown -R root Nextcloud-Backup-Restore</code></li>
<li><code class="language-plaintext highlighter-rouge">cd Nextcloud-Backup-Restore</code></li>
<li><code class="language-plaintext highlighter-rouge">chmod 700 *.sh</code></li>
</ul>
</li>
<li>Appelez le script (interactif) de configuration automatisée (cela créera un fichier <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code> contenant la configuration souhaitée): <code class="language-plaintext highlighter-rouge">./setup.sh</code></li>
<li><strong>Important</strong>: Vérifiez ce fichier de configuration si tout a été configuré correctement (voir TODO dans les commentaires du fichier de configuration)</li>
<li>Commencez à utiliser les scripts : voir les sections <em>Sauvegarde</em> et <em>restauration</em> ci-dessous</li>
</ol>
<p>Gardez à lesprit que le fichier de configuration <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code> doit être situé dans le même répertoire que les scripts de sauvegarde/restauration, sinon la configuration ne sera pas trouvée.</p>
<p>Certaines options facultatives ne sont pas configurées à laide de <code class="language-plaintext highlighter-rouge">setup.sh</code>, mais sont définies sur les valeurs par défaut dans <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code>. Ce sont les options “dangereuses” qui ne doivent généralement pas être modifiées et qui sont marquées comme OPTIONAL dans <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code></p>
<h3 id="sauvegarde">Sauvegarde</h3>
<p>Afin de créer une sauvegarde, appelez simplement le script <em>NextcloudBackup.sh</em> sur votre machine Nextcloud. Si ce script est appelé sans paramètre, la sauvegarde est enregistrée dans un répertoire avec lhorodatage actuel dans votre répertoire de sauvegarde principal : à titre dexemple, ce serait <em>/media/hdd/nextcloud_backup/20170910_132703</em>. Le script de sauvegarde peut également être appelé avec un paramètre spécifiant le répertoire de sauvegarde principal, par exemple <em>./NextcloudBackup.sh /media/hdd/nextcloud_backup</em>. Dans ce cas, le répertoire spécifié sera utilisé comme répertoire principal de sauvegarde.</p>
<p>Vous pouvez également appeler ce script par cron. Exemple (à 2h du matin tous les soirs, avec sortie de journal) :</p>
<p><code class="language-plaintext highlighter-rouge">0 2 * * * /path/to/scripts/Nextcloud-Backup-Restore/NextcloudBackup.sh &gt; /path/to/logs/Nextcloud-Backup-$(date +\%Y\%m\%d\%H\%M\%S).log 2&gt;&amp;1</code></p>
<h3 id="restauration">Restauration</h3>
<p>Appelez <em>NextcloudRestore.sh</em> afin de restaurer une sauvegarde.<br />
Lorsque ce script est appelé sans paramètres, il répertorie les sauvegardes disponibles pour la restauration. <br />
Afin de restaurer une sauvegarde, appelez ce script avec un paramètre précisant le nom (cest-à-dire lhorodatage) de la sauvegarde à restaurer. Dans cet exemple, ce serait <em>20170910_132703</em>. La commande complète pour une restauration serait <em>./NextcloudRestore.sh 20170910_132703</em>.
Vous pouvez également spécifier le répertoire de sauvegarde principal avec un deuxième paramètre, par exemple <em>./NextcloudRestore.sh 20170910_132703 /media/hdd/nextcloud_backup</em>.</p>
<h3 id="mise-à-jour-des-scripts">Mise à jour des scripts</h3>
<p>Après avoir mis à jour les scripts vers une version plus récente, il est recommandé dexécuter (<code class="language-plaintext highlighter-rouge">setup.sh</code>) à nouveau le script de configuration afin de sassurer que les dernières modifications sont appliquées au fichier de configuration <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code>. <br />
Gardez à lesprit quune version déjà existante de <code class="language-plaintext highlighter-rouge">NextcloudBackupRestore.conf</code> sera écrasée au cours de cette procédure.</p>
<p>Il est également recommandé dexécuter à nouveau le script de configuration si vous souhaitez modifier certains paramètres de base de sauvegarde/restauration (par exemple activer ou désactiver la compression).</p>
<h2 id="maintenance">Maintenance</h2>
<ul>
<li><a href="https://docs.nextcloud.com/server/latest/admin_manual/index.html">Nextcloud Server Administration Guide</a></li>
<li><a href="https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/occ_command.html#">Utiliser les commandes php occ</a></li>
</ul>
<h3 id="ipv6-mal-identifié">IPV6 mal identifié</h3>
<p class="error">Il y a quelques erreurs concernant votre configuration.
Votre adresse réseau a été identifiée comme « 2a01:e0a:9c8:2080:e4df:3427:584e:b684 » et elle est bridée par le mécanisme anti-intrusion ce qui ralentit la performance de certaines requêtes. Si cette adresse réseau nest pas la vôtre, cela peut signifier quil y a une erreur de configuration dun proxy.</p>
<p>Il faut activer lapplication <strong>Brute-force-settings</strong><br />
<img src="/images/cloud.rnmkcy.eu09.png" alt="" /> <br />
Puis dans “Paramètres dadministration” , “Sécurité”<br />
<img src="/images/cloud.rnmkcy.eu10.png" alt="" /></p>
<h3 id="base-de-données-index-manquants">Base de données, index manquants</h3>
<p class="warning">La base de données a quelques index manquants. Lajout dindex dans de grandes tables peut prendre un certain temps. Elles ne sont donc pas ajoutées automatiquement. En exécutant “occ db:add-missing-indices”, ces index manquants pourront être ajoutés manuellement pendant que linstance continue de tourner. Une fois les index ajoutés, les requêtes sur ces tables sont généralement beaucoup plus rapides. Index optionnels manquants « mail_messages_strucanalyz_idx » dans la table « mail_messages ». Index optionnels manquants « mail_class_creat_idx » dans la table « mail_classifiers ». Index optionnels manquants « mail_acc_prov_idx » dans la table « mail_accounts ». Index optionnels manquants « mail_alias_accid_idx » dans la table « mail_aliases ».</p>
<p>Procédure pour la correction</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-s</span>
<span class="nb">cd</span> /var/www/nextcloud
<span class="nb">sudo</span> <span class="nt">-u</span> nextcloud /usr/bin/php8.2 occ db:add-missing-indices
</code></pre></div></div>
<p>Résultat</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Adding additional mail_messages_strucanalyz_idx index to the oc_mail_messages table, this can take some time...
oc_mail_messages table updated successfully.
Adding additional mail_class_creat_idx index to the oc_mail_classifiers table, this can take some time...
oc_mail_classifiers table updated successfully.
Adding additional mail_acc_prov_idx index to the oc_mail_accounts table, this can take some time...
oc_mail_accounts table updated successfully.
Adding additional mail_alias_accid_idx index to the oc_mail_aliases table, this can take some time...
oc_mail_aliases table updated successfully.
</code></pre></div></div>
<p>Ouvrir Nextcloud, <strong>Administration → Vue densemble</strong></p>
<h3 id="intégrité-des-fichiers">Intégrité des fichiers</h3>
<p><img src="/images/cloud.rnmkcy.eu01 .png" alt="" /><br />
Liste des fichiers invalides</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Technical information
=====================
The following list covers which files have failed the integrity check. Please read
the previous linked documentation to learn more about the errors and how to fix
them.
Results
=======
- core
- EXTRA_FILE
- nextcloud.log
[...]
</code></pre></div></div>
<p>Supprimer les fichiers nextcloud.log et rescanner</p>
<h3 id="fichiers-absents-après-mise-à-jour">Fichiers absents après mise à jour</h3>
<p>Il arrive parfois que les fichiers napparaissent pas après une mise à niveau . Une nouvelle analyse des fichiers peut aider</p>
<div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-u</span> www-data php console.php files:scan <span class="nt">--all</span>
<span class="c"># si nextcloud propriétaire</span>
<span class="nb">sudo</span> <span class="nt">-u</span> nextcloud php console.php files:scan <span class="nt">--all</span>
</code></pre></div></div>
<p>Parfois, Nextcloud peut rester bloqué lors dune mise à niveau si le processus de mise à niveau basé sur le Web est utilisé. Cela est généralement dû au fait que le processus prend trop de temps et rencontre un délai dattente PHP.</p>
<p>Arrêtez le processus de mise à niveau de cette façon :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data php occ maintenance:mode --off
</code></pre></div></div>
<p>Démarrez ensuite le processus manuel :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data php occ upgrade
</code></pre></div></div>
<p>Si cela ne fonctionne pas correctement, essayez la fonction de réparation :</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u www-data php occ maintenance:repair
</code></pre></div></div>
<h3 id="entretien-de-nextcloud-corbeille-php-et-cache">Entretien de Nextcloud (corbeille, PHP et cache)</h3>
<p>En mode sudo : <code class="language-plaintext highlighter-rouge">sudo -s</code></p>
<p><strong>Vider la corbeille</strong><br />
Il peut arriver, lorsque la corbeille devient très chargée, quil ne soit plus possible de la vider via linterface graphique. Dans ce cas-ci, il est recommandé dutiliser la ligne de commande pour effectuer une vidange manuelle. De plus, cette méthode permet daccomplir le travail pour plusieurs comptes à la fois, ou même pour lensemble de linstallation.</p>
<p>Premièrement, on va se positionner dans le répertoire dinstallation de Nextcloud, généralement <code class="language-plaintext highlighter-rouge">/var/www/nextcloud</code></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /var/www/nextcloud
</code></pre></div></div>
<p>Si votre installation est native, lutilisateur sera <strong>www-data</strong>. Si, par contre, vous utilisez Yunohost, votre utilisateur est <strong>nextcloud</strong>, car il crée des utilisateurs pour chaque application.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">nc_user</span><span class="o">=</span>nextcloud <span class="c"># changer ici au besoin</span>
</code></pre></div></div>
<p>Nous allons exécuter la commande suivante pour nettoyer le système de fichiers et la corbeille</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo -u ${nc_user} php occ trashbin:cleanup --all-users
</code></pre></div></div>
<p><strong>Limiter la durée de rétention des fichiers</strong><br />
On peut limiter la durée de rétention des fichiers. Pour ce faire, il faut modifier le fichier <code class="language-plaintext highlighter-rouge">/var/www/nextcloud/config/config.php</code><br />
À la fin du fichier, après la dernière ligne de paramètres, ajouter la ligne suivante:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'trashbin_retention_obligation' =&gt; '30, 35',
</code></pre></div></div>
<p><strong>Maintenance automatique</strong><br />
Nextcloud inclus une routine PHP pour effectuer des tâches de maintenance automatique. Nous pouvons augmenter la fréquence dexécution en ajoutant cette ligne de commande à la table de CRON de lutilisateur root. Pour modifier, utiliser cette commande:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo crontab -u ${nc_user} -e
</code></pre></div></div>
<p>Ajouter la ligne suivante:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>*/15 * * * * php -f /var/www/nextcloud/cron.php
</code></pre></div></div>
<p><strong>Nettoyer le cache des fichiers</strong><br />
Pour nettoyer le cache des fichiers, la commande est similaire à celle utilisée précédemment pour vider la corbeille</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo</span> <span class="nt">-u</span> <span class="k">${</span><span class="nv">nc_user</span><span class="k">}</span> php occ files:scan <span class="nt">--all</span>
<span class="nb">sudo</span> <span class="nt">-u</span> <span class="k">${</span><span class="nv">nc_user</span><span class="k">}</span> php occ files:cleanup
</code></pre></div></div>
2024-11-21 17:20:33 +01:00
<h3 id="avertissements-et-erreurs-de-mise-à-jour">Avertissements et Erreurs de mise à jour</h3>
2024-10-31 20:18:37 +01:00
<p><strong>Passage Nextcloud Hub 9 (30.0.0)</strong> septembre 2024</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> Detected some missing optional indices. Occasionally new indices are added (by Nextcloud or installed applications) to improve database performance. Adding indices can sometimes take awhile and temporarily hurt performance so this is not done automatically during upgrades. Once the indices are added, queries to those tables should be faster. Use the command `occ db:add-missing-indices` to add them. Index manquants : "fs_name_hash" in table "filecache". Pour plus dinformation, voir la documentation ↗.
sudo -u nextcloud php occ maintenance:mode --on # Maintenance mode enabled
sudo -u nextcloud php occ db:add-missing-indices
sudo -u nextcloud php occ maintenance:mode --off # Maintenance disabled
---
One or more mimetype migrations are available. Occasionally new mimetypes are added to better handle certain file types. Migrating the mimetypes take a long time on larger instances so this is not done automatically during upgrades. Use the command `occ maintenance:repair --include-expensive` to perform the migrations.
sudo -u nextcloud php occ maintenance:repair --include-expensive
</code></pre></div></div>
<p><strong>BUG</strong> NON RESOLU le 20/09/2024</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>An exception occured while running the setup check: ValueError: The arguments array must contain 3 items, 1 given in /var/www/nextcloud/lib/private/L10N/L10NString.php:68 Stack trace:
#0 /var/www/nextcloud/lib/private/L10N/L10NString.php(68): vsprintf()
#1 /var/www/nextcloud/lib/private/L10N/L10N.php(107): OC\L10N\L10NString-&gt;__toString()
#2 /var/www/nextcloud/lib/private/L10N/LazyL10N.php(38): OC\L10N\L10N-&gt;n()
#3 /var/www/nextcloud/apps/user_ldap/lib/SetupChecks/LdapConnection.php(87): OC\L10N\LazyL10N-&gt;n()
#4 /var/www/nextcloud/lib/private/SetupCheck/SetupCheckManager.php(34): OCA\User_LDAP\SetupChecks\LdapConnection-&gt;run()
#5 /var/www/nextcloud/apps/settings/lib/Controller/CheckSetupController.php(147): OC\SetupCheck\SetupCheckManager-&gt;runAll()
#6 /var/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php(208): OCA\Settings\Controller\CheckSetupController-&gt;check()
#7 /var/www/nextcloud/lib/private/AppFramework/Http/Dispatcher.php(114): OC\AppFramework\Http\Dispatcher-&gt;executeController()
#8 /var/www/nextcloud/lib/private/AppFramework/App.php(161): OC\AppFramework\Http\Dispatcher-&gt;dispatch()
#9 /var/www/nextcloud/lib/private/Route/Router.php(302): OC\AppFramework\App::main()
#10 /var/www/nextcloud/lib/base.php(1001): OC\Route\Router-&gt;match()
#11 /var/www/nextcloud/index.php(24): OC::handleRequest()
#12 {main}
</code></pre></div></div>
<p>Le(s) lien(s)</p>
<ul>
<li></li>
</ul>
2024-11-21 17:20:33 +01:00
<p><strong>Passage Nextcloud Hub 9 (30.0.2)</strong> novembre 2024</p>
<p>Avertissement sur un problème de cache</p>
<p class="warning">Le module PHP OPcache nest pas correctement configuré. Le tampon mémoire des chaînes internes OPcache est presque plein. Pour vous assurer que les chaînes répétitives peuvent être mise en cache, il est recommandé de définir la variable “opcache.interned_strings_buffer” de votre fichier de configuration PHP à une valeur supérieure à “16”</p>
<p>Correction dans le fichier <code class="language-plaintext highlighter-rouge">/etc/php/8.3/fpm/pool.d/nextcloud.conf</code><br />
<code class="language-plaintext highlighter-rouge">php_value[opcache.interned_strings_buffer]=256</code><br />
Relancer fpm : <code class="language-plaintext highlighter-rouge">sudo systemctl restart php8.3-fpm</code></p>
2024-10-31 20:18:37 +01:00
</div>
<div class="d-print-none"><footer class="article__footer"><meta itemprop="dateModified" content="2023-09-02T00:00:00+02:00"><!-- start custom article footer snippet -->
<!-- end custom article footer snippet -->
<!--
<div align="right"><a type="application/rss+xml" href="/feed.xml" title="S'abonner"><i class="fa fa-rss fa-2x"></i></a>
&emsp;</div>
-->
</footer>
<div class="article__section-navigator clearfix"><div class="previous"><span>PRÉCÉDENT</span><a href="/2023/09/02/Endeavour_Dell_Latitude_e6230_conteneur_nspawn_debian_bookworm_nspyan.html">EndeavourOS Dell Latitude e6230 --> conteneur nspawn debian bookworm nspyan</a></div><div class="next"><span>SUIVANT</span><a href="/2023/09/12/Economiseur-et-Veille-Ecran-XFCE-xscreensaver.html">Economiseur et veille écran XFCE XScreensaver</a></div></div></div>
</div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
$(function() {
var $this ,$scroll;
var $articleContent = $('.js-article-content');
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var scroll = hasSidebar ? '.js-page-main' : 'html, body';
$scroll = $(scroll);
$articleContent.find('.highlight').each(function() {
$this = $(this);
$this.attr('data-lang', $this.find('code').attr('data-lang'));
});
$articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
$this = $(this);
$this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
});
$articleContent.on('click', '.anchor', function() {
$scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
});
});
});
})();
</script>
</div><section class="page__comments d-print-none"></section></article><!-- start custom main bottom snippet -->
<!-- end custom main bottom snippet -->
</div>
</div></div></div></div>
</div><script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $body = $('body'), $window = $(window);
var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
var activeCount = 0;
function modal(options) {
var $root = this, visible, onChange, hideWhenWindowScroll = false;
var scrollTop;
function setOptions(options) {
var _options = options || {};
visible = _options.initialVisible === undefined ? false : show;
onChange = _options.onChange;
hideWhenWindowScroll = _options.hideWhenWindowScroll;
}
function init() {
setState(visible);
}
function setState(isShow) {
if (isShow === visible) {
return;
}
visible = isShow;
if (visible) {
activeCount++;
scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
$root.addClass('modal--show');
$pageMain.scrollTop(scrollTop);
activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
$window.on('keyup', handleKeyup);
} else {
activeCount > 0 && activeCount--;
$root.removeClass('modal--show');
$window.scrollTop(scrollTop);
activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
$window.off('keyup', handleKeyup);
}
onChange && onChange(visible);
}
function show() {
setState(true);
}
function hide() {
setState(false);
}
function handleKeyup(e) {
// Char Code: 27 ESC
if (e.which === 27) {
hide();
}
}
setOptions(options);
init();
return {
show: show,
hide: hide,
$el: $root
};
}
$.fn.modal = modal;
});
})();
</script><div class="modal modal--overflow page__search-modal d-print-none js-page-search-modal"><script>
(function () {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
// search panel
var search = (window.search || (window.search = {}));
var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
true : window.useDefaultSearchBox ;
var $searchModal = $('.js-page-search-modal');
var $searchToggle = $('.js-search-toggle');
var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
var modalVisible = false;
search.searchModal = searchModal;
var $searchBox = null;
var $searchInput = null;
var $searchClear = null;
function getModalVisible() {
return modalVisible;
}
search.getModalVisible = getModalVisible;
function handleModalChange(visible) {
modalVisible = visible;
if (visible) {
search.onShow && search.onShow();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
} else {
search.onShow && search.onHide();
useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
setTimeout(function() {
useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
search.clear && search.clear();
window.pageAsideAffix && window.pageAsideAffix.refresh();
}, 400);
}
}
$searchToggle.on('click', function() {
modalVisible ? searchModal.hide() : searchModal.show();
});
// Char Code: 83 S, 191 /
$(window).on('keyup', function(e) {
if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
modalVisible || searchModal.show();
}
});
if (useDefaultSearchBox) {
$searchBox = $('.js-search-box');
$searchInput = $searchBox.children('input');
$searchClear = $searchBox.children('.js-icon-clear');
search.getSearchInput = function() {
return $searchInput.get(0);
};
search.getVal = function() {
return $searchInput.val();
};
search.setVal = function(val) {
$searchInput.val(val);
};
$searchInput.on('focus', function() {
$(this).addClass('focus');
});
$searchInput.on('blur', function() {
$(this).removeClass('focus');
});
$searchInput.on('input', window.throttle(function() {
var val = $(this).val();
if (val === '' || typeof val !== 'string') {
search.clear && search.clear();
} else {
$searchBox.addClass('not-empty');
search.onInputNotEmpty && search.onInputNotEmpty(val);
}
}, 400));
$searchClear.on('click', function() {
$searchInput.val(''); $searchBox.removeClass('not-empty');
search.clear && search.clear();
});
}
});
})();
</script><div class="search search--dark">
<div class="main">
<div class="search__header">Recherche</div>
<div class="search-bar">
<div class="search-box js-search-box">
<div class="search-box__icon-search"><i class="fas fa-search"></i></div>
<input id="search-input" type="text" />
<div class="search-box__icon-clear js-icon-clear">
<a><i class="fas fa-times"></i></a>
</div>
</div>
<button class="button button--theme-dark button--pill search__cancel js-search-toggle">
Annuler</button>
</div>
<div id="results-container" class="search-result js-search-result"></div>
</div>
</div>
<!-- Script pointing to search-script.js -->
<script>/*!
* Simple-Jekyll-Search
* Copyright 2015-2020, Christian Fei
* Licensed under the MIT License.
*/
(function(){
'use strict'
var _$Templater_7 = {
compile: compile,
setOptions: setOptions
}
const options = {}
options.pattern = /\{(.*?)\}/g
options.template = ''
options.middleware = function () {}
function setOptions (_options) {
options.pattern = _options.pattern || options.pattern
options.template = _options.template || options.template
if (typeof _options.middleware === 'function') {
options.middleware = _options.middleware
}
}
function compile (data) {
return options.template.replace(options.pattern, function (match, prop) {
const value = options.middleware(prop, data[prop], options.template)
if (typeof value !== 'undefined') {
return value
}
return data[prop] || match
})
}
'use strict';
function fuzzysearch (needle, haystack) {
var tlen = haystack.length;
var qlen = needle.length;
if (qlen > tlen) {
return false;
}
if (qlen === tlen) {
return needle === haystack;
}
outer: for (var i = 0, j = 0; i < qlen; i++) {
var nch = needle.charCodeAt(i);
while (j < tlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}
var _$fuzzysearch_1 = fuzzysearch;
'use strict'
/* removed: const _$fuzzysearch_1 = require('fuzzysearch') */;
var _$FuzzySearchStrategy_5 = new FuzzySearchStrategy()
function FuzzySearchStrategy () {
this.matches = function (string, crit) {
return _$fuzzysearch_1(crit.toLowerCase(), string.toLowerCase())
}
}
'use strict'
var _$LiteralSearchStrategy_6 = new LiteralSearchStrategy()
function LiteralSearchStrategy () {
this.matches = function (str, crit) {
if (!str) return false
str = str.trim().toLowerCase()
crit = crit.trim().toLowerCase()
return crit.split(' ').filter(function (word) {
return str.indexOf(word) >= 0
}).length === crit.split(' ').length
}
}
'use strict'
var _$Repository_4 = {
put: put,
clear: clear,
search: search,
setOptions: __setOptions_4
}
/* removed: const _$FuzzySearchStrategy_5 = require('./SearchStrategies/FuzzySearchStrategy') */;
/* removed: const _$LiteralSearchStrategy_6 = require('./SearchStrategies/LiteralSearchStrategy') */;
function NoSort () {
return 0
}
const data = []
let opt = {}
opt.fuzzy = false
opt.limit = 10
opt.searchStrategy = opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = NoSort
opt.exclude = []
function put (data) {
if (isObject(data)) {
return addObject(data)
}
if (isArray(data)) {
return addArray(data)
}
return undefined
}
function clear () {
data.length = 0
return data
}
function isObject (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Object]'
}
function isArray (obj) {
return Boolean(obj) && Object.prototype.toString.call(obj) === '[object Array]'
}
function addObject (_data) {
data.push(_data)
return data
}
function addArray (_data) {
const added = []
clear()
for (let i = 0, len = _data.length; i < len; i++) {
if (isObject(_data[i])) {
added.push(addObject(_data[i]))
}
}
return added
}
function search (crit) {
if (!crit) {
return []
}
return findMatches(data, crit, opt.searchStrategy, opt).sort(opt.sort)
}
function __setOptions_4 (_opt) {
opt = _opt || {}
opt.fuzzy = _opt.fuzzy || false
opt.limit = _opt.limit || 10
opt.searchStrategy = _opt.fuzzy ? _$FuzzySearchStrategy_5 : _$LiteralSearchStrategy_6
opt.sort = _opt.sort || NoSort
opt.exclude = _opt.exclude || []
}
function findMatches (data, crit, strategy, opt) {
const matches = []
for (let i = 0; i < data.length && matches.length < opt.limit; i++) {
const match = findMatchesInObject(data[i], crit, strategy, opt)
if (match) {
matches.push(match)
}
}
return matches
}
function findMatchesInObject (obj, crit, strategy, opt) {
for (const key in obj) {
if (!isExcluded(obj[key], opt.exclude) && strategy.matches(obj[key], crit)) {
return obj
}
}
}
function isExcluded (term, excludedTerms) {
for (let i = 0, len = excludedTerms.length; i < len; i++) {
const excludedTerm = excludedTerms[i]
if (new RegExp(excludedTerm).test(term)) {
return true
}
}
return false
}
/* globals ActiveXObject:false */
'use strict'
var _$JSONLoader_2 = {
load: load
}
function load (location, callback) {
const xhr = getXHR()
xhr.open('GET', location, true)
xhr.onreadystatechange = createStateChangeListener(xhr, callback)
xhr.send()
}
function createStateChangeListener (xhr, callback) {
return function () {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
callback(null, JSON.parse(xhr.responseText))
} catch (err) {
callback(err, null)
}
}
}
}
function getXHR () {
return window.XMLHttpRequest ? new window.XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')
}
'use strict'
var _$OptionsValidator_3 = function OptionsValidator (params) {
if (!validateParams(params)) {
throw new Error('-- OptionsValidator: required options missing')
}
if (!(this instanceof OptionsValidator)) {
return new OptionsValidator(params)
}
const requiredOptions = params.required
this.getRequiredOptions = function () {
return requiredOptions
}
this.validate = function (parameters) {
const errors = []
requiredOptions.forEach(function (requiredOptionName) {
if (typeof parameters[requiredOptionName] === 'undefined') {
errors.push(requiredOptionName)
}
})
return errors
}
function validateParams (params) {
if (!params) {
return false
}
return typeof params.required !== 'undefined' && params.required instanceof Array
}
}
'use strict'
var _$utils_9 = {
merge: merge,
isJSON: isJSON
}
function merge (defaultParams, mergeParams) {
const mergedOptions = {}
for (const option in defaultParams) {
mergedOptions[option] = defaultParams[option]
if (typeof mergeParams[option] !== 'undefined') {
mergedOptions[option] = mergeParams[option]
}
}
return mergedOptions
}
function isJSON (json) {
try {
if (json instanceof Object && JSON.parse(JSON.stringify(json))) {
return true
}
return false
} catch (err) {
return false
}
}
var _$src_8 = {};
(function (window) {
'use strict'
let options = {
searchInput: null,
resultsContainer: null,
json: [],
success: Function.prototype,
searchResultTemplate: '<li><a href="{url}" title="{desc}">{title}</a></li>',
templateMiddleware: Function.prototype,
sortMiddleware: function () {
return 0
},
noResultsText: 'No results found',
limit: 10,
fuzzy: false,
debounceTime: null,
exclude: []
}
let debounceTimerHandle
const debounce = function (func, delayMillis) {
if (delayMillis) {
clearTimeout(debounceTimerHandle)
debounceTimerHandle = setTimeout(func, delayMillis)
} else {
func.call()
}
}
const requiredOptions = ['searchInput', 'resultsContainer', 'json']
/* removed: const _$Templater_7 = require('./Templater') */;
/* removed: const _$Repository_4 = require('./Repository') */;
/* removed: const _$JSONLoader_2 = require('./JSONLoader') */;
const optionsValidator = _$OptionsValidator_3({
required: requiredOptions
})
/* removed: const _$utils_9 = require('./utils') */;
window.SimpleJekyllSearch = function (_options) {
const errors = optionsValidator.validate(_options)
if (errors.length > 0) {
throwError('You must specify the following required options: ' + requiredOptions)
}
options = _$utils_9.merge(options, _options)
_$Templater_7.setOptions({
template: options.searchResultTemplate,
middleware: options.templateMiddleware
})
_$Repository_4.setOptions({
fuzzy: options.fuzzy,
limit: options.limit,
sort: options.sortMiddleware,
exclude: options.exclude
})
if (_$utils_9.isJSON(options.json)) {
initWithJSON(options.json)
} else {
initWithURL(options.json)
}
const rv = {
search: search
}
typeof options.success === 'function' && options.success.call(rv)
return rv
}
function initWithJSON (json) {
_$Repository_4.put(json)
registerInput()
}
function initWithURL (url) {
_$JSONLoader_2.load(url, function (err, json) {
if (err) {
throwError('failed to get JSON (' + url + ')')
}
initWithJSON(json)
})
}
function emptyResultsContainer () {
options.resultsContainer.innerHTML = ''
}
function appendToResultsContainer (text) {
options.resultsContainer.innerHTML += text
}
function registerInput () {
options.searchInput.addEventListener('input', function (e) {
if (isWhitelistedKey(e.which)) {
emptyResultsContainer()
debounce(function () { search(e.target.value) }, options.debounceTime)
}
})
}
function search (query) {
if (isValidQuery(query)) {
emptyResultsContainer()
render(_$Repository_4.search(query), query)
}
}
function render (results, query) {
const len = results.length
if (len === 0) {
return appendToResultsContainer(options.noResultsText)
}
for (let i = 0; i < len; i++) {
results[i].query = query
appendToResultsContainer(_$Templater_7.compile(results[i]))
}
}
function isValidQuery (query) {
return query && query.length > 0
}
function isWhitelistedKey (key) {
return [13, 16, 20, 37, 38, 39, 40, 91].indexOf(key) === -1
}
function throwError (message) {
throw new Error('SimpleJekyllSearch --- ' + message)
}
})(window)
}());
</script>
<!-- Configuration -->
<script>
SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
noResultsText: '<p>Aucun résultat!</p>',
json: '/search.json',
searchResultTemplate: '<li><a href="{url}">{date}&nbsp;{title}</a>&nbsp;(Création {create})</li>'
})
</script>
</div></div>
<script>(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function scrollToAnchor(anchor, duration, callback) {
var $root = this;
$root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
callback && callback();
});
}
$.fn.scrollToAnchor = scrollToAnchor;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function affix(options) {
var $root = this, $window = $(window), $scrollTarget, $scroll,
offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
hasInit = false, curState;
function setOptions(options) {
var _options = options || {};
_options.offsetBottom && (offsetBottom = _options.offsetBottom);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroll && (scroll = _options.scroll);
_options.disabled !== undefined && (disabled = _options.disabled);
$scrollTarget = $(scrollTarget);
isOverallScroller = window.isOverallScroller($scrollTarget[0]);
$scroll = $(scroll);
}
function preCalc() {
top();
rootHeight = $root.outerHeight();
rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
rootLeft = $root.offset().left;
}
function calc(needPreCalc) {
needPreCalc && preCalc();
scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
rootBottomTop = scrollBottom - rootTop;
}
function top() {
if (curState !== 'top') {
$root.removeClass('fixed').css({
left: 0,
top: 0
});
curState = 'top';
}
}
function fixed() {
if (curState !== 'fixed') {
$root.addClass('fixed').css({
left: rootLeft + 'px',
top: 0
});
curState = 'fixed';
}
}
function bottom() {
if (curState !== 'bottom') {
$root.removeClass('fixed').css({
left: 0,
top: rootBottomTop + 'px'
});
curState = 'bottom';
}
}
function setState() {
var scrollTop = $scrollTarget.scrollTop();
if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
fixed();
} else if (scrollTop < rootTop) {
top();
} else {
bottom();
}
}
function init() {
if(!hasInit) {
var interval, timeout;
calc(true); setState();
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState();
});
$window.on('resize', function() {
disabled || (calc(true), setState());
});
hasInit = true;
}
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions,
refresh: function() {
calc(true, { animation: false }); setState();
}
};
}
$.fn.affix = affix;
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
function toc(options) {
var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
headingsPos, scrolling = false, hasRendered = false, hasInit = false;
function setOptions(options) {
var _options = options || {};
_options.selectors && (selectors = _options.selectors);
_options.container && (container = _options.container);
_options.scrollTarget && (scrollTarget = _options.scrollTarget);
_options.scroller && (scroller = _options.scroller);
_options.disabled !== undefined && (disabled = _options.disabled);
$headings = $(container).find(selectors).filter('[id]');
$scrollTarget = $(scrollTarget);
$scroller = $(scroller);
}
function calc() {
headingsPos = [];
$headings.each(function() {
headingsPos.push(Math.floor($(this).position().top));
});
}
function setState(element, disabled) {
var scrollTop = $scrollTarget.scrollTop(), i;
if (disabled || !headingsPos || headingsPos.length < 1) { return; }
if (element) {
$activeCur = element;
} else {
for (i = 0; i < headingsPos.length; i++) {
if (scrollTop >= headingsPos[i]) {
$activeCur = $tocLi.eq(i);
} else {
$activeCur || ($activeCur = $tocLi.eq(i));
break;
}
}
}
$activeLast && $activeLast.removeClass('active');
($activeLast = $activeCur).addClass('active');
}
function render() {
if(!hasRendered) {
$root.append($tocUl);
$headings.each(function() {
var $this = $(this);
$tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
.append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
});
$tocLi = $tocUl.children('li');
$tocUl.on('click', 'a', function(e) {
e.preventDefault();
var $this = $(this);
scrolling = true;
setState($this.parent());
$scroller.scrollToAnchor($this.attr('href'), 400, function() {
scrolling = false;
});
});
}
hasRendered = true;
}
function init() {
var interval, timeout;
if(!hasInit) {
render(); calc(); setState(null, scrolling);
// run calc every 100 millisecond
interval = setInterval(function() {
calc();
}, 100);
timeout = setTimeout(function() {
clearInterval(interval);
}, 45000);
window.pageLoad.then(function() {
setTimeout(function() {
clearInterval(interval);
clearTimeout(timeout);
}, 3000);
});
$scrollTarget.on('scroll', function() {
disabled || setState(null, scrolling);
});
$window.on('resize', window.throttle(function() {
if (!disabled) {
render(); calc(); setState(null, scrolling);
}
}, 100));
}
hasInit = true;
}
setOptions(options);
if (!disabled) {
init();
}
$window.on('resize', window.throttle(function() {
init();
}, 200));
return {
setOptions: setOptions
};
}
$.fn.toc = toc;
});
})();
/*(function () {
})();*/
</script><script>
/* toc must before affix, since affix need to konw toc' height. */(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window);
var $articleContent = $('.js-article-content');
var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
var toc;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
function disabled() {
return $col2.css('display') === 'none' || !hasToc;
}
tocDisabled = disabled();
toc = $tocRoot.toc({
selectors: TOC_SELECTOR,
container: $articleContent,
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
tocDisabled = disabled();
toc && toc.setOptions({
disabled: tocDisabled
});
}, 100));
});
})();
(function() {
var SOURCES = window.TEXT_VARIABLES.sources;
window.Lazyload.js(SOURCES.jquery, function() {
var $window = $(window), $pageFooter = $('.js-page-footer');
var $pageAside = $('.js-page-aside');
var affix;
var tocDisabled = false;
var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
affix = $pageAside.affix({
offsetBottom: $pageFooter.outerHeight(),
scrollTarget: hasSidebar ? '.js-page-main' : null,
scroller: hasSidebar ? '.js-page-main' : null,
scroll: hasSidebar ? $('.js-page-main').children() : null,
disabled: tocDisabled
});
$window.on('resize', window.throttle(function() {
affix && affix.setOptions({
disabled: tocDisabled
});
}, 100));
window.pageAsideAffix = affix;
});
})();
</script><!---->
</div>
<script>(function () {
var $root = document.getElementsByClassName('root')[0];
if (window.hasEvent('touchstart')) {
$root.dataset.isTouch = true;
document.addEventListener('touchstart', function(){}, false);
}
})();
</script>
</body>
</html>