• 0 Posts
  • 1 Comment
Joined 3 years ago
cake
Cake day: July 7th, 2023

help-circle
  • For whatever it is worth to you I’ve hardened my jellyfin docker compose this way. I’m obscuring some things in this that are local to my network.

    The container is read only. It mounts the media read only. It should be fairly isolated from getting privileges it shouldn’t have. The only things lost in this setup are the ability to delete media from a jellyfin client (something I never do) and the ability to manipulate files directly stored with the media. I use bazarr for subtitles so don’t need jellyfin to download them and I don’t keep trickplay or any other jellyfin metadata related files alongside the media. I feel pretty confident with this that even if the jellyfin codebase had a serious 0 day that the worst I’d lose is metadata and server setup, and important config files I have backing up to another machine.

    I’m sure there’s things I’ve overlooked with this setup so I’m very open to being told there’s a better way to do something.

    services:
      jellyfin:
        image: jellyfin/jellyfin:latest
        container_name: jellyfin
        restart: unless-stopped
        user: ${PUID}:${PGID}
        group_add:
          - "992" # my render group id
        security_opt:
          - no-new-privileges:true
        cap_drop:
          - ALL
        read_only: true
        networks:
          macvlan:
            ipv4_address: OBSCURED
            mac_address: OBSCURED
        healthcheck:
          test: [ "CMD", "curl", "-fsS", "http://127.0.0.1:8096/health" ]
          interval: 1m
          timeout: 10s
          retries: 3
          start_period: 30s
        environment:
          - TZ=${TZ}
          - JELLYFIN_PublishedServerUrl=OBSCURED
          - TMPDIR=/transcode
        volumes:
          - ./jellyfin:/config
          - ./cache:/cache
          - ${MEDIA}:/media:ro
          - ./transcode:/transcode # be sure to set this dir in the jellyfin config
        devices:
          - /dev/dri/renderD128:/dev/dri/renderD128
        deploy:
          resources:
            limits:
              memory: 5G
            reservations:
              memory: 3G
    
      watchstate:
        image: ghcr.io/arabcoders/watchstate:latest
        container_name: watchstate
        restart: unless-stopped
        user: ${PUID}:${PGID}
        ports:
          - 8180:8080/tcp
        volumes:
          - ./watchstate:/config
    
    networks:
      macvlan:
        driver: macvlan
        driver_opts:
          parent: OBSCURED # Replace with host network interface name (find via: ip route | grep default)
        ipam:
          config:
            - subnet: OBSCURED # Your local LAN network CIDR
              gateway: OBSCURED # Your local router IP address
    
    
    spoiler