mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 06:03:34 +01:00
Added docs and search. (#6273)
* Added docs and search. * Fixed pull request runs.
This commit is contained in:
parent
6def26b2f0
commit
abfadd493c
8 changed files with 253 additions and 56 deletions
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
|
@ -6,6 +6,8 @@ on:
|
|||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [develop]
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
schedule:
|
||||
- cron: '0 13 * * 1'
|
||||
|
||||
|
|
2
.github/workflows/docker.yml
vendored
2
.github/workflows/docker.yml
vendored
|
@ -1,6 +1,8 @@
|
|||
name: Docker
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'doc/**'
|
||||
push:
|
||||
branches:
|
||||
- 'develop'
|
||||
|
|
34
.github/workflows/lint-package-lock.yml
vendored
34
.github/workflows/lint-package-lock.yml
vendored
|
@ -1,34 +0,0 @@
|
|||
name: "Lint"
|
||||
|
||||
# any branch is useful for testing before a PR is submitted
|
||||
on: [push, pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint-package-lock:
|
||||
# run on pushes to any branch
|
||||
# run on PRs from external forks
|
||||
if: |
|
||||
(github.event_name != 'pull_request')
|
||||
|| (github.event.pull_request.head.repo.id != github.event.pull_request.base.repo.id)
|
||||
name: package-lock.json
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
-
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: 20
|
||||
-
|
||||
name: Run lockfile-lint on package-lock.json
|
||||
run: >
|
||||
npx lockfile-lint
|
||||
--path src/package-lock.json
|
||||
--allowed-hosts npm
|
||||
--allowed-schemes https:
|
||||
--allowed-schemes github:
|
||||
--allowed-urls github:mapbox/node-sqlite3#593c9d498be2510d286349134537e3bf89401c4a
|
|
@ -9,6 +9,9 @@ export default defineConfig({
|
|||
description: "Next Generation Collaborative Document Editing",
|
||||
base: '/etherpad-lite/',
|
||||
themeConfig: {
|
||||
search: {
|
||||
provider: 'local'
|
||||
},
|
||||
// https://vitepress.dev/reference/default-theme-config
|
||||
nav: [
|
||||
{ text: 'Home', link: '/' },
|
||||
|
@ -49,8 +52,8 @@ export default defineConfig({
|
|||
{
|
||||
text: 'Old Docs',
|
||||
items: [
|
||||
{ text: 'Easysync description', link: '/easysync/easysync-full-description.pdf' },
|
||||
{ text: 'Easysync notes', link: '/easysync/easysync-notes.pdf' }
|
||||
{ text: 'Easysync description', link: '/etherpad-lite/easysync/easysync-full-description.pdf' },
|
||||
{ text: 'Easysync notes', link: '/etherpad-lite/easysync/easysync-notes.pdf' }
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
# Editbar
|
||||
src/static/js/pad_editbar.js
|
||||
|
||||
Located in `src/static/js/pad_editbar.js`
|
||||
|
||||
## isEnabled()
|
||||
|
||||
If the editorbar contains the class `enabledtoolbar`, it is enabled.
|
||||
|
||||
|
||||
## disable()
|
||||
|
||||
Disables the editorbar. This is done by adding the class `disabledtoolbar` and removing the enabledtoolbar
|
||||
|
||||
## toggleDropDown(dropdown)
|
||||
|
||||
Shows the dropdown `div.popup` whose `id` equals `dropdown`.
|
||||
|
||||
## registerCommand(cmd, callback)
|
||||
|
||||
Register a handler for a specific command. Commands are fired if the corresponding button is clicked or the corresponding select is changed.
|
||||
|
||||
## registerAceCommand(cmd, callback)
|
||||
|
|
|
@ -1,43 +1,141 @@
|
|||
# editorInfo
|
||||
# EditorInfo
|
||||
|
||||
Location: `src/static/js/ace2_inner.js`
|
||||
|
||||
## editorInfo.ace_replaceRange(start, end, text)
|
||||
This function replaces a range (from `start` to `end`) with `text`.
|
||||
|
||||
## editorInfo.ace_getRep()
|
||||
Returns the `rep` object.
|
||||
|
||||
Returns the `rep` object. The rep object consists of the following properties:
|
||||
|
||||
- `lines`: Implemented as a skip list
|
||||
- `selStart`: The start of the selection
|
||||
- `selEnd`: The end of the selection
|
||||
- `selFocusAtStart`: Whether the selection is focused at the start
|
||||
- `alltext`: The entire text of the document
|
||||
- `alines`: The entire text of the document, split into lines
|
||||
- `apool`: The pool of attributes
|
||||
|
||||
## editorInfo.ace_getAuthor()
|
||||
|
||||
Returns the authors of the pad. If the pad has no authors, it returns an empty object.
|
||||
|
||||
|
||||
## editorInfo.ace_inCallStack()
|
||||
|
||||
Returns true if the editor is in the call stack.
|
||||
|
||||
## editorInfo.ace_inCallStackIfNecessary(?)
|
||||
|
||||
Executes the function if the editor is in the call stack.
|
||||
|
||||
## editorInfo.ace_focus(?)
|
||||
|
||||
Focuses the editor.
|
||||
|
||||
## editorInfo.ace_importText(?)
|
||||
|
||||
Imports text into the editor.
|
||||
|
||||
## editorInfo.ace_importAText(?)
|
||||
|
||||
Imports text and attributes into the editor.
|
||||
|
||||
## editorInfo.ace_exportText(?)
|
||||
|
||||
Exports the text from the editor.
|
||||
|
||||
## editorInfo.ace_editorChangedSize(?)
|
||||
|
||||
Changes the size of the editor.
|
||||
|
||||
## editorInfo.ace_setOnKeyPress(?)
|
||||
|
||||
Sets the key press event.
|
||||
|
||||
## editorInfo.ace_setOnKeyDown(?)
|
||||
|
||||
Sets the key down event.
|
||||
|
||||
## editorInfo.ace_setNotifyDirty(?)
|
||||
|
||||
Sets the dirty notification.
|
||||
|
||||
## editorInfo.ace_dispose(?)
|
||||
|
||||
Disposes the editor.
|
||||
|
||||
## editorInfo.ace_setEditable(bool)
|
||||
|
||||
Sets the editor to be editable or not.
|
||||
|
||||
## editorInfo.ace_execCommand(?)
|
||||
|
||||
Executes a command.
|
||||
|
||||
## editorInfo.ace_callWithAce(fn, callStack, normalize)
|
||||
|
||||
Calls a function with the ace instance.
|
||||
|
||||
## editorInfo.ace_setProperty(key, value)
|
||||
|
||||
Sets a property.
|
||||
|
||||
## editorInfo.ace_setBaseText(txt)
|
||||
|
||||
Sets the base text.
|
||||
|
||||
## editorInfo.ace_setBaseAttributedText(atxt, apoolJsonObj)
|
||||
|
||||
Sets the base attributed text.
|
||||
|
||||
## editorInfo.ace_applyChangesToBase(c, optAuthor, apoolJsonObj)
|
||||
|
||||
Applies changes to the base.
|
||||
|
||||
## editorInfo.ace_prepareUserChangeset()
|
||||
|
||||
Prepares the user changeset.
|
||||
|
||||
## editorInfo.ace_applyPreparedChangesetToBase()
|
||||
|
||||
Applies the prepared changeset to the base.
|
||||
|
||||
## editorInfo.ace_setUserChangeNotificationCallback(f)
|
||||
|
||||
Sets the user change notification callback.
|
||||
|
||||
## editorInfo.ace_setAuthorInfo(author, info)
|
||||
|
||||
Sets the author info.
|
||||
|
||||
## editorInfo.ace_fastIncorp(?)
|
||||
|
||||
Incorporates changes quickly.
|
||||
|
||||
## editorInfo.ace_isCaret(?)
|
||||
|
||||
Returns true if the caret is at the specified position.
|
||||
|
||||
## editorInfo.ace_getLineAndCharForPoint(?)
|
||||
|
||||
Returns the line and character for a point.
|
||||
|
||||
## editorInfo.ace_performDocumentApplyAttributesToCharRange(?)
|
||||
|
||||
Applies attributes to a character range.
|
||||
|
||||
## editorInfo.ace_setAttributeOnSelection(attribute, enabled)
|
||||
|
||||
Sets an attribute on current range.
|
||||
Example: `call.editorInfo.ace_setAttributeOnSelection("turkey::balls", true); // turkey is the attribute here, balls is the value
|
||||
Notes: to remove the attribute pass enabled as false
|
||||
|
||||
## editorInfo.ace_toggleAttributeOnSelection(?)
|
||||
|
||||
Toggles an attribute on the current range.
|
||||
|
||||
## editorInfo.ace_getAttributeOnSelection(attribute, prevChar)
|
||||
Returns a boolean if an attribute exists on a selected range.
|
||||
prevChar value should be true if you want to get the previous Character attribute instead of the current selection for example
|
||||
|
@ -48,32 +146,63 @@ Example `var isItThere = documentAttributeManager.getAttributeOnSelection("turke
|
|||
|
||||
See the ep_subscript plugin for an example of this function in action.
|
||||
Notes: Does not work on first or last character of a line. Suffers from a race condition if called with aceEditEvent.
|
||||
|
||||
## editorInfo.ace_performSelectionChange(?)
|
||||
|
||||
Performs a selection change.
|
||||
|
||||
## editorInfo.ace_doIndentOutdent(?)
|
||||
|
||||
Indents or outdents the selection.
|
||||
|
||||
## editorInfo.ace_doUndoRedo(?)
|
||||
|
||||
Undoes or redoes the last action.
|
||||
|
||||
## editorInfo.ace_doInsertUnorderedList(?)
|
||||
|
||||
Inserts an unordered list.
|
||||
|
||||
## editorInfo.ace_doInsertOrderedList(?)
|
||||
|
||||
Inserts an ordered list.
|
||||
|
||||
## editorInfo.ace_performDocumentApplyAttributesToRange()
|
||||
|
||||
Applies attributes to a range.
|
||||
|
||||
## editorInfo.ace_getAuthorInfos()
|
||||
Returns an info object about the author. Object key = author_id and info includes author's bg color value.
|
||||
Use to define your own authorship.
|
||||
|
||||
## editorInfo.ace_performDocumentReplaceRange(start, end, newText)
|
||||
This function replaces a range (from [x1,y1] to [x2,y2]) with `newText`.
|
||||
|
||||
## editorInfo.ace_performDocumentReplaceCharRange(startChar, endChar, newText)
|
||||
This function replaces a range (from y1 to y2) with `newText`.
|
||||
|
||||
## editorInfo.ace_renumberList(lineNum)
|
||||
If you delete a line, calling this method will fix the line numbering.
|
||||
|
||||
## editorInfo.ace_doReturnKey()
|
||||
Forces a return key at the current caret position.
|
||||
|
||||
## editorInfo.ace_isBlockElement(element)
|
||||
Returns true if your passed element is registered as a block element
|
||||
Returns true if your passed element is registered as a block element.
|
||||
|
||||
## editorInfo.ace_getLineListType(lineNum)
|
||||
Returns the line's html list type.
|
||||
|
||||
## editorInfo.ace_caretLine()
|
||||
Returns X position of the caret.
|
||||
|
||||
## editorInfo.ace_caretColumn()
|
||||
Returns Y position of the caret.
|
||||
|
||||
## editorInfo.ace_caretDocChar()
|
||||
|
||||
Returns the Y offset starting from [x=0,y=0]
|
||||
|
||||
## editorInfo.ace_isWordChar(?)
|
||||
|
||||
Returns true if the character is a word character.
|
||||
|
|
|
@ -485,7 +485,7 @@ You can pass the following values to the provided callback:
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.authorize = (hookName, context, cb) => {
|
||||
const user = context.req.session.user;
|
||||
const path = context.req.path; // or context.resource
|
||||
|
@ -533,7 +533,7 @@ object should come from global settings (`context.users[username]`).
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.authenticate = (hook_name, context, cb) => {
|
||||
if (notApplicableToThisPlugin(context)) {
|
||||
return cb([]); // Let the next authentication plugin decide
|
||||
|
@ -587,7 +587,7 @@ failure or a generic 403 page for an authorization failure).
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.authFailure = (hookName, context, cb) => {
|
||||
if (notApplicableToThisPlugin(context)) {
|
||||
return cb([]); // Let the next plugin handle the error
|
||||
|
@ -618,7 +618,7 @@ another plugin (if any, otherwise fall back to a generic 403 error page).
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.preAuthzFailure = (hookName, context, cb) => {
|
||||
if (notApplicableToThisPlugin(context)) return cb([]);
|
||||
context.res.status(403).send(renderFancy403Page(context.req));
|
||||
|
@ -650,7 +650,7 @@ another plugin (if any, otherwise fall back to the deprecated authFailure hook).
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.authnFailure = (hookName, context, cb) => {
|
||||
if (notApplicableToThisPlugin(context)) return cb([]);
|
||||
context.res.redirect(makeLoginURL(context.req));
|
||||
|
@ -678,7 +678,7 @@ another plugin (if any, otherwise fall back to the deprecated authFailure hook).
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.authzFailure = (hookName, context, cb) => {
|
||||
if (notApplicableToThisPlugin(context)) return cb([]);
|
||||
if (needsPremiumAccount(context.req) && !context.req.session.user.premium) {
|
||||
|
@ -792,7 +792,7 @@ If needed, you can access the user's account information (if authenticated) via
|
|||
|
||||
Examples:
|
||||
|
||||
```
|
||||
```js
|
||||
// Using an async function
|
||||
exports.clientVars = async (hookName, context) => {
|
||||
const user = context.socket.client.request.session.user || {};
|
||||
|
@ -850,7 +850,7 @@ the body of the exported HTML.
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.exportHTMLAdditionalContent = async (hookName, {padId}) => {
|
||||
return 'I am groot in ' + padId;
|
||||
};
|
||||
|
@ -867,7 +867,7 @@ This hook will allow a plug-in developer to append Styles to the Exported HTML.
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.stylesForExport = function(hook, padId, cb){
|
||||
cb("body{font-size:13.37em !important}");
|
||||
}
|
||||
|
@ -885,7 +885,7 @@ or provide an object whose properties will be assigned to the attributes object.
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.aceAttribClasses = (hookName, attrs, cb) => {
|
||||
return cb([{
|
||||
sub: 'tag:sub',
|
||||
|
@ -904,7 +904,7 @@ This hook will allow a plug-in developer to modify the file name of an exported
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
exports.exportFileName = function(hook, padId, callback){
|
||||
callback("newFileName"+padId);
|
||||
}
|
||||
|
@ -920,7 +920,7 @@ Things in context:
|
|||
This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. If tags are stored as `['color', 'red']` on the attribute pool, use `exportHtmlAdditionalTagsWithData` instead. An Array should be returned.
|
||||
|
||||
Example:
|
||||
```
|
||||
```js
|
||||
// Add the props to be supported in export
|
||||
exports.exportHtmlAdditionalTags = function(hook, pad, cb){
|
||||
var padId = pad.id;
|
||||
|
@ -938,7 +938,7 @@ Things in context:
|
|||
Identical to `exportHtmlAdditionalTags`, but for tags that are stored with a specific value (not simply `true`) on the attribute pool. For example `['color', 'red']`, instead of `['bold', true]`. This hook will allow a plug-in developer to include more properties and attributes to support during HTML Export. An Array of arrays should be returned. The exported HTML will contain tags like `<span data-color="red">` for the content where attributes are `['color', 'red']`.
|
||||
|
||||
Example:
|
||||
```
|
||||
```js
|
||||
// Add the props to be supported in export
|
||||
exports.exportHtmlAdditionalTagsWithData = function(hook, pad, cb){
|
||||
var padId = pad.id;
|
||||
|
@ -962,7 +962,7 @@ Context properties: None.
|
|||
|
||||
Example:
|
||||
|
||||
```
|
||||
```js
|
||||
// Add support for exporting comments metadata
|
||||
exports.exportEtherpadAdditionalContent = () => ['comments'];
|
||||
```
|
||||
|
|
|
@ -204,7 +204,6 @@ For the editor container, you can also make it full width by adding `full-width-
|
|||
| `MAX_AGE` | How long may clients use served javascript code (in seconds)? Not setting this may cause problems during deployment. Set to 0 to disable caching. | `21600` (6 hours) |
|
||||
| `ABIWORD` | Absolute path to the Abiword executable. Abiword is needed to get advanced import/export features of pads. Setting it to null disables Abiword and will only allow plain text and HTML import/exports. | `null` |
|
||||
| `SOFFICE` | This is the absolute path to the soffice executable. LibreOffice can be used in lieu of Abiword to export pads. Setting it to null disables LibreOffice exporting. | `null` |
|
||||
| `TIDY_HTML` | Path to the Tidy executable. Tidy is used to improve the quality of exported pads. Setting it to null disables Tidy. | `null` |
|
||||
| `ALLOW_UNKNOWN_FILE_ENDS` | Allow import of file types other than the supported ones: txt, doc, docx, rtf, odt, html & htm | `true` |
|
||||
| `REQUIRE_AUTHENTICATION` | This setting is used if you require authentication of all users. Note: "/admin" always requires authentication. | `false` |
|
||||
| `REQUIRE_AUTHORIZATION` | Require authorization by a module, or a user with is_admin set, see below. | `false` |
|
||||
|
@ -219,6 +218,24 @@ For the editor container, you can also make it full width by adding `full-width-
|
|||
| `DUMP_ON_UNCLEAN_EXIT` | Enable dumping objects preventing a clean exit of Node.js. WARNING: this has a significant performance impact. | `false` |
|
||||
| `EXPOSE_VERSION` | Expose Etherpad version in the web interface and in the Server http header. Do not enable on production machines. | `false` |
|
||||
|
||||
### Add plugin configurations
|
||||
|
||||
It is possible to add arbitrary configurations for plugins by setting the `EP__PLUGIN__<PLUGIN_NAME>__<CONFIG_NAME>` environment variable. It is important to separate paths with a double underscore `__`.
|
||||
|
||||
For example, to configure the `ep_comments` plugin to use the `comments` database, you can set the following environment variables:
|
||||
|
||||
The original config looks like this:
|
||||
```json
|
||||
"ep_comments_page": {
|
||||
"highlightSelectedText": true
|
||||
},
|
||||
```
|
||||
We have two paths ep_comments_page and highlightSelectedText, so we need to set the following environment variable:
|
||||
|
||||
|
||||
```yaml
|
||||
EP__ep_comments_page__highlightSelectedText=true
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
|
@ -249,9 +266,79 @@ docker run -d \
|
|||
|
||||
Run a test instance running DirtyDB on a persistent volume:
|
||||
|
||||
```
|
||||
```shell
|
||||
docker run -d \
|
||||
-v etherpad_data:/opt/etherpad-lite/var \
|
||||
-p 9001:9001 \
|
||||
etherpad/etherpad
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Ready to use Docker Compose
|
||||
|
||||
```yaml
|
||||
version: "3.8"
|
||||
|
||||
# Add this file to extend the docker-compose setup, e.g.:
|
||||
# docker-compose build --no-cache
|
||||
# docker-compose up -d --build --force-recreate
|
||||
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
ETHERPAD_PLUGINS:
|
||||
# change from development to production if needed
|
||||
target: development
|
||||
tty: true
|
||||
stdin_open: true
|
||||
volumes:
|
||||
# no volume mapping of node_modules as otherwise the build-time installed plugins will be overwritten with the mount
|
||||
# the same applies to package.json and pnpm-lock.yaml in root dir as these would also get overwritten and build time installed plugins will be removed
|
||||
- ./src:/opt/etherpad-lite/src
|
||||
- ./bin:/opt/etherpad-lite/bin
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
# change from development to production if needed
|
||||
NODE_ENV: development
|
||||
ADMIN_PASSWORD: ${DOCKER_COMPOSE_APP_DEV_ADMIN_PASSWORD}
|
||||
DB_CHARSET: ${DOCKER_COMPOSE_APP_DEV_ENV_DB_CHARSET:-utf8mb4}
|
||||
DB_HOST: postgres
|
||||
DB_NAME: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_DATABASE:?}
|
||||
DB_PASS: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_PASSWORD:?}
|
||||
DB_PORT: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_PORT:-5432}
|
||||
DB_TYPE: "postgres"
|
||||
DB_USER: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_USER:?}
|
||||
# For now, the env var DEFAULT_PAD_TEXT cannot be unset or empty; it seems to be mandatory in the latest version of etherpad
|
||||
DEFAULT_PAD_TEXT: ${DOCKER_COMPOSE_APP_DEV_ENV_DEFAULT_PAD_TEXT:- }
|
||||
DISABLE_IP_LOGGING: ${DOCKER_COMPOSE_APP_DEV_ENV_DISABLE_IP_LOGGING:-true}
|
||||
SOFFICE: ${DOCKER_COMPOSE_APP_DEV_ENV_SOFFICE:-null}
|
||||
TRUST_PROXY: ${DOCKER_COMPOSE_APP_DEV_ENV_TRUST_PROXY:-true}
|
||||
restart: always
|
||||
ports:
|
||||
- "${DOCKER_COMPOSE_APP_DEV_PORT_PUBLISHED:-9001}:${DOCKER_COMPOSE_APP_DEV_PORT_TARGET:-9001}"
|
||||
|
||||
postgres:
|
||||
image: postgres:15-alpine
|
||||
# Pass config parameters to the mysql server.
|
||||
# Find more information below when you need to generate the ssl-relevant file your self
|
||||
environment:
|
||||
POSTGRES_DB: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_DATABASE:?}
|
||||
POSTGRES_PASSWORD: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_PASSWORD:?}
|
||||
POSTGRES_PORT: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_PORT:-5432}
|
||||
POSTGRES_USER: ${DOCKER_COMPOSE_POSTGRES_DEV_ENV_POSTGRES_USER:?}
|
||||
PGDATA: /var/lib/postgresql/data/pgdata
|
||||
restart: always
|
||||
# Exposing the port is not needed unless you want to access this database instance from the host.
|
||||
# Be careful when other postgres docker container are running on the same port
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data/pgdata
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue