Compare commits
2 Commits
47cca67b69
...
00d108de62
Author | SHA1 | Date |
---|---|---|
Félix Baylac-Jacqué | 00d108de62 | |
Félix Baylac-Jacqué | 0122f75747 |
|
@ -0,0 +1,91 @@
|
|||
{ config, options, lib, pkgs, stdenv, ... }:
|
||||
let
|
||||
cfg = config.services.pleroma;
|
||||
in {
|
||||
options = {
|
||||
services.pleroma = with lib; {
|
||||
enable = mkEnableOption "pleroma";
|
||||
|
||||
package = mkOption {
|
||||
type = types.package;
|
||||
default = import ../default.nix { inherit pkgs; };
|
||||
description = "Pleroma package to use.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "User account under which pleroma runs.";
|
||||
};
|
||||
|
||||
group = mkOption {
|
||||
type = types.str;
|
||||
default = "pleroma";
|
||||
description = "Group account under which pleroma runs.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
users = {
|
||||
users."${cfg.user}" = {
|
||||
description = "Pleroma user";
|
||||
home = "/var/lib/pleroma";
|
||||
extraGroups = [ cfg.group ];
|
||||
};
|
||||
groups."${cfg.group}" = {};
|
||||
};
|
||||
|
||||
environment.systemPackages = [ cfg.package ];
|
||||
|
||||
systemd.services.pleroma = {
|
||||
description = "Pleroma social network";
|
||||
after = [ "network-online.target" "postgresql.service" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
environment = {
|
||||
MIX_ENV = "prod";
|
||||
};
|
||||
serviceConfig = {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
Type = "forking";
|
||||
WorkingDirectory = "/var/lib/pleroma";
|
||||
StateDirectory = "pleroma pleroma/static pleroma/uploads";
|
||||
StateDirectoryMode = "700";
|
||||
|
||||
# Checking the conf file is there then running the database
|
||||
# migration before each service start, just in case there are
|
||||
# some pending ones.
|
||||
#
|
||||
# It's sub-optimal as we'll always run this, even if pleroma
|
||||
# has not been updated. But the no-op process is pretty fast.
|
||||
# Better be safe than sorry migration-wise.
|
||||
ExecStartPre =
|
||||
let preScript = pkgs.writers.writeBashBin "pleromaStartPre" ''
|
||||
if [ ! -f "/etc/pleroma/config.exs" ]; then
|
||||
echo "ERROR: Missing pleroma config file at /etc/pleroma/config.exs"
|
||||
echo "Did you read https://git.alternativebit.fr/NinjaTrappeur/pleroma-otp-nixos/src/branch/master/readme.md#user-content-pleroma-configuration-management ?"
|
||||
exit 1
|
||||
fi
|
||||
${cfg.package}/bin/pleroma_ctl migrate'';
|
||||
in "${preScript}/bin/pleromaStartPre";
|
||||
|
||||
ExecStart = "${cfg.package}/bin/pleroma daemon";
|
||||
ExecStop = "${cfg.package}/bin/pleroma stop";
|
||||
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
|
||||
|
||||
# Systemd sandboxing directives.
|
||||
# Taken from the upstream contrib systemd service at
|
||||
# pleroma/installation/pleroma.service
|
||||
PrivateTmp = true;
|
||||
ProtectHome = true;
|
||||
ProtectSystem = "full";
|
||||
PrivateDevices = false;
|
||||
NoNewPrivileges = true;
|
||||
CapabilityBoundingSet = "~CAP_SYS_ADMIN";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
meta.maintainers = with lib.maintainers; [ ninjatrappeur ];
|
||||
}
|
140
readme.md
140
readme.md
|
@ -1,12 +1,144 @@
|
|||
# Pleroma on NixOS: OTP Release
|
||||
|
||||
## TODO
|
||||
## Quick Start
|
||||
|
||||
- Add NixOS module.
|
||||
Add your pleroma configuration to `/etc/pleroma/config.exs`, make sure
|
||||
it's readable by the `pleroma` user.
|
||||
|
||||
## Minor Annoyances
|
||||
You can then use the following example to get started.
|
||||
|
||||
We're retrieving the binary distribution directly from the GitLab CI pipeline.
|
||||
```
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
pleromaModuleSrc = builtins.fetchTarball {
|
||||
url = "https://git.alternativebit.fr/NinjaTrappeur/pleroma-otp-nixos/archive/master.tar.gz";
|
||||
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [ "${pleromaModuleSrc}/modules/pleroma.nix" ]
|
||||
|
||||
security.acme = {
|
||||
email = "root@tld";
|
||||
acceptTerms = true;
|
||||
certs = {
|
||||
"social.tld.com" = {
|
||||
webroot = "/var/www/social.tld.com";
|
||||
email = "root@tld";
|
||||
group = "nginx";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
pleroma.enable = true;
|
||||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_12;
|
||||
};
|
||||
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts."social.tld.com" = {
|
||||
addSSL = true;
|
||||
sslCertificate = "/var/lib/acme/social.tld.com/fullchain.pem";
|
||||
sslCertificateKey = "/var/lib/acme/social.tld.com/key.pem";
|
||||
root = "/var/www/social.tld.com";
|
||||
# ACME endpoint
|
||||
locations."/.well-known/acme-challenge" = {
|
||||
root = "/var/www/social.tld.com/";
|
||||
};
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:4000";
|
||||
extraConfig = ''
|
||||
# if you do not want remote frontends to be able to access your Pleroma backend
|
||||
# server, remove these lines.
|
||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
||||
add_header 'Access-Control-Allow-Methods' 'POST, PUT, DELETE, GET, PATCH, OPTIONS' always;
|
||||
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Idempotency-Key' always;
|
||||
add_header 'Access-Control-Expose-Headers' 'Link, X-RateLimit-Reset, X-RateLimit-Limit, X-RateLimit-Remaining, X-Request-Id' always;
|
||||
if ($request_method = OPTIONS) {
|
||||
return 204;
|
||||
}
|
||||
# stop removing lines here.
|
||||
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
add_header X-Permitted-Cross-Domain-Policies none;
|
||||
add_header X-Frame-Options DENY;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header Referrer-Policy same-origin;
|
||||
add_header X-Download-Options noopen;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
|
||||
client_max_body_size 16m;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Pleroma Configuration Management
|
||||
|
||||
### File Configuration
|
||||
|
||||
Pleroma is expecting its configuration to be found at
|
||||
`/etc/pleroma/config.exs`. This configuration file is containing some
|
||||
secrets, the Nix store being world-readable, it seems like storing the
|
||||
pleroma conf there is a pretty bad idea.
|
||||
|
||||
Meaning, this module won't handle this configuration file for you, you
|
||||
have to do it manually. From here, two options:
|
||||
|
||||
1. You are migrating a src-based install (mix-based). You can re-use
|
||||
your `$src_root/config/prod.secret.exs` file. Change the `use Mix.Config`
|
||||
statement with `use Config`.
|
||||
2. This is a brand new installation. In that case you can use
|
||||
`pleroma_ctl instance gen --output config.exs --output-psql setup.psql`,
|
||||
this will prompt you some questions and will generate both your
|
||||
config file and database initial migration. Note: `pleroma_ctl`
|
||||
will be in your system path as soon as you enable the pleroma
|
||||
service. You can alternatively build it by building this repo's
|
||||
`default.nix` derivation.
|
||||
|
||||
### Database Configuration
|
||||
|
||||
If it's not already done, you need to seed your pleroma postgresql database.
|
||||
|
||||
Using the `setup.psql` file generated in the previous section, you can
|
||||
load the seed with `sudo -u postgres psql -f seed.psql`.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- In this module, we decided not to try any kind of magical conf on
|
||||
the Nginx-side. Web server configurations can quickly get pretty
|
||||
custom, letting the admin handle it seems like the best thing to do
|
||||
to me. On top of that, a lot of directives we're using are not
|
||||
covered by the NixOS Nginx module, we have to make a heavy use of
|
||||
`extraConfig`, making the whole config not easily overrideable.
|
||||
**However**, the Nginx block config is quite huge, there's maybe
|
||||
something smarter to do.
|
||||
- The configuration file contains some secrets. On top of that, the
|
||||
config file format is a pure Elixir file, making it poor candidate
|
||||
for a
|
||||
[RFC042](https://github.com/Infinisil/rfcs/blob/config-option/rfcs/0042-config-option.md)
|
||||
-style `settings` attributeset. Because of that, I kinda chicken out
|
||||
and decided to keep the conf file management 100% out of this
|
||||
module. There's probably a better middle ground here. Something
|
||||
allowing us to keep the secret part (db password, endpoint secret
|
||||
key) out of the store while leveraging the module system for the
|
||||
less secret configuration settings. Maybe the solution is to
|
||||
leverage Elixir's import system?
|
||||
|
||||
## Update Pleroma to a New Version
|
||||
|
||||
We're retrieving the binary distribution directly from the GitLab CI
|
||||
pipeline.
|
||||
|
||||
To find the latest and greatest bindist stable URL, you have to visit
|
||||
https://git.pleroma.social/pleroma/pleroma/-/tree/stable, clicky click
|
||||
|
|
Loading…
Reference in New Issue