• 3 Posts
  • 20 Comments
Joined 4 months ago
cake
Cake day: December 28th, 2024

help-circle
  • I enjoy it when people go to absurd lengths to not spend money. There’s so much room for creativity within what we tools we already have available to us.

    I also think that it’s important to try new things and see what we can learn from it. Trying and failing is all a part of learning. And we need more ideas and knowledge out there if the idea of open source is to spread and gain popularity.

    If a project is not interesting or important to me, that doesn’t mean that someone else can’t benefit from it. I think if one person finds a project useful or interesting then that’s worth sharing alone. And if only one other person wants to contribute their time to that project, then that’s still pretty awesome.


  • I ended up using rsync to do my backups. I have a laptop, an Android phone with Termux, a HomeAssistant docker image on a Raspberry Pi 4 and a home PieFed instance on a Raspberry Pi 5.

    Each RPi board will create a complete backup on it’s on storage. I’ll then make a copy of each backup to my laptop. And finally another copy from my laptop to an external usb storage device. I also made a specific folder on my Android phone for the purpose of syncing with my laptop.

    What I like about rsync is that it can be made to only transfer any changed files and not everything each time.

    Since I use docker images on both my RPi boards, I made a script that shuts down all the containers before make a backup copy and finally starting the containers again. I even made a script to do something similar to restore from the saved backup.

    Took a lot of trail and error to get them working but I am pretty happy with it. I have the scripts here if anyone is interested. I labelled what I did but didn’t really leave comments explaining things. They are pretty simple anyways.

    I could have used rsnapshot but learning how to use rsync has been interesting enough to me.


  • …Continued from PieFed Instructions…

    1. OPTIONAL: Environment Variables
      • Some functions such as email or captcha’s won’t work unless you add the necessary variables into the ~/pyfedi/.env.docker file. Look at ~/pyfedi/env.sample and add the other variables to ~/pyfedi/.env.docker according to your needs.
      1. View the sample file
        • nano ~/pyfedi/env.sample
      2. Edit & Save .env.docker file
        • nano ~/pyfedi/.env.docker
      3. Restart PieFed Docker container
        • docker compose down && docker compose up -d

    Updating PieFed Docker Container

    1. docker compose down
    2. git pull
    3. docker compose up --build
    4. docker compose down && docker compose up -d

  • taters@piefed.socialOPtoPieFed Meta@piefed.social*Permanently Deleted*
    link
    fedilink
    English
    arrow-up
    4
    ·
    edit-2
    3 months ago

    Backup/Restore Setup

    I decided to keep it simple and use the rsync command which comes already installed on Raspberry Pi OS. The guide linked below does a good job of explaining rsync in a step by step process.

    Below the linked guide I’ll provide an example of the commands I use to Backup and Restore my raspberry Pi. This creates a copy of the /rootfs folders that make up your Raspberry Pi Operating System and User folders. The commands will exclude some folders that may cause issues when restoring a backup. The guide linked below has more details.

    Since I am going to power down the Pi and physically connect it’s hard drive to my computer, I don’t have to worry about making backups on a live and running storage.

    The below commands assume I also have an additional EXTERNAL_STORAGE hard drive connected to my computer. This means the backup command will copy the contents from the Raspberry Pi drive (/rootfs folder) to the EXTERNAL_STORAGE drive (/EXTERNAL_STORAGE/backup folder). The restore command will copy the contents from the EXTERNAL_STORAGE drive (/EXTERNAL_STORAGE/backup/rootfs folder) to the Raspberry Pi drive (/rootfs folder)

    rsync WILL delete data on the target location to sync all files and folders from the source location. Be mindful of which direction you are going to avoid any losses. I suggest testing it out on some other folders before commiting to backing up and restoring the entire Raspberry Pi. The guide linked below also covers exclusions to minimize backup sizes.

    The backup storage MUST be formatted in EXT4 to make sure file permissions and attributes remain the same.

    1. nano ~/.bash_aliases
      1. Add comments & Save
        • alias rsyncBACKUP="sudo rsync -avxhP --delete --exclude={'proc/','sys/','dev/','tmp/','run/','mnt/','media/','home/USERNAME/.cache','lost+found'} /media/USERNAME/rootfs /media/USERNAME/EXTERNAL_STORAGE/backup/"
        • rsyncRESTORE="sudo rsync -avxhP --delete --exclude={'proc/','sys/','dev/','tmp/','run/','mnt/','media/','home/USERNAME/.cache','lost+found'} /media/USERNAME/EXTERNAL_STORAGE/backup/rootfs/ /media/USERNAME/rootfs"
    2. Reset bash in terminal
      • . ~/.bashrc
    3. Backup system TO EXTERNAL_STORAGE
      • !!EXT4 file system only!!
      • rsBACKUP
    4. Restore system FROM EXTERNAL_STORAGE
      • rsRESTORE

    Firewall (LOCAL HOST)

    1. Install: Choose ONE
      • Command line only
        • sudo apt install -y ufw
      • Graphical Interface with command line access
        • sudo apt install -y gufw

    I haven’t figured out how to properly set this up for myself yet, but I figure it’s probably worth having for an additional layer of protection.


  • …Continued from PieFed Instructions…

    Cloudflare Website Settings

    These settings are suggested to help manage traffic. See here for more detailed information.

    1. Exclude Settings
      1. From the main page -> Your DOMAINNAME.COM -> Security -> WAF -> Custom Rules -> Click Create Rule -> Change the following settings and values on Cloudflare to match what’s listed below:
        • Rule Name: Allow Inbox
        • Field: URI Path
        • Operator: contains
        • Value: /inbox
        • Log matching requests: On
        • Then take action…: Skip
        • WAF components to skip: All remaining custom rules
      2. Click `Deploy’ to complete
    2. Caching Settings
      1. From the main page -> Your DOMAINNAME.COM -> Caching -> Cache Rules -> Click Create rule -> Change the following settings on Cloudflare to match what’s listed below:
        • Rule name: ActivityPub
        1. Custom filter expressions: On
          1. Field: URI Path
          2. Operator: Starts with
          3. Value: /activities/
        2. Click Or
        3. Repeat until you have values for 4 rules total containing the values:
          • /activities/
          • /api/
          • /nodeinfo/
          • /.well-known/webfinger
        • Cache Eligibility: On
        • Edge TTL -> Click + add setting
          • Click Ignore cache-control header and use this TTL
          • Input time-to-live (TTL): 2 hours
        • Click Deploy to complete
      2. Click Create rule again
        • Rule name: ActivityPub2
        1. Custom filter expressions: On
          1. Field: Request Header
          2. Name: accept
          3. Operator: contains
          4. Value: application/activity+json
        2. Click Or
        3. Repeat until you have 2 rules total containing the values:
          • application/activity+json
          • application/ld+json
        • Cache Eligibility: On
        • Edge TTL -> Click + add setting
          • Click Ignore cache-control header and use this TTL
          • Input time-to-live (TTL): Type 10 seconds
        • Click Deploy to complete
    3. Optimization Settings
      1. Speed -> Optimization -> Content Optimization -> Change the following settings on Cloudflare to match what’s listed below:
        • Speed Brain: Off
        • Cloudflare Fonts: Off
        • Early Hints: Off
        • Rocket Loader: Off
    4. Cloudflare Tokens for .env.docker File
      1. Create an API “Zone.Cache Purge” token
        1. After logging in to Cloudflare, go to this page
        2. Click Create Token -> Click Get Started under Create Custom Token
        3. Token Name -> PieFed
        4. Under Permissions -> Change the following drop down menu’s to match what’s listed below
          • First drop down menu: Zone
          • Second drop down menu: Cache Purge
          • Third drop down menu: Purge
        5. Click Continue to summary -> Click Create Token
        6. Copy the generated API Token. This will be used for CLOUDFLARE_API_TOKEN in the .env.docker file. Note, once you leave this screen, the API token will remain but the generated code that can be copied will disappear forever.
      2. Copy API Zone ID
        1. From the main page -> Your DOMAINNAME.COM -> Scroll down and look for API Zone ID in the far right column
        2. Copy API Zone ID Token. This will be used for CLOUDFLARE_ZONE_ID in the .env.docker File.
      3. The following step must be completed on the Raspberry Pi (LOCAL HOST) where PieFed is running:
        1. nano ~/pyfedi/.env.docker
          1. Add the following lines with your copied API Tokens & Save
            • CLOUDFLARE_API_TOKEN = 'ZONE.CACHE_PURGE_TOKEN'
            • CLOUDFLARE_ZONE_ID = 'API_ZONE_ID_TOKEN'
        2. Restart PieFed Docker container
          • docker compose down && docker compose up -d

    Troubleshooting

    • If you receive an error while posting images, the folder permissions will need to change. Change USERNAME with your username.
      1. cd ~/pyfedi
      2. sudo chown -R USERNAME:USERNAME ./media

  • taters@piefed.socialOPtoPieFed Meta@piefed.social*Permanently Deleted*
    link
    fedilink
    English
    arrow-up
    3
    ·
    edit-2
    3 months ago

    Lemmy (LOCAL HOST)

    The lemmy instructions are simple and straight forward. When changing the fields asked of you in the instructions, it’s helpful to search and replace the required fields. In nano when editing a file, press CTRL + \ and follow the instructions at the bottom of the window. This will find and replace text.

    The Lemmy instructions show text for editing with {{ Example }}. To avoid confusion, those curly braces must be removed and replaced with the expected data.

    • If you used NPM’s login page to test Cloudflare Tunnels, you will need to login to NPM and change the Port Forward from 81 to 10633
      • Click Hosts -> Proxy Hosts -> Click the 3-Dots for your DOMAINNAME.COM proxy rule -> Edit & Save
    1. Follow Lemmy Install Instructions
      • IGNORE steps Reverse Proxy/Webserver & Let’s Encrypt since we have addressed those steps earlier with NPM and Cloudflare Tunnels/Security.
    2. Through a Web Browser, type in your DOMAINNAME.COM and you should see an admin creation page. Complete that and the initial instance setup afterwards.
    3. Test federation, replace capitals with the required information
      • curl -H 'Accept: application/activity+json' https://domainname.com/u/LEMMY_USERNAME

        • If you see .json information, Lemmy is federated
        • If you see .html information, lemmy is NOT federated

    Updating Lemmy Docker Container

    See here for more information.

    1. docker compose down
    2. docker compose pull
    3. docker compose up -d

    PieFed (LOCAL HOST)

    The PieFed installation instructions will provide more detailed information about each step. This guide does NOT cover any email setup for PieFed.

    • If you used NPM’s login page to test Cloudflare Tunnels, you will need to login to NPM and change the Port Forward from 81 to 8030

      • Click Hosts -> Proxy Hosts -> Click the 3-Dots for your DOMAINNAME.COM proxy rule -> Edit & Save
    • PieFed Install Instructions

    1. Download & Prepare files
      1. git clone https://codeberg.org/rimu/pyfedi.git
      2. cd pyfedi
      3. cp env.docker.sample .env.docker
    2. Edit & Save files
      1. nano .env.docker
        1. Change value for SECRET_KEY with random numbers and letters
        2. Change value for SERVER_NAME with your DOMAINNAME.COM
      2. nano compose.yaml
        • Note ports 8030:5000. You can change the external container port: 8030: if you are using a custom port. Do NOT touch the internal container port :5000.
          • ports:
          • - '8030:5000'
    3. Build
      1. export DOCKER_BUILDKIT=1
      2. sudo docker compose up --build
        • Wait until text stops scrolling
    4. Access your DOMAINNAME.COM from a Web Browser
      1. You may see a message that says database system is ready to accept connections in your terminal window after PieFed is done installing and loading. This means you are ready to attempt a connection through your Web Browser now.
        • If you see constant permission errors, Open and SSH login to the Raspberry Pi in a new terminal window and do the following to allow PieFed to access the required folders:
          1. cd ~/pyfedi
          2. chown -R USERNAME:USERNAME ./pgdata
            • You can leave this window open, it can be used for the step 5.
      2. You may see an “Internal Server Error” after your first connection attempt. This is normal. You will see movement in your terminal window on each attempt to connect to PieFed. Now you can proceed to initialize the database.
    5. Initialize Database
      1. Open and SSH login to the Raspberry Pi in a new terminal window
        1. sudo docker exec -it piefed_app1 sh
        2. export FLASK_APP=pyfedi.py
        3. flask init-db
          • Enter username/email/password. Email is optional.
        4. Access PieFed from your Web Browser again. PieFed should now display. You can log in as admin with the same username and password.
        5. exit
        6. You can close this terminal window now
    6. Return to the terminal with the running docker build and press CTRL + C to stop PieFed.
    7. Run PieFed in the background
      • docker-compose up -d
    8. Setup Cron (Automated) Tasks
      • This will set up automated tasks for daily maintenance, weekly maintenance and email notifications.
      • Change USERNAME to your username.
      1. Setup automated tasks
        1. sudo nano /etc/cron.d/piefed
          1. Paste and Save
    • /etc/cron.d/piefed file
    5 2 * * * USERNAME docker exec piefed_app1 bash -c "cd /app && ./daily.sh"  
    5 4 * * 1 USERNAME docker exec piefed_app1 bash -c "cd /app && ./remove_orphan_files.sh"  
    1 */6 * * * USERNAME docker exec piefed_app1 bash -c "cd /app && ./email_notifs.sh"  
    

  • Cloudflared (LOCAL HOST)

    !!Only proceed with these instructions after setting Cloudflare as your Primary DNS provider. This process may take up to a day after changing nameservers!!

    The following instructions do a few things. First you will install Cloudflared (with a ‘d’). Then you will be asked to log in, create a tunnel, run a tunnel and then creating a service (while the current tunnel is running) so your tunnel can run automatically from startup.

    I’ve noted that this will be installed on the local host (where you are hosting an instance), we will be installing Cloudflared on multiple devices for reasons I will cover later. Hopefully this reduces confusion later on.

    1. Service Install & Create Tunnel & Run Tunnel
      1. Select option -> Linux
      2. Step 4: Change -> credentials-file: /root/.cloudflared/<Tunnel-UUID>.json -> credentials-file: /home/USERNAME/.cloudflared/<Tunnel-UUID>.json
      3. Step 5: SKIP step 2, you will get an error and it’s not important anyways.
      4. Step 6: Keep this window open after running the new tunnel
        • ONLY AFTER completing step 2.i.d. below (Run as a service), press CTRL + C to exit this tunnel
    • Example config.yml file (See above about Step 4)
    tunnel: TUNNEL_ID
    credentials-file: /home/USERNAME/.cloudflared/TUNNEL_ID.json
    ingress:
      - hostname: DOMAINNAME.COM
        service: http://localhost:5050/
      - service: http_status:404
    
    1. Run as a service

      1. Open and SSH login to the Raspberry Pi in a new terminal window
        1. You will get an error if you do not copy your config.yml from your Home folder to /etc/cloudflared. You will need to copy this file again if you make any changes to the config.yml such as adding more tunnels. This will be covered later when setting up Remote SSH access.
          • sudo cp ~/.cloudflared/config.yml /etc/cloudflared/config.yml
        2. cloudflared service install
        3. systemctl start cloudflared
        4. systemctl status cloudflared
          • Check to see if things are green and working, then press CTRL + C when done to exit
          • You can now stop the running tunnel from the first step as previously stated (See Step 1.iv.)
        5. You can close this terminal window now
    2. Enable SSL connections on Cloudflare site

      • Log in to your account on Cloudflare and simply click on the following links
      1. From the main page -> Your DOMAINNAME.COM -> SSL/TLS -> Configure -> Full -> Save
      2. SSL/TLS -> Edge Certificates -> Change the following settings on Cloudflare to match what’s listed below:
        • Always Use HTTPS: On
        • Opportunistic Encryption: On
        • Automatic HTTPS Rewrites: On
        • Universal SSL: Enabled

    If you used NPM as a reverse proxy and it’s set to port 81, go to any Web Browser and type in your DOMAINNAME.COM. You should be directed to NPM’s login page. Check the address bar and your domain name should have a padlock symbol followed by https://domainname.com/. Note that it should read HTTPS:// (with an s) and not HTTP:// (without an s). HTTPS along with the padlock symbol means your connections are properly encrypted.

    This is the most complicated step for self-hosting. If you can confirm your connection is encrypt, setting up other services and webapps are fairly straight forward.


  • Port Forwarding/Reverse Proxy

    Port Forwarding

    Pick a port number between 1024-65,535. This is how Cloudflare will send data and remote connections to your instance without worrying about blocked ports. I like to use 5050 because it’s simple, easy to remember and not used by any of my other self-hosted services. To be consistent, for the rest of this guide I will use port 5050 as an example. Feel free to replace it with any port number you feel like using.

    Router settings are different for each device, refer to a manual or call your ISP for support depending on your situation.

    1. SSH login to your Raspberry Pi and enter the command hostname -I
      • This will print the IP addresses used by the host machine. The first IP address printed will be your local IP address. The rest of the addresses are NOT needed and can be ignored.
    2. Access your Port Forwarding settings in your private network router.
    3. Find your Raspberry Pi device by the Local IP address
    4. Add a rule to allow TCP connections on port 5050.
      • If your router port forwarding settings show Internal and External fields, simply add 5050 to both fields.
    5. Save

    If you are only hosting a Lemmy or PieFed instance, you will be able to do that without the need of a Reverse Proxy which is described below. In this case you can simply use the default ports for Lemmy or PieFed. Replace my example port 5050 with the following depending on your needs:

    • Lemmy default port: 10633
    • PieFed default port: 8030

    Reverse Proxy

    A reverse proxy allows the local host machine to distribute incoming user connections to different services hosted on the local machine. For example, all data from Cloudflare comes in on port 5050 when accessing the DOMAINNAME.COM address. I can use Subdomains to redirect incoming connections on port 5050 to open ports on my local host machine.

    For example, both Lemmy and PieFed can be hosted at the same time. We can use the subdomains lemmy. and piefed. to redirect traffic. When a user types lemmy.DOMAINNAME.COM into the address bar, Cloudflare will send the connection through 5050 to your home and private router which then continues to the Reverse Proxy. The Reverse Proxy running on the local host machine will catch the subdomain request and immediately switch to port 10633 where a connection to Lemmy will be completed. Typing in piefed.DOMAINNAME.COM will guide all requests to port 8030 where PieFed is running and complete that connection.

    For simplicity, Nginx Proxy Manager is docker based with an easy to use web user interface that’s accessible through your local network connected Web Browser. It has it’s limitations but works fine for the current needs.

    Nginx Proxy Manager (LOCAL HOST)

    NPM is extremely simple to set up. Simply create a new folder, create a docker-compose.yml file filled with the necessary information and then run the container.

    1. mkdir ~/npm
    2. cd ~/npm
    3. nano docker-compose.yml
    4. Paste the following into the docker-compose.yml file and save:
    • docker-compose.yml
    services:
      app:
        image: 'jc21/nginx-proxy-manager:latest'
        restart: always
        ports:
          - '5050:80'
          - '81:81'
          - '443:443'
        volumes:
          - ./data:/data
          - ./letsencrypt:/etc/letsencrypt
    

    Note that port 5050: externally connects to NPM internally through port :80. Make sure 5050 matches the Cloudflare Tunnel port you have decided on using.

    1. docker compose up -d and wait for the services to start running
    2. In your Web Browser on any device connected to your private network, type your Raspberry Pi’s local address followed by :81 into the address bar. For example 192.168.0.100:81. See Port Fowarding for help finding your local IP address.
    3. The login page will ask for account details. Enter the following:
      • Account = admin@example.com
      • Password = changeme
      • You will now be asked to create a new admin account
    4. Reverse Proxy Setup:
      1. After Login, click Hosts -> Proxy Hosts -> Add New Proxy
      2. Domain Names field: Your DOMAINNAME.COM
        • Press Enter to store that domain name, NPM won’t store your domain name if you don’t hit enter
      3. Forward Hostname/IP field: Your local host machine ip address (example 192.168.0.100). See Port Fowarding for help finding your local IP address.
      4. Forward Port field: I like to use port 81 to test Cloudflare Tunnels before installing Lemmy or PieFed. This is the login page for NPM. This can be quickly changed to the ports listed below after confirming a secure connection from Cloudflare Tunnels.
        • Lemmy: 10633
        • PieFed: 8030
      5. Block Common Exploits: Enabled
      6. Websockets Support: Enabled
      7. Save

  • taters@piefed.socialOPtoPieFed Meta@piefed.social*Permanently Deleted*
    link
    fedilink
    English
    arrow-up
    3
    ·
    edit-2
    3 months ago

    Requirements

    • A purchased Domain Name
    • Set Cloudflare as your Domain Name’s primary Domain Name Servers (DNS). See here
      • Do this up to a day before in advance as changes may take up to a day to take effect.
    • Raspberry Pi 5 with Raspberry Pi OS (64) image installed
      • You can use other hardware with Debian 12 Operating Systems but I can’t guarantee these instructions will be the exact same
    • A USB external hard drive
      • Something with good read/write speeds will help
    • Access to any routers on your private network
      • You will need access to Port Forwarding options. You will need to read any router manuals or ask your Internet Service Provider since this is different for every device.
    • SSH remote access to Raspberry Pi 5. See here

    Setup & Software Installation (LOCAL HOST)

    The required software to host Lemmy or PieFed will include

    • Docker
    • Cloudflared
    • Lemmy or PieFed

    Additional software I will also cover but aren’t necessary are:

    • Nginx Proxy Manager (NPM)
    • UFW/GUFW - Simple Firewall
    • RSync - For making backups
    • Termux - Android terminal app that will be used for remote SSH access

    Docker (LOCAL HOST)

    The official Docker instructions are clear, quick and simple. The process will also add their repository information for quick and easy updates. This will be installed as a service on your operating system.





  • I’ve tried just building PieFed in docker with as few things changed as possible and I am still running getting the same message when I try to log in. The CSRF tokens do not match.

    The only change I made was in the .env.docker file which was SERVER_NAME=‘pi.DOMAINNAME.ca:8030

    This is what the reverse proxy in nginx looks like now:

    upstream app_server {  
        # fail_timeout=0 means we always retry an upstream even if it failed  
        # to return a good HTTP response  
    
        # for UNIX domain socket setups  
        # server unix:/tmp/gunicorn.sock fail_timeout=0;  
    
        # for a TCP configuration  
        server 192.168.40.140:5000 fail_timeout=0;  
        keepalive 4;  
    }  
    
    server {  
        server_name pi.DOMAINNAME.ca;  
        root /home/USERNAME/pyfedi/app;  
    
        keepalive_timeout 30;  
        ssi off;  
    
        location / {  
            # Proxy all requests to Gunicorn  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
            proxy_set_header X-Forwarded-Proto $scheme;  
            proxy_set_header Host $http_host;  
            proxy_redirect off;  
            proxy_http_version 1.1;  
            proxy_set_header Connection "";  
            proxy_pass http://app_server;  
            ssi off;  
        }  
    
       # Serve static files directly with nginx  
        location ~* /static/ {  
            alias /home/USERNAME/pyfedi/app/static/;  
            expires max;  
            access_log off;  
        }  
    
    }  
    
    

    I’ve tried changing ports, commenting out different parts and it’s still the same. I’ve even checked the port forwarding settings and I still getting the same message. I did notice when I ran netstat -tunpl I didn’t see any ports from docker for port 5000. If I understand how the reverse proxy works, I should have a connection coming in from the outside on port 8030 and be redirected by nginx to port 5000 on the local machine where PieFed is hosted? If that’s right, then nginx isn’t sending anything through 5000 locally and just through 8030 I think.


  • No worries, I’m at least learning a lot about network communication and using the terminal in linux more comfortably. In this case I learned how virtual environments work.

    Also since it’s a Pi, I’ve been copying and swapping SD cards at certain points as a backup. It’s easy to clean up learning mistakes along the way. It’s also good practice before I do it all over again on a proper storage device.



  • To start, if I load PieFed first, then nginx I get an error like below:

    nginx error:

    × nginx.service - nginx - high performance web server  
         Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)  
         Active: failed (Result: exit-code) since Thu 2025-01-02 17:26:07 EST; 22s ago  
       Duration: 5min 39.898s  
           Docs: https://nginx.org/en/docs/  
        Process: 9406 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=1/FAILURE)  
            CPU: 6ms  
    
    Jan 02 17:26:06 pi nginx[9406]: nginx: [emerg] bind() to 0.0.0.0:5000 failed (98: Address already in use)  
    Jan 02 17:26:06 pi nginx[9406]: nginx: [emerg] bind() to [::]:5000 failed (98: Address already in use)  
    Jan 02 17:26:06 pi nginx[9406]: nginx: [emerg] bind() to 0.0.0.0:5000 failed (98: Address already in use)  
    Jan 02 17:26:06 pi nginx[9406]: nginx: [emerg] bind() to [::]:5000 failed (98: Address already in use)  
    Jan 02 17:26:07 pi nginx[9406]: nginx: [emerg] bind() to 0.0.0.0:5000 failed (98: Address already in use)  
    Jan 02 17:26:07 pi nginx[9406]: nginx: [emerg] bind() to [::]:5000 failed (98: Address already in use)  
    Jan 02 17:26:07 pi nginx[9406]: nginx: [emerg] still could not bind()  
    Jan 02 17:26:07 pi systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE  
    Jan 02 17:26:07 pi systemd[1]: nginx.service: Failed with result 'exit-code'.  
    Jan 02 17:26:07 pi systemd[1]: Failed to start nginx.service - nginx - high performance web server.  
    

    If I do the opposite and load nginx before PieFed, PieFed will make a similar complaint about sharing the same port.

    The pyfedi.service, celery.service and celeryd files all look similar to the examples from the INSTALL.md except I changed the directory names to match my name in the appropriate places.

    Here are the error messages I am getting from systemctl:

    pyfedi.service error/celery.service error:

    sudo systemctl status celery.service  
    × pyfedi.service - Gunicorn instance to serve PieFed application  
         Loaded: loaded (/etc/systemd/system/pyfedi.service; enabled; preset: enabled)  
         Active: failed (Result: exit-code) since Thu 2025-01-02 14:28:27 EST; 4h 42min ago  
       Duration: 126ms  
        Process: 6699 ExecStart=/home/USERNAME/pyfedi/venv/bin/gunicorn --config gunicorn.conf.py --preload pyfedi:app (code>  
       Main PID: 6699 (code=exited, status=1/FAILURE)  
            CPU: 126ms  
    
    Jan 02 14:28:27 pi systemd[1]: pyfedi.service: Scheduled restart job, restart counter is at 5.  
    Jan 02 14:28:27 pi systemd[1]: Stopped pyfedi.service - Gunicorn instance to serve PieFed application.  
    Jan 02 14:28:27 pi systemd[1]: pyfedi.service: Start request repeated too quickly.  
    Jan 02 14:28:27 pi systemd[1]: pyfedi.service: Failed with result 'exit-code'.  
    Jan 02 14:28:27 pi systemd[1]: Failed to start pyfedi.service - Gunicorn instance to serve PieFed application.  
    lines 1-13/13 (END)  
    
    ----------  
    
    × celery.service - Celery Service  
         Loaded: loaded (/etc/systemd/system/celery.service; enabled; preset: enabled)  
         Active: failed (Result: exit-code) since Thu 2025-01-02 14:28:26 EST; 4h 42min ago  
        Process: 6694 ExecStart=/bin/sh -c ${CELERY_BIN} multi start -A ${CELERY_APP} ${CELERYD_NODES} --pidfile=${CELERY>  
            CPU: 341ms  
    
    Jan 02 14:28:26 pi sh[6695]:   File "<frozen importlib._bootstrap_external>", line 940, in exec_module  
    Jan 02 14:28:26 pi sh[6695]:   File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed  
    Jan 02 14:28:26 pi sh[6695]:   File "/home/USERNAME/pyfedi/celery_worker.py", line 3, in <module>  
    Jan 02 14:28:26 pi sh[6695]:     from app import celery, create_app  
    Jan 02 14:28:26 pi sh[6695]:   File "/home/USERNAME/pyfedi/app/__init__.py", line 7, in <module>  
    Jan 02 14:28:26 pi sh[6695]:     from flask import Flask, request, current_app, session  
    Jan 02 14:28:26 pi sh[6695]: ModuleNotFoundError: No module named 'flask'  
    Jan 02 14:28:26 pi systemd[1]: celery.service: Control process exited, code=exited, status=2/INVALIDARGUMENT  
    Jan 02 14:28:26 pi systemd[1]: celery.service: Failed with result 'exit-code'.  
    Jan 02 14:28:26 pi systemd[1]: Failed to start celery.service - Celery Service.  
    
    

    At this point I am stuck and not sure where to go from here.


  • You’re right, it was outdated. It seems I got mixed up after a fresh OS install on my Pi. I used APT to download and install docker which is extremely outdated. I now have proper repositories set up for both docker and nginx and everything is up to date. I didn’t need to make any changes to the dockerfile with the proper version.

    I’m having issues getting nginx, pyfedi.service and celery.service to work.

    Below are some snippets from my notes which should lay out all the steps I’ve taken, hopefully that will explain where I am currently at.

    <br>
    Steps from fresh OS Install:

    ## Apt software  
    sudo apt install ddclient gufw -y  
    
    # ddclient -> Account/Password/Domain Address  
    # gufw  
    
    ## Repository Software  
    # Docker -> Install-> https://docs.docker.com/engine/install/debian/  
    # nginx -> Install -> https://nginx.org/en/linux_packages.html#Debian  
            -> sudo nano /etc/nginx/nginx.conf  
               -> Add line -> include /etc/nginx/sites-enabled/DOMAINNAME;  
            -> sudo nano /etc/nginx/sites-enabled/DOMAIN -> Copy DOMAINNAME reverse proxy settings from USB  
            -> sudo nginx -t  
            -> sudo service nginx restart  
    
    ## Docker Images  
    # PieFed -> Install: Easy/Docker -> https://codeberg.org/rimu/pyfedi/src/branch/main/INSTALL.md  
      ->Edit file entries  
        -env.docker  
         -> SECRET_KEY='k3avh6fp'  
         -> SERVER_NAME='pi.DOMAINNAME.ca:5000'  
        -compose.yaml  
         -> ports: - '8030:5000' -> - '5000:5000'  
    
    ## Running In Production  
    # Virtual Environment -> Gunicorn & Celery  
      -> python -m venv ~/home/USERNAME/pyfedi/venv  
      -> source ~/home/USERNAME/pyfedi/venv/bin/activate  
      -> pip3 install gunicorn celery  
      -> deactivate  
    # Copy file celery_worker.default.py -> celery_worker.py  
      -> Change -> DATABASE_URL -> postgresql+psycopg2://piefed:piefed@db/piefed  
      -> Change -> SERVER_NAME -> pi.DOMAINNAME.ca:5000  
    # Create Background Service Files -> Copy EACH from USB  
      -> sudo nano /etc/systemd/system/pyfedi.service  
      -> sudo nano /etc/systemd/system/celery.service  
      -> sudo nano /etc/default/celeryd  
    # Enable/Start Background Services  
      -> sudo systemctl enable pyfedi.service  
      -> sudo systemctl enable celery.service  
      -> sudo systemctl start pyfedi.service  
      -> sudo systemctl start celery.service  
    

    <br>
    /etc/nginx/sites-enabled/DOMAIN file:

    upstream app_server {  
        # fail_timeout=0 means we always retry an upstream even if it failed  
        # to return a good HTTP response  
    
        # for UNIX domain socket setups  
        # server unix:/tmp/gunicorn.sock fail_timeout=0;  
    
        # for a TCP configuration  
        server 192.168.40.140:5000 fail_timeout=0;  
        keepalive 4;  
    }  
    
    server {  
        listen 5000;  
        listen [::]:5000;  
        server_name pi.DOMAINNAME.ca;  
        root /home/USERNAME/pyfedi/app;  
    
        keepalive_timeout 30;  
        ssi off;  
    
        location / {  
            # Proxy all requests to Gunicorn  
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;  
            proxy_set_header X-Forwarded-Proto $scheme;  
            proxy_set_header Host $http_host;  
            proxy_redirect off;  
            proxy_http_version 1.1;  
            proxy_set_header Connection "";  
            proxy_pass http://app_server;  
            ssi off;  
        }  
    
        # Serve static files directly with nginx  
        location ~* /static/ {  
            alias /home/USERNAME/pyfedi/app/static/;  
            expires max;  
            access_log off;  
        }  
    
    }  
    

  • I decided to start over today with a fresh OS install on my Pi. I did everything according to a checklist I started so nothing new has changed from my knowledge. I am getting errors trying to get past the

    export DOCKER_BUILDKIT=1  
    docker-compose up --build  
    

    part of the INSTALL.md for the docker instructions.

    I’ve saved a copy of my terminal but I’m not sure where a good spot to paste it is since it’s long. There were a lot of permission error 13’s so I tried

    sudo docker-compose up --build  
    

    and things started to download and proceed up until a point before another error showed up.

    Step 1/14 : FROM --platform=$BUILDPLATFORM python:3-alpine AS builder  
    failed to parse platform : "" is an invalid component of "": platform specifier component must match "^[A-Za-z0-9_-]+$": invalid argument  
    ERROR: Service 'celery' failed to build : Build failed  
    

    I’m quite confident I did nothing different this time so I don’t know what would be causing issues today. I can provide you with the outputs from my terminal if that will help you.


  • Yeah, I had :5000 at the end, otherwise I would have gotten an error with the initial website connection from a browser saying the domain did not match. That’s how I figured out to change the port in the compose.yaml from an earlier attempt.

    I did not create a reverse proxy. I got excited at getting the site to load that I missed that. I’ll try that in a couple days when I’m free again.

    Docker decided to randomly disappear my PieFed image an hour after I finished working on it. The PyFedi folder and all it’s contents have vanished. A very quick search showed that it has happened to other people with other images. So it’s a thing maybe? Strange but fortunately it was all fresh and nothing was lost.


  • So after a few attempts, I was able to get PieFed working by accessing it through pi.MyDomainName.ca:5000

    I changed the SERVER_NAME in .env.docker to match the address above, but with my actual domain name. I also changed the port numbers from 8030:5000 to 5000:5000 in the compose.yaml

    I am running into an issue when I attempt to use the login information after the database initialization steps. I get the error “The CSRF tokens do not match.” above the username field on the login screen. I’m not sure what that means exactly.

    Other than that, using the docker was fairly straight forward except for some information I forgot to put in correctly the first couple times.


  • Thanks for the suggestions, I’ll have a look into them and see how they fit my needs. I am looking for something that uses markdown language. I’m using that in other parts of this project as a way to keep things unified and simple for others to participate or contribute.

    I don’t do blogs or anything but I do intend to make a community on slrpnk.net in addition to my local instance on my pi. The Solarpunk community will focus more on creating a guide for others to create their own local communities and knowledge base.

    The ultimate goal is making sure it’s simple and accessible to as many people as possible.

    Once I set up an instance or some sort of community page, I plan to write up an outline of decision choices and future goals in order to help people understand what’s going on and where to begin contributing. I’ll be able to use my seed library as a working example.

    I am hoping to be ready within the next couple weeks. I can let you know when the Solarpunk community goes up so you can check it out.


  • Thanks for the information.

    I have a more questions about account registration/logins. If I understand correctly, they will require SSL.

    Before I ask anything, I just want to explain what it is I want to do so it’s easier to understand where I’m coming from.

    I want to start a seed library for my local community in my town. Unless Monsanto is targeting libraries for heritage seeds, I feel my risk is quite low.

    I would like a simple place for people to talk, share information and organize events. I’m also trying to create everything as independent from outside services as possible. The reason being that if any of these outside services experience an extended outage, I can physically move my Raspberry Pi box to central location with local internet/wifi (a library for example) and people will still be able to access all the information. Think of the pi box as becoming a digital community board. In this situation, federation is completely unimportant.

    If Cloudflare tunneling experiences issues or outages, can people still create and login to accounts locally? I’m going to assume any disruptions to any email services would also have an effect since that is used for registration as well.

    I prefer the Reddit/Lemmy/Piefed style and the markdown language works well with the other parts of my project. It’s not necessary and I may keep searching around for something that suites my use case better.

    I’ll most likely go ahead and try installing PieFed anyways with Cloudflare tunneling(or Let’s Encrypt if I don’t have to worry about blocked ports) and smtp2go. At the very least it’ll be an experience and a good place to start for my needs. I can move on from there if I feel the need to.

    Thanks again.