title = "Generic installation guide" summary = "How to set up everything you need to run your own Pixelfed instance." weight = 20 [menu] [menu.docs] identifier = "admin/installation"
Make sure you have all prerequisites installed and the appropriate services running/enabled before continuing.
Pixelfed Beta currently uses the dev
branch for deployable code. When v1.0 is released, the stable branch will be changed to stable
, with dev
branch being used for development and testing.
cd /usr/share/webapps # or wherever you choose to install web applications
git clone -b dev https://github.com/pixelfed/pixelfed.git pixelfed # checkout dev branch into "pixelfed" folder
Your web server and app processes need to be able to write to the Pixelfed directory. Make sure to set the appropriate permissions. For example, if you are running your processes through the http
user/group, then run the following:
cd pixelfed
sudo chown -R http:http . # change user/group to http user and http group
sudo find . -type d -exec chmod 755 {} \; # set all directories to rwx by user/group
sudo find . -type f -exec chmod 644 {} \; # set all files to rw by user/group
::: danger
User and group permissions
Make sure to use the correct user/group name for your system. This may be http
, www-data
, or pixelfed
(if using a dedicated user).
:::
Run composer install
to fetch the dependencies needed by Pixelfed. It is recommended to run with the following flags:
composer install --no-ansi --no-interaction --optimize-autoloader
By default Pixelfed comes with a .env.example
file for production deployments, and a .env.testing
file for debug deployments. You'll need to rename or copy one of these files to .env
regardless of which environment you're working on.
cp .env.example .env # for production deployments
cp .env.testing .env # for debug deployments
You can now edit .env
and change values for your setup.
APP_NAME
to your desired title, e.g. Pixelfed
. This will be shown in the header bar and other places.APP_DEBUG
is false
for production environments, or true
for debug environments.APP_URL
to the HTTPS URL that you wish to serve Pixelfed through, e.g. https://pixelfed.example
APP_DOMAIN
, ADMIN_DOMAIN
, and SESSION_DOMAIN
to the domain name you will be using for Pixelfed, e.g. pixelfed.example
By default, the values provided will allow connecting to MySQL or MariaDB over the default localhost TCP connection.
If you are running Postgres:
DB_CONNECTION
to pgsql
instead of mysql
.If you are running your SQL server on a different machine or port:
DB_HOST
to the IP of the machineDB_PORT
to the port on which your database server is exposedAlternatively, if you are using a Unix socket:
DB_SOCKET
to the path of the socket, e.g. /run/mysqld/mysqld.sock
To connect to the database you created:
DB_DATABASE
to the name of the database created for PixelfedDB_USERNAME
to the user that was granted privileges for that databaseDB_PASSWORD
to the password that identifies the user with privileges to the databaseIf you are running Redis over TCP on the same machine as Pixelfed, then the default settings will work.
If you are running Redis on another machine:
REDIS_HOST
to the IP of the machine your Redis server is running onREDIS_PORT
to the port on which Redis is exposedREDIS_PASSWORD
to the password of that Redis serverIf you are using a Unix socket for Redis, then:
REDIS_SCHEME
to unix
REDIS_HOST
to the path of the socket, e.g. /run/redis/redis.sock
REDIS_PORT
to 0
::: tip TCP server vs. Unix socket
Redis usually comes pre-configured to listen for TCP requests on the local machine over port 6379. In your Redis configuration, typically at /etc/redis.conf
, the relevant lines are bind 127.0.0.1
and port 6379
.
Changing the latter line to port 0
will disable TCP listening, in which case Redis must be configured for socket access. Lines such as unixsocket /run/redis/redis.sock
and unixsocketperm 770
must be set to enable socket access. Additionally, both the app user and web user should have permission to access the socket, e.g. by being added to the redis
group.
Using a Unix socket is optional, but may provide faster access since it does not have to create TCP packets. TCP is usually used over a network, and would be required if Redis were running on a different machine than your web server. :::
By default, Pixelfed will not send any emails, but will instead write messages to the Laravel log.
To setup a mailer for production deployments, you have several options for supported mail services. Pixelfed currently supports SMTP, Mailgun, Postmark, Amazon SES, and sendmail
for sending emails to users.
MAIL_FROM_ADDRESS
to the email address you want to send fromMAIL_FROM_NAME
to the name you want to appear on emailsMAIL_ENCRYPTION
to tls
in order to have emails be properly deliveredSet up your SMTP server. Or, create an account with Mailtrap.
MAIL_DRIVER
to smtp
MAIL_HOST
to your host, e.g. smtp.mailtrap.io
MAIL_PORT
to your port, e.g. 587
or 2525
MAIL_USERNAME
and MAIL_PASSWORD
if your SMTP server requires authorization. (Mailtrap.io does not.)Create an account with Mailgun.
MAIL_DRIVER
to mailgun
MAIL_HOST
to smtp.mailgun.org
MAIL_PORT
to 587
MAIL_USERNAME
to your Mailgun domainMAIL_PASSWORD
to your Mailgun API keyIf you are not using the "US" Mailgun region, you may define your region's endpoint in the services.php
configuration file located in the config/
directory:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
'endpoint' => 'api.eu.mailgun.net',
],
To use the Postmark driver, install Postmark's SwiftMailer transport via Composer:
composer require wildbit/swiftmailer-postmark
Next, install Guzzle and set the driver
option in your config/mail.php
configuration file to postmark
. Finally, verify that your config/services.php
configuration file contains the following options:
'postmark' => [
'token' => 'your-postmark-token',
],
Create an account with Amazon AWS.
MAIL_DRIVER
to ses
SES_KEY
SES_SECRET
SES_REGION
(if not using the default of us-east-1
)MAIL_DRIVER
to sendmail
If you are using ImageMagick, then:
IMAGE_DRIVER
to imagick
If you want to enable ActivityPub federation:
ACTIVITY_PUB
to true
AP_REMOTE_FOLLOW
to true
If you want to enable OAuth support for external clients:
OAUTH_ENABLED
to true
One time only, you need to generate the secret APP_KEY
:
php artisan key:generate
One time only, the storage/
directory must be linked to the application:
php artisan storage:link
Database migrations must be run:
php artisan migrate --force
If you want to enable support for location data:
php artisan import:cities
If you enabled ActivityPub federation:
php artisan instance:actor
If you enabled OAuth:
php artisan passport:keys
Routes should be cached whenever the source code changes or whenever you change routes:
php artisan route:cache
php artisan view:cache
Every time you edit your .env file, you must run this command to have the changes take effect:
php artisan config:cache
::: tip Running Pixelfed without a cache
It is possible to not use a cache by not running the above cache commands, but it is recommended to run these for production deployments. If you choose not to run these commands, then you can freely edit the .env file and source code instead, and your changes will be reflected instantly, but performance may take a slight hit. You can also undo these commands by running :clear
commands:
php artisan route:clear
php artisan view:clear
php artisan config:clear
:::
Pixelfed supports both Laravel Horizon and Queue Workers to power the job queue. The main difference between Horizon and Queue Worker is the dashboard provided by Horizon as well as advanced load balancing. We recommend using Horizon. Horizon provides a beautiful dashboard which allows you to easily monitor key metrics of your queue system such as job throughput, runtime, and job failures.
If you want admins to be able to access the Horizon web dashboard, you will need to run the following commands:
php artisan horizon:install
php artisan horizon:publish
If your user has the correct permissions to access Redis and the Pixelfed installation folder, then you can simply run php artisan horizon
as that user in a terminal. This may be fine, but if you close the terminal then Horizon will also be terminated. Running directly is recommended only in deployments where a terminal can run uninterrupted, e.g. in a VM or using a utility such as GNU Screen or tmux.
If you are running in production, it is more ideal to create a background service for running Pixelfed's task queue. You will need to use a task manager like systemd or Supervisor. For more information, refer to the Laravel Documentation.
Most distributions will already come with systemd, so you may set up this unit file at /etc/systemd/system/pixelfed.service
:
[Unit]
Description=Pixelfed task queueing via Laravel Horizon
After=network.target
Requires=mariadb
Requires=php-fpm
Requires=redis
Requires=nginx
[Service]
Type=simple
ExecStart=/usr/bin/php /usr/share/webapps/pixelfed/artisan horizon
User=http
Restart=on-failure
[Install]
WantedBy=multi-user.target
::: tip Using correct paths and service names
The example above assumes you are using MariaDB and Nginx, that your distribution's PHP packages do not have versioned names, and that your distribution uses the http
user to serve Nginx. It also assumes that you have installed Pixelfed in /usr/share/webapps/pixelfed in accordance with the rest of the installation process documentation. Some changes you may need to make include:
mariadb
with postgresql
or mysql
php-fpm
with your distro's PHP-FPM package name, e.g. php8.1-fpm
nginx
with apache
, or replacing Requires
with Wants
if you are not running in a production environment/usr/bin/php
or /usr/share/webapps/pixelfed/artisan
with the correct paths, e.g. /usr/bin/php8.1
or /path/to/pixelfed/artisan
User=http
to reflect the app user, e.g. User=pixelfed
or commenting this line in order to run in the system slice.
:::You can now use systemd to manage Pixelfed like any other background service:
sudo systemctl enable --now pixelfed
Alternatively, if you do not wish to use systemd, then you can install Supervisor and create this sample Supervisor configuration file at /etc/supervisor/conf.d/pixelfed.conf
, making sure to use the correct path to your Pixelfed installation and the appropriate app-user:
[program:pixelfed]
command=/usr/bin/php /usr/share/webapps/pixelfed/artisan horizon
user=http
autorestart=true
redirect_stderr=true
stdout_logfile=/usr/share/webapps/pixelfed/horizon.log
stopwaitsecs=3600
::: tip Using correct paths
You may need to replace /usr/bin/php
or /usr/share/webapps/pixelfed/artisan
with the correct paths, e.g. /usr/bin/php8.1
or /path/to/pixelfed/artisan
:::
You will then need to run these commands:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start pixelfed
Pixelfed also includes a queue worker that will process new jobs as they are pushed onto the queue. You may run the worker using the queue:work
command. Note that once the command has started, it will continue to run until it is manually stopped or you close your terminal:
php artisan queue:work
Again, you can use Supervisor or systemd as described above, substituting horizon
for queue:work
.
The task scheduler is used to run periodic commands in the background, such as media optimization, garbage collection, and other time-based tasks that should be run every once in a while.
To set up scheduled tasks using Cron:
EDITOR=nano crontab -e
Paste the following cronjob into your crontab:
* * * * * /usr/bin/php /usr/share/webapps/pixelfed/artisan schedule:run >> /dev/null 2>&1
::: tip Using correct paths
You may need to replace /usr/bin/php
or /usr/share/webapps/pixelfed/artisan
with the correct paths, e.g. /usr/bin/php7.3
or /path/to/pixelfed/artisan
:::
To translate HTTPS web requests to PHP workers, you will need to configure a reverse proxy.
Pixelfed includes a public/.htaccess
file that is used to provide URLs without the index.php front controller in the path. Before serving Pixelfed with Apache, be sure to enable the mod_rewrite
module in your Apache configuration so the .htaccess
file will be honored by the server.
If the .htaccess
file that ships with Pixelfed does not work with your Apache installation, try this alternative:
Options +FollowSymLinks -Indexes
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
Pixelfed includes a sample NGINX configuration at contrib/nginx.conf
. You can copy the contents of this file or include it within your nginx.conf
. Take note of the comments, and make sure to set the correct domain name and root path.
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name pixelfed.example; # change this to your fqdn
root /usr/share/webapps/pixelfed/public; # path to repo/public
ssl_certificate /etc/nginx/ssl/server.crt; # generate your own
ssl_certificate_key /etc/nginx/ssl/server.key; # or use letsencrypt
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+CHACHA20:EECDH+AES;
ssl_prefer_server_ciphers on;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
client_max_body_size 15M; # or your desired limit
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php-fpm/php-fpm.sock; # make sure this is correct
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # or $request_filename
}
location ~ /\.(?!well-known).* {
deny all;
}
}
server { # Redirect http to https
server_name pixelfed.example; # change this to your fqdn
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
::: tip FastCGI path
Make sure to use the correct fastcgi_pass
socket path for your distribution and version of PHP-FPM. For example, on Arch, this is /run/php-fpm/php-fpm.sock
, but on Ubuntu it may be /run/php/php8.1-fpm.sock
, on Debian it may be /var/run/php/php8.1-fpm.sock
, and so on. If you have configured a PHP server over TCP, you may also pass to its IP and port, e.g. localhost:9000
by default.
:::
::: warning Nginx web root
Make sure to use the /public
folder as your server root. For example:
server {
root /var/www/pixelfed/public;
````
If you set root to the install directory (example: `root /var/www/pixelfed;`) Pixelfed will not work.
:::
::: tip
**Nginx client max body size**
Make sure to set an appropriate `client_max_body_size` setting in the `nginx.conf` file. Set this slightly greater than your desired post size limit for file uploads. The `nginx.conf` file location will vary based on your server. `/etc/nginx/nginx.conf`
Example:`http {client_max_body_size 9m;}`
:::
#### Obtaining an HTTPS certificate
For testing deployments, you may generate a self-signed SSL certificate. For example:
```bash
sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.crt
For production deployments, you will need to obtain a certificate from a certificate authority. You may automate certification from LetsEncrypt, a free certificate authority, by using a utility such as EFF Certbot or acme.sh.
Sample usage of certbot:
certbot --nginx -d pixelfed.example