Cloudron makes it easy to run web apps like WordPress, Nextcloud, GitLab on your server. Find out more or install now.


Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Bookmarks
  • Search
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo

Cloudron Forum

Apps | Demo | Docs | Install
  1. Cloudron Forum
  2. MiroTalk
  3. MiroTalk SFU: Recording not possible?

MiroTalk SFU: Recording not possible?

Scheduled Pinned Locked Moved MiroTalk
51 Posts 4 Posters 1.8k Views 4 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S shrey

    When i try to enable Recording via the env file, the app errors out. Main error:

    {
    Nov 13 19:11:04 errno: -2,
    Nov 13 19:11:04 code: 'ENOENT',
    Nov 13 19:11:04 syscall: 'mkdir',
    Nov 13 19:11:04 path: '/app/code/app/rec/'
    Nov 13 19:11:04 }
    

    So, is it not currently possible to enable Recording at all (Local/S3) ?

    MiroTalkM Offline
    MiroTalkM Offline
    MiroTalk
    wrote on last edited by
    #10

    @shrey said in MiroTalk SFU: Recording not possible?:

    {
    Nov 13 19:11:04 errno: -2,
    Nov 13 19:11:04 code: 'ENOENT',
    Nov 13 19:11:04 syscall: 'mkdir',
    Nov 13 19:11:04 path: '/app/code/app/rec/'
    Nov 13 19:11:04 }

    I think the main issue is a missing volume mount:

    • The container is trying to create /app/code/app/rec/, but this path doesn’t exist inside the container and isn’t mapped to any mounted volume.
    • Since Docker containers are isolated, any folder that isn’t part of a volume or explicitly created inside the container won’t persist and may fail to be created due to permissions.

    Something like:

    volumes:
      - /mirotalksfu-path-on-cloudron/app/rec:/app/code/app/rec
      - /mirotalksfu-path-on-cloudron/app/rtmp:/app/code/app/rtmp
    

    This way, both /rec and /rtmp directories are properly mounted and writable.

    1 Reply Last reply
    0
    • MiroTalkM Offline
      MiroTalkM Offline
      MiroTalk
      wrote on last edited by
      #11

      Ok from what understand: Cloudron allows writing only to /app/data, while /app/code is read-only, so all dynamic folders (rec, rtmp, uploads, etc.) must be moved into /app/data.

      1 Reply Last reply
      0
      • nebulonN Offline
        nebulonN Offline
        nebulon
        Staff
        wrote on last edited by
        #12

        Thanks for all the insights here. So I think the folder to store recordings should then default to /app/data/rec or so with an option to configure that to use a different volume (not sure how large those recordings are)

        For RTMP_DIR is this some kind of temporary directory and thus maybe should be configured as /tmp/... or maybe even /run/... ?

        1 Reply Last reply
        0
        • MiroTalkM Offline
          MiroTalkM Offline
          MiroTalk
          wrote on last edited by MiroTalk
          #13

          Yeah, setting the recordings directory RECORDING_DIR to /app/data/rec makes sense. This keeps all generated recordings inside the application’s persistent data area, which is consistent and easy to manage.

          Regarding RTMP_DIR, it is not a temporary directory.
          This directory is used to store the media files that will be streamed via RTMP. Since these files may need to remain available for repeated or scheduled streaming, it’s better to keep them in a persistent and organized location. Can be also in /app/data/rtmp as consistent with the rest of the project’s data layout.

          So in summary:

          • RECORDING_DIR → /app/data/rec
            Stores recordings generated by the application.

          • RTMP_DIR → /app/data/rtmp
            Stores video files intended for RTMP streaming, not temporary, should persist.

          1 Reply Last reply
          0
          • nebulonN Offline
            nebulonN Offline
            nebulon
            Staff
            wrote on last edited by
            #14

            perfect, I will prepare a package update then. So just to double check, this only applies to the SFU flavor of mirotalk?

            1 Reply Last reply
            0
            • MiroTalkM Offline
              MiroTalkM Offline
              MiroTalk
              wrote on last edited by
              #15

              perfect, I will prepare a package update then. So just to double check, this only applies to the SFU flavor of mirotalk?

              WIP on MiroTalk SFU: Let me fix this first, then I’ll ping you when done 🙂

              1 Reply Last reply
              1
              • nebulonN Offline
                nebulonN Offline
                nebulon
                Staff
                wrote on last edited by
                #16

                in case your code would ensure the paths via "mkdirp()" it would make the package code easier 🙂

                1 Reply Last reply
                1
                • MiroTalkM Offline
                  MiroTalkM Offline
                  MiroTalk
                  wrote on last edited by MiroTalk
                  #17

                  @nebulon @James @shrey

                  Implemented in MiroTalk SFU v2.0.14 — Docker image is building now (available in ~1 hour).

                  • Commit
                  • Build

                  For Cloudron deployments, server-side recording should now work using the following configuration:

                  Recording

                  RECORDING_ENABLED=true
                  RECORDING_DIR='../data/rec'            # Path relative to /app/code → resolves to /app/data/rec
                  RECORDING_MAX_FILE_SIZE=1073741824     # Max file size in bytes (default: 1GB)
                  

                  RTMP

                  RTMP_DIR='../data/rtmp'                # Path relative to /app/code → resolves to /app/data/rtmp
                  

                  Note

                  If the target directories do not exist, MiroTalk SFU will automatically create them at runtime, just like before.

                  Cloudron automatically mounts /app/data, so using ../data/... ensures the app writes to the persistent, writable directory.

                  1 Reply Last reply
                  6
                  • nebulonN Offline
                    nebulonN Offline
                    nebulon
                    Staff
                    wrote on last edited by
                    #18

                    New package is out. Thanks for all the work @mirotalk-57bab571 and being so proactive here!

                    MiroTalkM 1 Reply Last reply
                    4
                    • nebulonN nebulon

                      New package is out. Thanks for all the work @mirotalk-57bab571 and being so proactive here!

                      MiroTalkM Offline
                      MiroTalkM Offline
                      MiroTalk
                      wrote on last edited by MiroTalk
                      #19

                      @nebulon said in MiroTalk SFU: Recording not possible?:

                      New package is out. Thanks for all the work @mirotalk-57bab571 and being so proactive here!

                      Good! I’m always here to help. Thanks to Cloudron for trusting MiroTalk and supporting us! By the way, I love the new Cloudron UI v.9.0.10, it looks amazing!

                      1 Reply Last reply
                      4
                      • MiroTalkM Offline
                        MiroTalkM Offline
                        MiroTalk
                        wrote on last edited by
                        #20

                        PS: Thanks also to @James for his IT support and excellent debugging and suggestions.

                        1 Reply Last reply
                        3
                        • S Offline
                          S Offline
                          shrey
                          wrote on last edited by
                          #21

                          Hi @nebulon @mirotalk-57bab571
                          So, i'm still unable to boot up the app after setting RECORDING_ENABLED=true :

                          Nov 15 09:36:54 node:fs:1364
                          Nov 15 09:36:54 const result = binding.mkdir(
                          Nov 15 09:36:54 ^
                          Nov 15 09:36:54 2025-11-15T04:06:54Z
                          Nov 15 09:36:54 Error: ENOENT: no such file or directory, mkdir '/app/code/app/rec/'
                          Nov 15 09:36:54 at Object.mkdirSync (node:fs:1364:26)
                          Nov 15 09:36:54 at Object.<anonymous> (/app/code/app/src/Server.js:280:12)
                          Nov 15 09:36:54 at Module._compile (node:internal/modules/cjs/loader:1554:14)
                          Nov 15 09:36:54 at Object..js (node:internal/modules/cjs/loader:1706:10)
                          Nov 15 09:36:54 at Module.load (node:internal/modules/cjs/loader:1289:32)
                          Nov 15 09:36:54 at Function._load (node:internal/modules/cjs/loader:1108:12)
                          Nov 15 09:36:54 at TracingChannel.traceSync (node:diagnostics_channel:322:14)
                          Nov 15 09:36:54 at wrapModuleLoad (node:internal/modules/cjs/loader:220:24)
                          Nov 15 09:36:54 at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
                          Nov 15 09:36:54 at node:internal/main/run_main_module:36:49 {
                          Nov 15 09:36:54 errno: -2,
                          Nov 15 09:36:54 code: 'ENOENT',
                          Nov 15 09:36:54 syscall: 'mkdir',
                          Nov 15 09:36:54 path: '/app/code/app/rec/'
                          Nov 15 09:36:54 }
                          Nov 15 09:36:54 2025-11-15T04:06:54Z
                          Nov 15 09:36:54 Node.js v22.14.0
                          Nov 15 09:36:54 \
                          
                          MiroTalkM 1 Reply Last reply
                          0
                          • S shrey

                            Hi @nebulon @mirotalk-57bab571
                            So, i'm still unable to boot up the app after setting RECORDING_ENABLED=true :

                            Nov 15 09:36:54 node:fs:1364
                            Nov 15 09:36:54 const result = binding.mkdir(
                            Nov 15 09:36:54 ^
                            Nov 15 09:36:54 2025-11-15T04:06:54Z
                            Nov 15 09:36:54 Error: ENOENT: no such file or directory, mkdir '/app/code/app/rec/'
                            Nov 15 09:36:54 at Object.mkdirSync (node:fs:1364:26)
                            Nov 15 09:36:54 at Object.<anonymous> (/app/code/app/src/Server.js:280:12)
                            Nov 15 09:36:54 at Module._compile (node:internal/modules/cjs/loader:1554:14)
                            Nov 15 09:36:54 at Object..js (node:internal/modules/cjs/loader:1706:10)
                            Nov 15 09:36:54 at Module.load (node:internal/modules/cjs/loader:1289:32)
                            Nov 15 09:36:54 at Function._load (node:internal/modules/cjs/loader:1108:12)
                            Nov 15 09:36:54 at TracingChannel.traceSync (node:diagnostics_channel:322:14)
                            Nov 15 09:36:54 at wrapModuleLoad (node:internal/modules/cjs/loader:220:24)
                            Nov 15 09:36:54 at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:170:5)
                            Nov 15 09:36:54 at node:internal/main/run_main_module:36:49 {
                            Nov 15 09:36:54 errno: -2,
                            Nov 15 09:36:54 code: 'ENOENT',
                            Nov 15 09:36:54 syscall: 'mkdir',
                            Nov 15 09:36:54 path: '/app/code/app/rec/'
                            Nov 15 09:36:54 }
                            Nov 15 09:36:54 2025-11-15T04:06:54Z
                            Nov 15 09:36:54 Node.js v22.14.0
                            Nov 15 09:36:54 \
                            
                            MiroTalkM Offline
                            MiroTalkM Offline
                            MiroTalk
                            wrote on last edited by MiroTalk
                            #22

                            @shrey said in MiroTalk SFU: Recording not possible?:

                            So, i'm still unable to boot up the app after setting RECORDING_ENABLED=true

                            Forget the previous env configuration. In the latest Cloudron commit, recording is enabled by default, and the app/data path now appears to be automatically resolved as well.

                            rec.png

                            1 Reply Last reply
                            0
                            • S Offline
                              S Offline
                              shrey
                              wrote on last edited by
                              #23

                              @mirotalk-57bab571

                              I restarted the updated app, but i still get only this:
                              image.png

                              No rec folder available, and no default recording taking place.

                              image.png

                              1 Reply Last reply
                              0
                              • S Offline
                                S Offline
                                shrey
                                wrote on last edited by shrey
                                #24

                                @mirotalk-57bab571

                                It seems like 2 separate updated packages have been released for this.
                                Just came across the 2nd one and updated the app again.

                                1. The rec folder is now available in /app/data/
                                2. All recordings are still being saved on the local device only. No server-side recording. No S3 recording.
                                jamesJ 1 Reply Last reply
                                0
                                • S shrey

                                  @mirotalk-57bab571

                                  It seems like 2 separate updated packages have been released for this.
                                  Just came across the 2nd one and updated the app again.

                                  1. The rec folder is now available in /app/data/
                                  2. All recordings are still being saved on the local device only. No server-side recording. No S3 recording.
                                  jamesJ Offline
                                  jamesJ Offline
                                  james
                                  Staff
                                  wrote on last edited by
                                  #25

                                  Hello @shrey
                                  I have just updated my Mirotalk SFU app and now the recordings are stored inside the Mirotalk SFU app in /app/data/rec/.
                                  Please share your /app/data/env file.
                                  With the updated app and a fresh installed app the recording works.
                                  In a meeting I can do:
                                  25148661-faea-4ff2-9c2d-854f2cc505d2-image.png

                                  0d480e1b-0961-49df-a606-a2eaee3e27d0-image.png

                                  ls -lah /app/data/rec/
                                  total 5.2M
                                  drwxr-xr-x 2 cloudron cloudron 4.0K Nov 15 09:46 .
                                  drwxr-xr-x 3 cloudron cloudron 4.0K Nov 15 09:44 ..
                                  -rw-r--r-- 1 cloudron cloudron 5.2M Nov 15 09:46 Rec_09598YoungSpid_2025_11_15_10_45_32_e0005370-10dd-4487-a68e-cff4d94f274d.webm
                                  
                                  1 Reply Last reply
                                  1
                                  • S Offline
                                    S Offline
                                    shrey
                                    wrote on last edited by
                                    #26

                                    Hi @james , thanks for the screenshots. I can now see that there's a "Save on server" option in the UI, and it's working for me as well.

                                    Now, just S3 is left to work.
                                    My env file ->

                                    # Recording
                                    RECORDING_ENABLED=true                           # Enable recording functionality (true|false)
                                    RECORDING_UPLOAD_TO_S3=false                      # Upload recording to AWS S3 bucket [true/false]
                                    
                                    # AWS S3 Configuration  
                                    AWS_S3_ENABLED=true                              # Enable AWS S3 storage (true|false)  
                                    AWS_S3_BUCKET_NAME=<bucket-name>                       # Name of your S3 bucket (must exist)  
                                    AWS_ACCESS_KEY_ID=<key-id>                                # AWS Access Key ID (leave empty for IAM roles)  
                                    AWS_SECRET_ACCESS_KEY=<key-secret>                            # AWS Secret Access Key (leave empty for IAM roles)  
                                    AWS_REGION=<region>                                   # AWS region (e.g., us-east-2, eu-west-2)  
                                    AWS_S3_ENDPOINT=https://<region>.digitaloceanspaces.com
                                    

                                    Note: Although i didn't find the "AWS_S3_ENDPOINT" key in the env template, i configured it because it seems to work with most S3 client libraries, and is a necessity to be able to connect to S3 spaces other than AWS.

                                    MiroTalkM 1 Reply Last reply
                                    0
                                    • jamesJ Offline
                                      jamesJ Offline
                                      james
                                      Staff
                                      wrote on last edited by
                                      #27

                                      Hello @shrey
                                      The library used in MiroTalk SFU for AWS/S3 is aws-sdk/client-s3.
                                      It seems MiroTalk SFU does not have the option to configure the endpoint.
                                      From the MiroTalk SFU Code handling the configuration:

                                      https://github.com/miroslavpejic85/mirotalksfu/blob/b2a41e597610524b259097d2e1b52674dda631c0/app/src/config.template.js#L948-L954

                                              aws: {
                                                  enabled: process.env.AWS_S3_ENABLED === 'true',
                                                  accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'your-access-key-id',
                                                  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'your-secret-access-key',
                                                  region: process.env.AWS_REGION || 'us-east-2',
                                                  bucket: process.env.AWS_S3_BUCKET || 'mirotalk',
                                              },
                                      

                                      Also in the server.js where the S3Client is initialized, the endpoint is never configured, thus using the default, resolving the endpoint from the AWS_REGION.
                                      https://github.com/miroslavpejic85/mirotalksfu/blob/b2a41e597610524b259097d2e1b52674dda631c0/app/src/Server.js#L297-L303

                                      const s3Client = new S3Client({
                                          region: config?.integrations?.aws?.region, // Set your AWS region
                                          credentials: {
                                              accessKeyId: config?.integrations?.aws?.accessKeyId,
                                              secretAccessKey: config?.integrations?.aws?.secretAccessKey,
                                          },
                                      });
                                      

                                      So we need to ask @mirotalk-57bab571 to add the option to configure the endpoint as well.
                                      Adding to that, when a non AWS endpoint is used, the option forcePathStyle: true might also be needed for the best compatibility with e.g. MinIO and most S3-compatible systems.


                                      @mirotalk-57bab571
                                      It is the weekend, please don't feel pressured or forced to work on the weekend.
                                      Would it be possible to add the option to configure the S3Client endpoint config and S3Client forcePathStyle config?

                                      MiroTalkM 1 Reply Last reply
                                      2
                                      • jamesJ james

                                        Hello @shrey
                                        The library used in MiroTalk SFU for AWS/S3 is aws-sdk/client-s3.
                                        It seems MiroTalk SFU does not have the option to configure the endpoint.
                                        From the MiroTalk SFU Code handling the configuration:

                                        https://github.com/miroslavpejic85/mirotalksfu/blob/b2a41e597610524b259097d2e1b52674dda631c0/app/src/config.template.js#L948-L954

                                                aws: {
                                                    enabled: process.env.AWS_S3_ENABLED === 'true',
                                                    accessKeyId: process.env.AWS_ACCESS_KEY_ID || 'your-access-key-id',
                                                    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY || 'your-secret-access-key',
                                                    region: process.env.AWS_REGION || 'us-east-2',
                                                    bucket: process.env.AWS_S3_BUCKET || 'mirotalk',
                                                },
                                        

                                        Also in the server.js where the S3Client is initialized, the endpoint is never configured, thus using the default, resolving the endpoint from the AWS_REGION.
                                        https://github.com/miroslavpejic85/mirotalksfu/blob/b2a41e597610524b259097d2e1b52674dda631c0/app/src/Server.js#L297-L303

                                        const s3Client = new S3Client({
                                            region: config?.integrations?.aws?.region, // Set your AWS region
                                            credentials: {
                                                accessKeyId: config?.integrations?.aws?.accessKeyId,
                                                secretAccessKey: config?.integrations?.aws?.secretAccessKey,
                                            },
                                        });
                                        

                                        So we need to ask @mirotalk-57bab571 to add the option to configure the endpoint as well.
                                        Adding to that, when a non AWS endpoint is used, the option forcePathStyle: true might also be needed for the best compatibility with e.g. MinIO and most S3-compatible systems.


                                        @mirotalk-57bab571
                                        It is the weekend, please don't feel pressured or forced to work on the weekend.
                                        Would it be possible to add the option to configure the S3Client endpoint config and S3Client forcePathStyle config?

                                        MiroTalkM Offline
                                        MiroTalkM Offline
                                        MiroTalk
                                        wrote on last edited by
                                        #28

                                        @james said in MiroTalk SFU: Recording not possible?:

                                        Would it be possible to add the option to configure the S3Client endpoint config and S3Client forcePathStyle config?

                                        So the goal is to avoid hard-coding support only for AWS S3.
                                        To extend the configuration so it also supports any S3-compatible storage (MinIO, Wasabi, DigitalOcean Spaces, etc.), i need to add the following to the .env file:

                                        AWS_S3_ENDPOINT=                     # e.g., http://localhost:9000 for MinIO
                                        AWS_S3_FORCE_PATH_STYLE=false        # Set to true for S3-compatible services
                                        

                                        Then expose these values in config.js:

                                        aws: {
                                            // ...
                                            endpoint: process.env.AWS_S3_ENDPOINT || '',
                                            forcePathStyle: process.env.AWS_S3_FORCE_PATH_STYLE === 'true',
                                        },
                                        

                                        Finally, update the S3 client configuration in Server.js:

                                        const s3Client = new S3Client({
                                            // ...
                                            endpoint: config?.integrations?.aws?.endpoint || undefined,
                                            forcePathStyle: config?.integrations?.aws?.forcePathStyle === true,
                                        });
                                        

                                        With this setup, the application continues to work with AWS S3 as it currently does, but can also switch to any S3-compatible service simply by adjusting environment variables and no additional code changes required.

                                        Sounds good to me! @James just confirm.

                                        1 Reply Last reply
                                        3
                                        • jamesJ Offline
                                          jamesJ Offline
                                          james
                                          Staff
                                          wrote on last edited by
                                          #29

                                          Hello @mirotalk-57bab571

                                          LGTM!
                                          Maybe adding a doc string in the env to AWS_S3_ENDPOINT that if left empty it will use region to resolve it automatically.

                                          1 Reply Last reply
                                          1
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Bookmarks
                                          • Search