mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-12-23 02:26:36 +00:00
Remove the docs folder (#371)
Since documentation now has its own repo. I also modified a bit the dockerfile to make the image lighter.
This commit is contained in:
parent
5c5cf36b0d
commit
5a682419cb
14 changed files with 1 additions and 1178 deletions
|
@ -16,6 +16,6 @@ RUN cargo install diesel_cli --no-default-features --features postgres --version
|
|||
COPY . .
|
||||
RUN cargo install --path ./ --force --no-default-features --features postgres
|
||||
RUN cargo install --path plume-cli --force --no-default-features --features postgres
|
||||
RUN rm -rf target/release/incremental
|
||||
RUN cargo clean
|
||||
CMD ["plume"]
|
||||
EXPOSE 7878
|
||||
|
|
48
docs/API.md
48
docs/API.md
|
@ -1,48 +0,0 @@
|
|||
# API documentation
|
||||
|
||||
## Getting an API token
|
||||
|
||||
To get access to the API, you should register your app and obtain a
|
||||
token. To do so, use the `/api/v1/apps` API (accessible without a token) to create
|
||||
a new app. Store the result somewhere for future use.
|
||||
|
||||
Then send a request to `/api/v1/oauth2`, with the following GET parameters:
|
||||
|
||||
- `client_id`, your client ID.
|
||||
- `client_secret`, your client secret.
|
||||
- `scopes`, the scopes you want to access. They are separated by `+`, and can either
|
||||
be `read` (global read), `write` (global write), `read:SCOPE` (read only in `SCOPE`),
|
||||
or `write:SCOPE` (write only in `SCOPE`).
|
||||
- `username` the username (not the email, display name nor the fully qualified name) of the
|
||||
user using your app.
|
||||
- `password`, the password of the user.
|
||||
|
||||
Plume will respond with something similar to:
|
||||
|
||||
```json
|
||||
{
|
||||
"token": "<YOUR TOKEN HERE>"
|
||||
}
|
||||
```
|
||||
|
||||
To authenticate your requests you should put this token in the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer <YOUR TOKEN HERE>
|
||||
```
|
||||
|
||||
<script src="//unpkg.com/swagger-ui-dist@3/swagger-ui-bundle.js"></script>
|
||||
|
||||
<div id="api"></div>
|
||||
|
||||
<script>
|
||||
const ui = SwaggerUIBundle({
|
||||
url: "/Plume/api.yaml",
|
||||
dom_id: '#api',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "StandaloneLayout"
|
||||
})
|
||||
</script>
|
99
docs/CLI.md
99
docs/CLI.md
|
@ -1,99 +0,0 @@
|
|||
# `plm` CLI reference
|
||||
|
||||
If any required argument is ommitted, you will be asked to input manually.
|
||||
|
||||
## `plm instance`
|
||||
|
||||
Manage instances.
|
||||
|
||||
### `plm instance new`
|
||||
|
||||
Create a new local instance.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
plm instance new --private --domain plu.me --name 'My Plume Instance' -l 'CC-BY'
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--domain`, `-d`: the domain name on which your instance will be available.
|
||||
- `--name`, `-n`: The name of your instance. It will be displayed on the homepage.
|
||||
- `--default-license`, `-l`: the license to use for articles written on this instance, if no other license is explicitely specified. Optional, defaults to CC-BY-SA.
|
||||
- `--private`, `-p`: if this argument is present, registering on this instance won't be possible. Optional, off by default.
|
||||
|
||||
**Environment variables:**
|
||||
|
||||
- `BASE_URL` will be used as a fallback if `--domain` is not specified.
|
||||
|
||||
## `plm users`
|
||||
|
||||
Manage users.
|
||||
|
||||
### `plm users new`
|
||||
|
||||
Creates a new user on this instance.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
plm users new --admin -n 'kate' -N 'Kate' --bio "I'm Kate." --email 'kate@plu.me'
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--name`, `--username`, `-n`: the name of this user. It will be used an human-readable identifier in URLs, for federation and when mentioning this person. It can't be changed afterwards.
|
||||
- `--display-name`, `-N`: the display name of this user, that will be shown everywhere on the interface.
|
||||
- `--bio`, `--biography`, `-b`: the biography of the user. Optional, empty by default.
|
||||
- `--email`, `-e`: the email adress of the user.
|
||||
- `--password`, `-p`: the password of the user. You probably want to use this option in shell scipts only, since if you don't specify it, the prompt won't show your password.
|
||||
- `--admin`, `-a`: makes the user an admin of the instance. Optional, off by default.
|
||||
|
||||
## `plm search`
|
||||
|
||||
Manage full text search index.
|
||||
|
||||
### `plm search init`
|
||||
|
||||
Initialize the search index.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
plm search init -p Plume'
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--path`, `-n`: path to plume working directory.
|
||||
- `--force`, `-f`: override any already existing search index.
|
||||
|
||||
### `plm search refill`
|
||||
|
||||
Refill the search index.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
plm search refill -p Plume'
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--path`, `-n`: path to plume working directory.
|
||||
|
||||
### `plm search unlock`
|
||||
|
||||
Remove lock on the search index, after abnormal termination such as power loss.
|
||||
Only do this if you know no processus is currently using the index.
|
||||
|
||||
**Example:**
|
||||
|
||||
```bash
|
||||
plm search unlock -p Plume'
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `--path`, `-n`: path to plume working directory.
|
|
@ -1,90 +0,0 @@
|
|||
# Development Guide
|
||||
|
||||
## Installing the development environment
|
||||
|
||||
Please refer to the [installation guide](INSTALL.md).
|
||||
|
||||
## Testing the federation
|
||||
|
||||
To test the federation, you'll need to setup another database (see "Setup the database"),
|
||||
also owned by the "plume" user, but with a different name. Then, you'll need to run the
|
||||
migrations for this database too.
|
||||
|
||||
```
|
||||
diesel migration run --database-url postgres://plume:plume@localhost/my_other_plume_db
|
||||
```
|
||||
|
||||
To run this other instance, you'll need to give two environment variables:
|
||||
|
||||
- `ROCKET_PORT`, the port on which your app will run
|
||||
- `DB_NAME`, the name of the database you just created
|
||||
|
||||
```
|
||||
ROCKET_PORT=3033 DB_NAME=my_other_plume_db cargo run
|
||||
```
|
||||
|
||||
If you don't want to setup HTTPS locally, you can also disable it by running your instance with `USE_HTTPS=0` set.
|
||||
|
||||
```
|
||||
USE_HTTPS=0 cargo run
|
||||
```
|
||||
|
||||
## Making a Pull Request
|
||||
To create an upstream fork of the repository in GitHub, click "Fork" in the top right button on the main page of the [Plume repository](https://github.com/Plume-org/Plume). Now, in the command line, set another remote for the repository by running the following command, replacing `myname` with the name under which you forked the repo. You can use another name besides `upstream` if you prefer. Using [SSH](https://help.github.com/articles/connecting-to-github-with-ssh/) is recommended.
|
||||
|
||||
```
|
||||
git remote add upstream git@github.com/myname/Plume.git
|
||||
# Alt # git remote add upstream https://github.com/myname/Plume.git
|
||||
```
|
||||
|
||||
Now, make any changes to the code you want. After committing your changes, push to the upstream fork. Once your changes are made, visit the GitHub page for your fork and select "New pull request". Add descriptive text, any issue numbers using hashtags to reference the issue number, screenshots of your changes if relevant, a description of how you tested your changes, and any other information that will help the project maintainers be able to quickly accept your pull requests.
|
||||
|
||||
The project maintainers may suggest further changes to improve the pull request even more. After implementing this locally, you can push to your upstream fork again and the changes will immediately show up in the pull request after pushing. Once all the suggested changes are made, the pull request may be accepted. Thanks for contributing.
|
||||
|
||||
## When working with Ructe templates
|
||||
|
||||
When working with the interface, or any message that will be displayed to the final user,
|
||||
keep in mind that Plume is an internationalized software.
|
||||
To make sure that the parts of the interface you are changing are translatable, you should:
|
||||
|
||||
- Wrap strings to translate in the `i18n!` macro (see [rocket_i18n docs](https://docs.rs/rocket_i18n/)
|
||||
for more details about its arguments).The `Catalog` argument is usually `ctx.1`.
|
||||
- Add the strings to translate to the `po/plume.pot` file
|
||||
|
||||
Here is an example: let's say we want to add two strings, a simple one and one
|
||||
that may deal with plurals. The first step is to add them to whatever
|
||||
template we want to display them in:
|
||||
|
||||
```html
|
||||
<p>@i18n!(ctx.1, "Hello, world!")</p>
|
||||
|
||||
<p>@i18n!(ctx.1, "You have one new notification", "You have {0} new notifications", n_notifications)</p>
|
||||
```
|
||||
|
||||
The second step is to add them to POT file. To add a simple message, just do:
|
||||
|
||||
```po
|
||||
msgid "Hello, world" # The string you used with your filter
|
||||
msgstr "" # Always empty
|
||||
```
|
||||
|
||||
For plural forms, the syntax is a bit different:
|
||||
|
||||
```po
|
||||
msgid "You have one new notification" # The singular form
|
||||
msgid_plural "You have {0} new notifications" # The plural one
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
```
|
||||
|
||||
And that's it! Once these new messages will have been translated, they will correctly be displayed in the requested locale!
|
||||
|
||||
## Code Style
|
||||
|
||||
For Rust, use the standard style. `rustfmt` can help you keeping your code clean.
|
||||
|
||||
For CSS, the only rule is to use One True Brace Style.
|
||||
|
||||
For JavaScript, we use [the JavaScript Standard Style](https://standardjs.com/).
|
||||
|
||||
For HTML/Ructe templates, we use HTML5 syntax.
|
|
@ -1,21 +0,0 @@
|
|||
# Useful Environment Variables
|
||||
|
||||
Plume relies on some environment variables for some configuration options. You can either set them before
|
||||
starting the app with `cargo run` or write them in a `.env` file to have automatically loaded.
|
||||
|
||||
Here are the variables that Plume uses:
|
||||
|
||||
- `BASE_URL`: the domain name, or IP and port on which Plume is listening. It is used in all federation-related code.
|
||||
- `DATABASE_URL`: the URL of the PostgreSQL database, used by Plume (`postgres://plume:plume@localhost/plume` by default with PostgreSQL, `plume.db` with SQlite).
|
||||
- `MIGRATION_DIRECTORY`: The folder that stores the migration files for the database, migrations/postgres for PostgreSQL database or migrations/sqlite for SQlite database.
|
||||
- `USE_HTTPS`: if it is `0`, federation and medias will be using HTTP by default (`1` by default).
|
||||
- `ROCKET_ADDRESS`: the adress on which Plume should listen (`0.0.0.0` by default).
|
||||
- `ROCKET_PORT`: the port on which Plume should listen ([`7878` by default](https://twitter.com/ag_dubs/status/852559264510070784))
|
||||
- `ROCKET_SECRET_KEY`: key used to sign private cookies and for CSRF protection. If it is not set, it will be regenerated everytime you restart Plume,
|
||||
meaning that all your users will get disconnected. You can generate one with `openssl rand -base64 32`.
|
||||
|
||||
## Diesel
|
||||
|
||||
Diesel, the tool we use to run migrations may be configured with the `DATABASE_URL` which should contain the URL of the
|
||||
PostgreSQL database. Otherwise, you can specify `--database-url YOUR-URL` everytime you run a `diesel` command.
|
||||
|
|
@ -1,192 +0,0 @@
|
|||
# How Plume Federates
|
||||
|
||||
To federate with other Fediverse software (and itself), Plume uses various
|
||||
protocols:
|
||||
- [ActivityPub](http://activitypub.rocks/), as the main federation protocol.
|
||||
- [WebFinger](https://webfinger.net/), to find other users and blog easily.
|
||||
- [HTTP Signatures](https://tools.ietf.org/id/draft-cavage-http-signatures-01.html), to
|
||||
authenticate activities.
|
||||
- [NodeInfo](http://nodeinfo.diaspora.software/), which is not part of the
|
||||
federation itself, but that gives some metadata about each instance.
|
||||
|
||||
Currently, the following are federated:
|
||||
- User profiles
|
||||
- Blogs
|
||||
- Articles
|
||||
- Comments
|
||||
- Likes
|
||||
- Reshares
|
||||
|
||||
And these parts are not federated, but may be in the future:
|
||||
- Media gallery
|
||||
- Instance metadata
|
||||
|
||||
## WebFinger
|
||||
|
||||
WebFinger is used to discover remote profiles. When you open the page of an unknown
|
||||
user (`/@/username@instance.tld`),
|
||||
Plume will send a WebFinger request to the other instance, on the standard
|
||||
`/.well-known/webfinger` endpoint. Plume
|
||||
will ignore the `/.well-known/host-meta` endpoint (that can normally be used to
|
||||
define another WebFinger endpoint),
|
||||
and always use the standard URL.
|
||||
|
||||
Plume uses the [`webfinger`](https://crates.io/crates/webfinger) crate to serve
|
||||
WebFinger informations and fetch them.
|
||||
|
||||
## HTTP Signatures
|
||||
|
||||
Plume check that each incoming Activity has been signed with the `actor`'s keypair.
|
||||
|
||||
To achieve that, it uses the `Signature` HTTP header. For more details on how this
|
||||
header is generated, please refer to the [HTTP Signatures
|
||||
Specification](https://tools.ietf.org/id/draft-cavage-http-signatures-01.html).
|
||||
|
||||
The `Digest` header should be present too, and used to generate the signature, so
|
||||
that we can verify the body of the request too.
|
||||
|
||||
## NodeInfo
|
||||
|
||||
Plume exposes instance metadata with NodeInfo on the `/nodeinfo` URL.
|
||||
|
||||
*Example output*
|
||||
|
||||
```json
|
||||
{
|
||||
"version": "2.0",
|
||||
"software": {
|
||||
"name": "Plume",
|
||||
"version": "0.2.0"
|
||||
},
|
||||
"protocols": ["activitypub"],
|
||||
"services": {
|
||||
"inbound": [],
|
||||
"outbound": []
|
||||
},
|
||||
"openRegistrations": true,
|
||||
"usage": {
|
||||
"users": {
|
||||
"total": 42
|
||||
},
|
||||
"localPosts": 7878,
|
||||
"localComments": 1312
|
||||
},
|
||||
"metadata": {}
|
||||
}
|
||||
```
|
||||
|
||||
## ActivityPub
|
||||
|
||||
Each user has a personal inbox at `/@/username/inbox`, and each instance has a shared
|
||||
inbox at `/inbox`.
|
||||
|
||||
If available, Plume will use the shared inbox to deliver activities.
|
||||
|
||||
### Object representation
|
||||
|
||||
- `Note` represents a comment.
|
||||
- `Article` is an article.
|
||||
- `Person` is for users.
|
||||
- `Group` is for blogs.
|
||||
|
||||
### Supported Activities
|
||||
|
||||
Plume 0.2.0 supports the following activity types.
|
||||
|
||||
#### Accept
|
||||
|
||||
Accepts a follow request.
|
||||
|
||||
It will be ignored when received, as Plume considered follow requests to be
|
||||
immediatly approved in all cases (however, this will change in the future).
|
||||
|
||||
When a [`Follow`](#follow) activity is received, Plume will respond with this
|
||||
activity.
|
||||
|
||||
- `actor` is the ID of the user accepting the request.
|
||||
- `object` is the `Follow` object being accepted.
|
||||
|
||||
#### Announce
|
||||
|
||||
Reshares an article (not available for other objects).
|
||||
|
||||
Makes an user (`actor`) reshare a post (`object`).
|
||||
- `actor` is the ID of the user who reshared the post.
|
||||
- `object` is the ID of the post to reshare.
|
||||
|
||||
#### Create
|
||||
|
||||
Creates a new article or comment.
|
||||
|
||||
If `object` is an `Article`:
|
||||
- `object.attibutedTo` is a list containing the ID of the authors and of the blog
|
||||
in which this article have been published. If no blog ID is specified, the article
|
||||
will be rejected. The `actor` of the activity corresponds to the user that clicked
|
||||
the "Publish" button, and should normally be one of the author in `attributedTo`.
|
||||
- `object.name` is the title of the article.
|
||||
- `object.content` is a string containing the HTML of the rendered article.
|
||||
- `object.creationDate` is the date of the first publication of this article.
|
||||
- `object.source` is a `Source` object, and its content is the Markdown source of
|
||||
this article.
|
||||
- `object.tag` is a list, and its elements are either:
|
||||
- a `Hashtag` object, for the tag of the article (no difference is made between
|
||||
global tags shown at the end of the article and hashtags in the article itself for
|
||||
the
|
||||
moment).
|
||||
- a `Mention` object, for every actor that have been mentionned in this
|
||||
article.
|
||||
|
||||
If `object` is a `Note`:
|
||||
- `object.content` is the HTML source of the rendered comment.
|
||||
- `object.inReplyTo` is the ID of the previous comment in the thread, or of the
|
||||
post that is commented if there is no previous comment.
|
||||
- `object.spoilerText` is a string to be displayed in place of the comment, unless
|
||||
the reader explicitely express their will to see the actual content (what is called
|
||||
*Content Warning* in Mastodon)
|
||||
- `object.tag` is a list of `Mention` that correspond to the mentionned users.
|
||||
|
||||
#### Delete
|
||||
|
||||
Deletes an object that was first created with a `Create` activity.
|
||||
|
||||
`object` is a `Tombstone`, and `object.id` the ID of the object to delete (either
|
||||
an Article ID, or a Note ID).
|
||||
|
||||
#### Follow
|
||||
|
||||
When received, the actor is added to the follower list of the target.
|
||||
|
||||
These activities are immediatly accepted (see [`Accept`](#accept)) by Plume.
|
||||
|
||||
For blogs, they won't actually do anything else than sending back an `Accept`
|
||||
activity: following a blog is not yet implemented.
|
||||
|
||||
- `actor` is the ID of an Actor, or a `Person` object. It represent the new
|
||||
follower.
|
||||
- `object` is the ID of the target user or blog.
|
||||
|
||||
#### Like
|
||||
|
||||
Can be used to add a like to an article.
|
||||
|
||||
- `actor` is the ID of the user liking the article.
|
||||
- `object` is the ID of the post being liked.
|
||||
|
||||
#### Update
|
||||
|
||||
Updates an article.
|
||||
|
||||
- `object` is an `Article` object. It has no mandatory field other than `id`. Only
|
||||
present fields will be updated.
|
||||
- `object.id` is the ID the of the article being updated.
|
||||
- `object.title` is the new title of the article.
|
||||
- `object.content` is the updated HTML of the article.
|
||||
- `object.subtitle` is the updated subtitle of the article.
|
||||
- `object.source` is a `Source` object, and its `content` property is the updated
|
||||
markdown of the article.
|
||||
|
||||
#### Undo
|
||||
|
||||
Cancels a previous action (either a like, reshare or follow).
|
||||
|
||||
- `object` is the `Announce`, `Follow` or `Like` to undo.
|
561
docs/INSTALL.md
561
docs/INSTALL.md
|
@ -1,561 +0,0 @@
|
|||
# Installing Plume (for development or production)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
In order to be installed and to work correctly, Plume needs:
|
||||
|
||||
- *Git* (to get the code)
|
||||
- *Curl* (for RustUp, the Rust installer)
|
||||
- *GCC* and *make* (to compile C dependencies)
|
||||
- *PostgreSQL* or *SQlite 3 development files* (for the database)
|
||||
- *GetText* (to manage translations)
|
||||
- *Rust* and *Cargo* (to build the code)
|
||||
- *OpenSSL* and *OpenSSL librairies* (for security)
|
||||
- *xz* (for gettext-sys compilation)
|
||||
- *pkg-config* (for openssl-sys compilation)
|
||||
|
||||
All the following instructions will need a terminal.
|
||||
|
||||
Here are the commands to install PostgreSQL and GetText on various operating systems.
|
||||
Some of them may need root permissions.
|
||||
|
||||
You can also install the project using Docker and docker-compose, please refer
|
||||
to the `Docker install` section.
|
||||
|
||||
On **Debian**:
|
||||
|
||||
```bash
|
||||
apt update
|
||||
|
||||
# If you want PostgreSQL
|
||||
apt install gettext postgresql postgresql-contrib libpq-dev git curl gcc make openssl libssl-dev xz-utils pkg-config
|
||||
|
||||
# If you want SQlite
|
||||
apt install gettext libsqlite3-dev git curl gcc make openssl libssl-dev xz-utils pkg-config
|
||||
|
||||
```
|
||||
|
||||
On **Fedora**, **CentOS** or **RHEL**:
|
||||
|
||||
```bash
|
||||
# If you want PostgreSQL
|
||||
dnf install postgresql-server postgresql-contrib libpqxx libpqxx-devel git curl gcc make openssl openssl-devel gettext
|
||||
|
||||
# If you want SQLite
|
||||
dnf install libsq3-devel sqlite3 libsqlite3-dev git curl gcc make openssl openssl-devel gettext
|
||||
```
|
||||
|
||||
On **Gentoo**:
|
||||
|
||||
```bash
|
||||
emerge --sync
|
||||
|
||||
# If you want PostgreSQL
|
||||
emerge -avu dev-db/postgresql dev-vcs/git sys-devel/gettext
|
||||
|
||||
# If you want SQlite
|
||||
emerge -avu dev-db/sqlite dev-vcs/git sys-devel/gettext
|
||||
```
|
||||
|
||||
On **Mac OS X**, with [Homebrew](https://brew.sh/):
|
||||
|
||||
```bash
|
||||
brew update
|
||||
|
||||
# For PostgreSQL
|
||||
brew install postgres gettext git
|
||||
|
||||
# For SQlite (already present, so only GetText and Git are needed)
|
||||
brew install gettext git
|
||||
```
|
||||
|
||||
## Configuring PostgreSQL
|
||||
|
||||
You can either run PostgreSQL from the machine that runs Plume, or from another server. We recommend you to use the first setup for development environments, or in production for small instances.
|
||||
|
||||
In the first case, just run this command after the PostgreSQL installation, to start it:
|
||||
|
||||
```
|
||||
service postgresql start
|
||||
```
|
||||
|
||||
If you want to have two separate machines, run these commands on the database server once you've installed the dependencies mentioned above on both servers:
|
||||
|
||||
```bash
|
||||
service postgresql start
|
||||
su - postgres
|
||||
createuser -d -P plume
|
||||
createdb -O plume plume
|
||||
```
|
||||
|
||||
## Creating a new user (optional)
|
||||
|
||||
This step is recommended if you are in a **production environment**, but it is not necessary.
|
||||
|
||||
```bash
|
||||
adduser plume
|
||||
su - plume
|
||||
cd ~
|
||||
```
|
||||
|
||||
Creating a new user will let you use systemd to manage Plume if you want (see the dedicated section below).
|
||||
|
||||
## Installing Rust and Cargo
|
||||
|
||||
We said that Plume needed Rust and Cargo to work, but we didn't install them at the same time as PostgreSQL and GetText, because there is an universal installation method called RustUp.
|
||||
|
||||
You can install it on **GNU/Linux** and **Mac OS X** with:
|
||||
|
||||
```bash
|
||||
curl https://sh.rustup.rs -sSf | sh
|
||||
```
|
||||
|
||||
When asked, choose the *"1) Proceed with installation (default)"* option.
|
||||
|
||||
Then run this command to be able to run cargo in the current session:
|
||||
|
||||
```bash
|
||||
export PATH="$PATH:/home/plume/.cargo/bin:/home/plume/.local/bin:/usr/local/sbin"
|
||||
```
|
||||
|
||||
On **Windows**, you'll need, if you don't already have them, to download and install the [Visual C++ 2015 Build Tools](https://www.microsoft.com/en-us/download/details.aspx?id=48159). Then, download the [rustup installer](https://www.rust-lang.org/en-US/install.html) and run it.
|
||||
|
||||
## Getting Plume's source code
|
||||
|
||||
Plume needs to be compiled from source. To download the code, run:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Plume-org/Plume.git
|
||||
cd Plume
|
||||
|
||||
# If you want PostgreSQL
|
||||
export FEATURES=postgres
|
||||
|
||||
# If you want SQlite
|
||||
export FEATURES=sqlite
|
||||
```
|
||||
|
||||
## Configuring Plume
|
||||
|
||||
Before starting Plume, you'll need to create a configuration file, called `.env`. Here is a sample of what you should put inside.
|
||||
|
||||
```bash
|
||||
# The address of the database
|
||||
# (replace USER, PASSWORD, PORT and DATABASE_NAME with your values)
|
||||
#
|
||||
# If you are using SQlite, use the path of the database file (`plume.db` for instance)
|
||||
DATABASE_URL=postgres://USER:PASSWORD@IP:PORT/DATABASE_NAME
|
||||
|
||||
# For PostgreSQL: migrations/postgres
|
||||
# For SQlite: migrations/sqlite
|
||||
MIGRATION_DIRECTORY=migrations/postgres
|
||||
|
||||
# The domain on which your instance will be available
|
||||
BASE_URL=plu.me
|
||||
|
||||
# Secret key used for private cookies and CSRF protection
|
||||
# You can generate one with `openssl rand -base64 32`
|
||||
ROCKET_SECRET_KEY=
|
||||
```
|
||||
|
||||
For more information about what you can put in your `.env`, see [the documentation about environment variables](ENV-VARS.md).
|
||||
|
||||
## Running migrations
|
||||
|
||||
Migrations are scripts used to update the database. They are run by a tool called Diesel, which can be installed with:
|
||||
|
||||
```bash
|
||||
cargo install diesel_cli --no-default-features --features $FEATURES --version '=1.3.0'
|
||||
```
|
||||
|
||||
To run the migrations, you can do:
|
||||
|
||||
```bash
|
||||
diesel migration run
|
||||
```
|
||||
|
||||
Migrations should be run before using Plume or the `plm` CLI tool, and after each update.
|
||||
When in doubt, run them.
|
||||
|
||||
## Running Plume
|
||||
|
||||
Then, you'll need to install Plume and the CLI tools to manage your instance.
|
||||
|
||||
```
|
||||
cargo install --no-default-features --features $FEATURES --path ./
|
||||
cargo install --no-default-features --features $FEATURES --path plume-cli
|
||||
```
|
||||
|
||||
After that, you'll need to setup your instance, and the admin's account.
|
||||
|
||||
```
|
||||
plm instance new
|
||||
plm users new --admin
|
||||
```
|
||||
|
||||
You will also need to initialise search index
|
||||
|
||||
```
|
||||
plm search init -p path/to/plume/workingdir
|
||||
```
|
||||
|
||||
For more information about these commands, and the arguments you can give them, check out [their documentaion](CLI.md).
|
||||
|
||||
Finally, you can start Plume with:
|
||||
|
||||
```bash
|
||||
plume
|
||||
```
|
||||
|
||||
We may provide precompiled packages in the future; if you have experience in these fields and want to help, feel free to discuss this in issues and to propose pull-requests!
|
||||
|
||||
## Docker install
|
||||
|
||||
You can use `docker` and `docker-compose` in order to manage your Plume instance and have it isolated from your host:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:Plume-org/Plume.git
|
||||
cd Plume
|
||||
cp docs/docker-compose.sample.yml docker-compose.yml
|
||||
cp docs/docker.sample.env .env
|
||||
|
||||
# Build the containers
|
||||
docker-compose build
|
||||
|
||||
# Launch the database
|
||||
docker-compose up -d postgres
|
||||
# Setup the database (create it and run migrations)
|
||||
docker-compose run --rm plume diesel database setup
|
||||
|
||||
# Setup your instance
|
||||
docker-compose run --rm plume plm instance new
|
||||
docker-compose run --rm plume plm users new --admin
|
||||
docker-compose run --rm plume plm search init
|
||||
|
||||
# Launch your instance for good
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
Then, you can configure your reverse proxy.
|
||||
|
||||
## Configuring Nginx
|
||||
|
||||
Here is a sample Nginx configuration for a Plume instance (replace `blog.example.com` with your domain name):
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name blog.example.com;
|
||||
|
||||
location /.well-known/acme-challenge {}
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
listen [::]:443 ssl http2;
|
||||
server_name blog.example.org;
|
||||
|
||||
access_log /var/log/nginx/access.log;
|
||||
root /home/plume/Plume/ ;
|
||||
|
||||
SSLCertificateFile /etc/letsencrypt/live/blog.example.com/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/blog.example.com/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/blog.example.com/chain.pem
|
||||
|
||||
# for ssl conf: https://cipherli.st/
|
||||
ssl_protocols TLSv1.2 TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
|
||||
ssl_prefer_server_ciphers on;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;# openssl dhparam -out /etc/letsencrypt/ssl-dhparam.pem 4096
|
||||
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
|
||||
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
|
||||
ssl_session_timeout 10m;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_tickets off; # Requires nginx >= 1.5.9
|
||||
ssl_stapling on; # Requires nginx >= 1.3.7
|
||||
ssl_stapling_verify on; # Requires nginx => 1.3.7
|
||||
resolver 9.9.9.9 80.67.169.12 valid=300s;
|
||||
resolver_timeout 5s;
|
||||
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; frame-src https:";
|
||||
|
||||
location ~* \.(jpg|jpeg|png|gif|ico|js|pdf)$ {
|
||||
add_header Cache-Control "public";
|
||||
expires 7d;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://localhost:7878/;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
client_max_body_size 10m;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuring Apache
|
||||
|
||||
If you prefer Apache, you can use this configuration (here too, replace `blog.example.com` with your domain):
|
||||
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName blog.example.com
|
||||
Redirect / https://blog.example.com/
|
||||
</VirtualHost>
|
||||
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
|
||||
<VirtualHost *:443>
|
||||
ServerAdmin admin@example.com
|
||||
ServerName blog.example.com
|
||||
<Directory "/home/plume/Plume">
|
||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||
Header always set Strict-Transport-Security "max-age=31536000"
|
||||
</Directory>
|
||||
SSLEngine on
|
||||
|
||||
# for cipher conf: https://cipherli.st/
|
||||
SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
|
||||
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
|
||||
SSLHonorCipherOrder On
|
||||
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
|
||||
Header always set X-Frame-Options DENY
|
||||
Header always set X-Content-Type-Options nosniff
|
||||
SSLCompression off
|
||||
SSLUseStapling on
|
||||
|
||||
# Requires Apache >= 2.4.11
|
||||
SSLSessionTickets Off
|
||||
|
||||
SSLCertificateFile /etc/letsencrypt/live/blog.example.com/cert.pem
|
||||
SSLCertificateKeyFile /etc/letsencrypt/live/blog.example.com/privkey.pem
|
||||
SSLCertificateChainFile /etc/letsencrypt/live/blog.example.com/chain.pem
|
||||
|
||||
ProxyPreserveHost On
|
||||
RequestHeader set X-Forwarded-Proto "https"
|
||||
|
||||
ProxyPass / http://127.0.0.1:7878/
|
||||
ProxyPassReverse / http://127.0.0.1:7878/
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
## Configuring Caddyserver
|
||||
|
||||
If you prefer [Caddyserver](http://caddyserver.com), you can use this configuration (again, replacing `blog.example.com` with your domain):
|
||||
|
||||
```
|
||||
blog.example.com {
|
||||
proxy / localhost:7878 {
|
||||
transparent
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Systemd integration
|
||||
|
||||
If you want to manage your Plume instance with systemd, you can use the following unit file (to be saved in `/etc/systemd/system/plume.service`):
|
||||
|
||||
```toml
|
||||
[Unit]
|
||||
Description=plume
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=plume
|
||||
WorkingDirectory=/home/plume/Plume
|
||||
ExecStart=/home/plume/.cargo/bin/plume
|
||||
TimeoutSec=30
|
||||
Restart=always
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Now you need to enable all of these services:
|
||||
|
||||
```bash
|
||||
systemctl enable /etc/systemd/system/plume.service
|
||||
```
|
||||
|
||||
Now start the services:
|
||||
|
||||
```bash
|
||||
systemctl start plume.service
|
||||
```
|
||||
|
||||
Check that they are properly running:
|
||||
|
||||
```bash
|
||||
systemctl status plume.service
|
||||
```
|
||||
|
||||
## SysVinit integration
|
||||
|
||||
This script can also be useful if you are using SysVinit.
|
||||
|
||||
```bash
|
||||
#!/bin/sh
|
||||
### BEGIN INIT INFO
|
||||
# Provides:
|
||||
# Required-Start: $remote_fs $syslog
|
||||
# Required-Stop: $remote_fs $syslog
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Start daemon at boot time
|
||||
# Description: Federated blogging
|
||||
# Based on https://raw.githubusercontent.com/fhd/init-script-template/master/template
|
||||
### END INIT INFO
|
||||
|
||||
dir="/home/plume/Plume"
|
||||
cmd="/home/plume/.cargo/bin/plume"
|
||||
user="plume"
|
||||
|
||||
name=`basename $0`
|
||||
pid_file="/var/run/$name.pid"
|
||||
stdout_log="/home/plume/Plume/plume.log"
|
||||
stderr_log="/home/plume/Plume/plume.err"
|
||||
|
||||
get_pid() {
|
||||
cat "$pid_file"
|
||||
}
|
||||
|
||||
is_running() {
|
||||
[ -f "$pid_file" ] && ps -p `get_pid` > /dev/null 2>&1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
if is_running; then
|
||||
echo "Already started"
|
||||
else
|
||||
echo "Starting $name"
|
||||
cd "$dir"
|
||||
if [ -z "$user" ]; then
|
||||
sudo $cmd >> "$stdout_log" 2>> "$stderr_log" &
|
||||
else
|
||||
sudo -u "$user" $cmd >> "$stdout_log" 2>> "$stderr_log" &
|
||||
fi
|
||||
echo $! > "$pid_file"
|
||||
if ! is_running; then
|
||||
echo "Unable to start, see $stdout_log and $stderr_log"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
stop)
|
||||
if is_running; then
|
||||
echo -n "Stopping $name.."
|
||||
kill `get_pid`
|
||||
for i in 1 2 3 4 5 6 7 8 9 10
|
||||
# for i in `seq 10`
|
||||
do
|
||||
if ! is_running; then
|
||||
break
|
||||
fi
|
||||
|
||||
echo -n "."
|
||||
sleep 1
|
||||
done
|
||||
echo
|
||||
|
||||
if is_running; then
|
||||
echo "Not stopped; may still be shutting down or shutdown may have failed"
|
||||
exit 1
|
||||
else
|
||||
echo "Stopped"
|
||||
if [ -f "$pid_file" ]; then
|
||||
rm "$pid_file"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "Not running"
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
if is_running; then
|
||||
echo "Unable to stop, will not attempt to start"
|
||||
exit 1
|
||||
fi
|
||||
$0 start
|
||||
;;
|
||||
status)
|
||||
if is_running; then
|
||||
echo "Running"
|
||||
else
|
||||
echo "Stopped"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|status}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
```
|
||||
|
||||
Now start the services:
|
||||
|
||||
```bash
|
||||
service plume.service start
|
||||
```
|
||||
|
||||
|
||||
And check:
|
||||
|
||||
```bash
|
||||
service plume.service status
|
||||
```
|
||||
|
||||
## OpenRC integration
|
||||
|
||||
This script can also be useful if you are using OpenRC.
|
||||
|
||||
```bash
|
||||
#! /sbin/openrc-run
|
||||
name="plume"
|
||||
description="plume : federated blogging"
|
||||
pidfile=/run/plume
|
||||
start() {
|
||||
ebegin "Starting plume"
|
||||
start-stop-daemon -v --start --exec "/home/plume/.cargo/bin/cargo run" --user "plume" --chdir "/home/plume/Plume" --background --stdout "/var/log/plume.log" --stderr "/var/log/plume.err" --make-pidfile --pidfile "/run/plume" -- "phx.server"
|
||||
eend $?
|
||||
}
|
||||
|
||||
stop() {
|
||||
ebegin "Stopping plume"
|
||||
start-stop-daemon --stop --user "plume" --chdir "/home/plume/Plume" --pidfile "/run/plume"
|
||||
eend $?
|
||||
}
|
||||
```
|
||||
Now you need to enable all of these services:
|
||||
|
||||
```bash
|
||||
rc-update add plume
|
||||
```
|
||||
|
||||
Now start the services:
|
||||
|
||||
```bash
|
||||
/etc/init.d/plume start
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Caveats:
|
||||
|
||||
- Pgbouncer is not supported yet (named transactions are used).
|
||||
- Rust nightly is a moving target, dependancies can break and sometimes you need to check a few versions to find the one working (run `rustup override set nightly-2018-07-17` in the Plume directory if you have issues during the compilation)
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Most of this documentation has been written by *gled-rs*. The systemd unit file, Nginx and Apache configurations have been written by *nonbinaryanargeek*. Some parts (especially the instructions to install native dependencies) are from the [Aardwolf project](https://github.com/Aardwolf-Social/aardwolf). The docker instructions, and files have been added by *Eliot Berriot*.
|
|
@ -1,44 +0,0 @@
|
|||
# Making Plume available in your language
|
||||
|
||||
*You will need to have basic git and GitHub knownledge to follow this guide. But we plan to setup a more user-friendly translation tool in the future.*
|
||||
|
||||
To translate Plume in your language, you'll first need to make sure it is listed in the `po/LINGUAS` file. If it is not, you can ask anybody with a development environment to add it (or do it yourself if you have a development environment). Once it will be here, Plume must be launched once to generate all the needed files.
|
||||
|
||||
Then you can start translating. Find the file corresponding to your locale, which is `po/YOUR_LOCALE.po`, and open it. Inside, you have a list of strings to translate. There are two kind of translatable strings.
|
||||
|
||||
## Simple strings
|
||||
|
||||
They look like this:
|
||||
|
||||
```po
|
||||
msgid "Hello, world"
|
||||
msgstr ""
|
||||
```
|
||||
|
||||
What is next to `msgid` is the string in English. To translate it, just fill the `msgstr` field with the translation.
|
||||
|
||||
## Strings with plural forms
|
||||
|
||||
Sometimes, strings may change depending on a number (for instance, a post counter). In the `.po` files, these strings look like this:
|
||||
|
||||
```
|
||||
msgid "One post"
|
||||
msgid_plural "{0} posts"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
```
|
||||
|
||||
Then you should fill the two `msgstr` field, one with the singular form,
|
||||
the second with the plural one. If your language as more than two forms,
|
||||
you can add another one by following the same pattern (`msgstr[n] ""`).
|
||||
|
||||
## Interpolation
|
||||
|
||||
Strings you translate may contain data from Plume (a username for instance).
|
||||
To tell Plume where to put these data, surround the number that identifies
|
||||
them by `{` and `}`. The identifier is also present in this form in the English
|
||||
string to translate (this what you can see above, with the `{0} posts` message).
|
||||
|
||||
## Note
|
||||
|
||||
When translating, please try to be as inclusive as possible.
|
|
@ -1,10 +0,0 @@
|
|||
# Plume documentation
|
||||
|
||||
- [Installing Plume (for development or production)](INSTALL.md)
|
||||
- [Updating your instance](UPDATE.md)
|
||||
- [Useful Environment Variables](ENV-VARS.md)
|
||||
- [Development Guide](DEVELOPMENT.md)
|
||||
- [Making Plume available in your language](INTERNATIONALIZATION.md)
|
||||
- [REST API reference](API.md)
|
||||
- [`plm` CLI reference](CLI.md)
|
||||
- [How Plume Federates](FEDERATION.md)
|
|
@ -1,19 +0,0 @@
|
|||
# Updating your instance
|
||||
|
||||
To update your instance, run these commands with `plume` user if you created it, or with your default user, in the Plume directory.
|
||||
|
||||
```bash
|
||||
git pull origin master
|
||||
cargo install --force && cargo install --path plume-cli --force
|
||||
|
||||
# Run the migrations
|
||||
diesel migration run
|
||||
|
||||
# If you are using sysvinit
|
||||
sudo service plume restart
|
||||
|
||||
# If you are using systemd
|
||||
sudo systemctl restart plume
|
||||
```
|
||||
|
||||
That's it!
|
|
@ -1 +0,0 @@
|
|||
theme: jekyll-theme-cayman
|
|
@ -1,64 +0,0 @@
|
|||
openapi: "3.0"
|
||||
info:
|
||||
version: "1.0.0"
|
||||
title: "Plume REST API"
|
||||
|
||||
servers:
|
||||
- url: http://localhost:7878/api/v1
|
||||
description: Your local instance
|
||||
- url: https://baptiste.gelez.xyz/api/v1
|
||||
description: Demo instance
|
||||
|
||||
paths:
|
||||
/apps:
|
||||
post:
|
||||
description:
|
||||
Registers an application.
|
||||
/posts/{id}:
|
||||
get:
|
||||
description:
|
||||
Retrieves a post by its ID.
|
||||
responses:
|
||||
'200':
|
||||
The post was found
|
||||
'403':
|
||||
The post exists, but you don't have the rights to fetch it (it is probably a private draft)
|
||||
'404':
|
||||
The post was not found
|
||||
/posts/:
|
||||
get:
|
||||
description:
|
||||
List posts.
|
||||
|
||||
definitions:
|
||||
App:
|
||||
type: "object"
|
||||
properties:
|
||||
name:
|
||||
type: "string"
|
||||
example: "My app"
|
||||
website:
|
||||
type: "string"
|
||||
example: "https://my.app"
|
||||
client_id:
|
||||
type: "string"
|
||||
example: "My app"
|
||||
client_secret:
|
||||
type: "string"
|
||||
example: "My app"
|
||||
Post:
|
||||
type: "object"
|
||||
properties:
|
||||
title:
|
||||
type: "string"
|
||||
example: "Hello, world!"
|
||||
id:
|
||||
type: "integer"
|
||||
format: "int64"
|
||||
example: 42
|
||||
subtitle:
|
||||
type: "string"
|
||||
example: "My first post."
|
||||
content:
|
||||
type: "string"
|
||||
format: "<p>This is my first post. Thanks for reading.</p>"
|
|
@ -1,18 +0,0 @@
|
|||
version: '3'
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:10.5
|
||||
env_file: .env
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "./data/postgres:/var/lib/postgresql/data"
|
||||
plume:
|
||||
build: .
|
||||
env_file: .env
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "./data/plume/static/media:/app/static/media"
|
||||
- "./.env:/app/.env"
|
||||
ports:
|
||||
- "127.0.0.1:7878:7878"
|
|
@ -1,10 +0,0 @@
|
|||
BASE_URL=yourdomain.com
|
||||
# generate one with openssl rand -base64 32
|
||||
ROCKET_SECRET_KEY=randomstringhere
|
||||
|
||||
# you can safely leave those defaults
|
||||
DATABASE_URL=postgres://plume:plume@postgres:5432/plume
|
||||
MIGRATION_DIR=migrations/postgres
|
||||
USE_HTTPS=1
|
||||
ROCKET_ADDRESS=0.0.0.0
|
||||
ROCKET_PORT=7878
|
Loading…
Reference in a new issue