đź“… 25 Jan 2021
- Requirements
- First steps
- Creating the docker image
- Creating the
docker-compose.yml
.env
file: create the settings of the instance- Current folder structure
- Start up the containers
- Configuring nginx
- Finishing touches
- Enable OAuth and API access so that apps can work
- Upgrading your Pixelfed instance to a new version
Since starting on PixelDroid, at multiple occasions I wanted to try things out or try to contribute to Pixelfed, but each time gave up on getting the server to work after a lot of frustration.
So now that I finally got it working, let me share a step by step guide on how to do it.
Requirements
docker
anddocker-compose
(or podman, but my server still has docker so that’s what I use here - I’ll switch over this summer probably, when I upgrade away from Ubuntu 18.04 on my server)nginx
git
First steps
First make a new folder:
mkdir pixelfed_docker_compose
cd pixelfed_docker_compose
And clone the pixelfed repo inside of that folder:
git clone https://github.com/pixelfed/pixelfed
Creating the docker image
Let’s build the docker image we are going to use:
cd pixelfed
docker build . -t pixelfed:{Current Date} -f contrib/docker/Dockerfile.apache
Replace {Current Date}
with the current date, today it would for example be
docker build . -t pixelfed:20210125 -f contrib/docker/Dockerfile.apache
This just tags the image we’re building here, so that in the future we know which is which.
Creating the docker-compose.yml
Below is my docker-compose.yml
. Read through it carefully so you understand what goes where.
The docker-compose file
version: '3'
services:
app:
image: pixelfed:20210125 #replace with the tag you just made
restart: unless-stopped
ports:
- "8080:80" #80 is the port inside the container, 8080 is the port outside
env_file:
- ./.env
volumes:
- "pixelfed-storage:/var/www/storage"
- "app-bootstrap:/var/www/bootstrap"
- ./.env:/var/www/.env # we'll be creating a .env file in a bit
networks:
- web
- pixelfed
db:
image: mysql:8.0 # You can probably also get it to work with mariadb
restart: unless-stopped
networks:
- pixelfed
command: --default-authentication-plugin=mysql_native_password
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_DATABASE=pixelfed
- MYSQL_USER=${DB_USERNAME}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_RANDOM_ROOT_PASSWORD=true
worker:
image: pixelfed:20210125 #replace with the tag you just made
restart: unless-stopped
env_file:
- ./.env
volumes:
- "pixelfed-storage:/var/www/storage"
- "app-bootstrap:/var/www/bootstrap"
networks:
- web # Required for ActivityPub
- pixelfed
command: gosu www-data php artisan horizon
redis:
image: redis:5-alpine
restart: unless-stopped
volumes:
- "redis-data:/data"
networks:
- pixelfed
volumes: # I'm using docker volumes here, if you want things to be stored elswhere you can change that here
redis-data:
app-bootstrap:
pixelfed-storage:
db-data:
networks:
pixelfed:
internal: true
web:
external: true
Save the this to a docker-compose.yml
file of your own inside the pixelfed_docker_compose
folder you created earlier.
.env
file: create the settings of the instance
Below is my .env file. Change the values to your desired configuration.
You might want to check out the .env.example
file in the pixelfed repo you just cloned, in case since the posting of this article something changed that requires an updated .env
file, but at the time of writing this one worked fine.
.env file
APP_NAME="PixelDroid testing instance"
APP_ENV=production
APP_KEY= #leave empty, this will be generated later!
APP_DEBUG=false
#change this and the following 3 to your own domain
APP_URL=https://testing.pixeldroid.org
APP_DOMAIN="testing.pixeldroid.org"
ADMIN_DOMAIN="testing.pixeldroid.org"
SESSION_DOMAIN="testing.pixeldroid.org"
TRUST_PROXIES="*"
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=pixelfed
DB_USERNAME=pixelfed
#change this to a random password
DB_PASSWORD= CHANGE_ME
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_DRIVER=redis
REDIS_SCHEME=tcp
REDIS_HOST=redis
REDIS_PASSWORD=null
REDIS_PORT=6379
# I'm using the log driver for this testing instance, so the following settings are irrelevant. For a real instance you'll want to change it to something else, see pixelfed documentation
MAIL_DRIVER=log
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="pixelfed@example.com"
MAIL_FROM_NAME="Pixelfed"
OPEN_REGISTRATION=true
ENFORCE_EMAIL_VERIFICATION=true
PF_MAX_USERS=1000
MAX_PHOTO_SIZE=64000
MAX_CAPTION_LENGTH=150
MAX_ALBUM_LENGTH=4
MAX_ACCOUNT_SIZE=10000000
IMAGE_QUALITY=100
ACTIVITY_PUB=true
AP_REMOTE_FOLLOW=true
AP_INBOX=true
PF_COSTAR_ENABLED=false
HORIZON_EMBED=true
OAUTH_ENABLED=true
Current folder structure
This is the folder structure you should have now:
pixelfed_docker_compose
pixelfed/
.env
docker-compose.yml
Start up the containers
Let’s create the networks we declared in the docker-compose.yml
:
docker network create web
First run docker-compose up -d
. This will start the containers as they were configured in the docker-compose file.
Then we are going to generate the key that we left empty in the .env
file:
docker-compose exec app php artisan key:generate
Respond yes to the prompt.
Check that a key was generated in the .env
file.
Now, let’s restart the container we just used to generate the .env
file, make sure the new .env
file is taken into account (config:cache
) and do the database migration.
docker-compose restart app
docker-compose exec app php artisan config:cache
docker-compose exec app php artisan migrate
Respond yes to the prompt.
Configuring nginx
Make a new file in your /etc/nginx/sites-enabled
directory (or wherever your nginx config looks for them, maybe in etc/nginx/conf.d/
depending on your configuration), to reverse proxy the requests to your domain to the right port (in this case, 8080), and to terminate SSL.
See below for my config file:
nginx config file
server {
listen 80;
listen [::]:80;
server_name testing.pixeldroid.org;
# enforce https
return 301 https://$server_name$request_uri;
}
server {
server_name testing.pixeldroid.org;
listen [::]:443 ssl;
listen 443 ssl;
ssl on;
ssl_certificate /etc/letsencrypt/live/testing.pixeldroid.org/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/testing.pixeldroid.org/privkey.pem; # managed by Certbot
client_max_body_size 100M;
location / {
proxy_set_header Host $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;
proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
proxy_set_header X-Forwarded-Port $http_x_forwarded_port;
proxy_redirect off;
proxy_pass http://127.0.0.1:8080;
}
}
Of course you should change the domain name, make sure the port is the one you chose before in the docker-compose file, and configure your own certificates (I let certbot do it, which is pretty convenient since it’ll also do renewals). Make sure the client_max_body_size
value is bigger than the value you set in the .env
.
Restart nginx (sudo systemctl restart nginx
), or just make it reload the config files (sudo nginx -s reload
).
Finishing touches
At this point, you should be able to access your instance on your domain. Check if it looks alright, especially make sure that it doesn’t have everything shown twice (which was a very weird issue I had for a while when some things were misconfigured). If you do have that issue, uncollapse the accordion below:
Look here to fix the "everything shown twice", and maybe other issues if the front page seems broken
First stop the containers (docker-compose down
).
Delete all the volumes except the one for the database (docker volume rm pixelfeddockercompose_redis-data pixelfeddockercompose_app-bootstrap pixelfeddockercompose_pixelfed-storage
, but the volumes might have different names for you: find out their names with docker volume ls
).
Then start the containers up again: docker-compose up -d
Now, you can create a new user. Go back to the folder with the docker-compose file in it, and run this:
docker-compose exec app php artisan user:create
Answer the questions as you wish, for the first account (yours) you probably want to answer the last three questions like this:
Make this user an admin? (yes/no) [no]:
> yes
Manually verify email address? (yes/no) [no]:
> yes
Are you sure you want to create this user? (yes/no) [no]:
> yes
Enable OAuth and API access so that apps can work
This was the most important part for me, since after all the main point of setting up an instance was to be able to debug and play with the API responses in the context of my work on PixelDroid.
As you might have noticed in the .env
file, I set OAUTH_ENABLED=true
so you would think this would enable the API.
However some additional steps are necessary, or you will get very generic errors. I only figured them out after coming accross the 0.10.6 beta release notes.
Go look at those release notes, or just follow the steps here:
docker-compose exec app php artisan passport:keys
Make sure you have OAUTH_ENABLED=true
in the .env
docker-compose exec app php artisan config:cache
docker-compose exec app php artisan route:cache
docker-compose exec app php artisan passport:client --personal
Just answer whatever to the prompt of that last command, I’m not ever sure it is necessary.
Upgrading your Pixelfed instance to a new version
First update the Pixelfed source and then build a new image (again, replace the date with the current date here):
cd pixelfed
git pull
docker build . -t pixelfed:20210203 -f contrib/docker/Dockerfile.apache
cd ..
To update the images used inside the docker-compose, replace the dots with each of the images you use (For instance, I ran docker pull mysql:8.0
and then docker pull redis:5-alpine
):
docker pull ...
Normally you would use docker-compose pull
here to get all of them, but the way I tagged our own pixelfed
image breaks that, since of course there is nothing there to be pulled.
Next we want to actually use the new image: just edit the docker-compose.yml
and replace the old image with the new one we just built.
Now, let’s delete and recreate all of our containers so that we use the latest versions we just made. This doesn’t delete any of the named volumes where the data actually is (remember, the docker way of doing things means your containers don’t store any data but just the application, so deleting the containers doesn’t delete any of your data)
docker-compose up -d
Pixelfed is now updated, but we still need to migrate from the previous version to this one:
In any case you should run
docker-compose exec app php artisan migrate
Depending on the version you come from and the new one you just installed, you will have to run some more commands. Check the release notes for more info.
To go from 0.10.9 to 0.10.10 I had to run the following (all preceded by docker-compose exec app
to run it in the app
container of course):
composer install
php artisan migrate --force
php artisan config:cache
php artisan route:cache
php artisan instance:actor