Video upload stops prematurely on backend server, but works well on localhost

I am working on a React project where I sell courses, and when I try to upload a video file larger than 1 GB, the upload process always stops midway. However, other files smaller than that upload without any issues.

I’m not using AWS or any other services; I’m trying to store the videos directly on my backend server (Cyber Panel).
How can I fix this? I’m still learning about this topic.

here is my code in backend

 export const uploadMultiplePelatihanVideo = async (req, res) => {
//   if (!req.files || !req.files.files) {
//     return res.status(400).json({ msg: "Tidak ada file yang diunggah." });
//   }

  const files = Array.isArray(req.files.files) ? req.files.files : [req.files.files];
  const allowedExt = [".mp4", ".avi", ".mkv"]; // Format video yang diizinkan
  const maxFileSize = 10000000000; // Batas ukuran file video 10000 MB
  const uploadedVideos = [];
  const title = req.body.title || "Tanpa Judul";

  try {
    const pelatihan = await Pelatihan.findOne({
      where: { pelatihanId: req.params.pelatihanId }
    });

    if (!pelatihan) {
      return res.status(404).json({ msg: "Pelatihan tidak ditemukan." });
    }

   
    // Loop melalui setiap file video yang diunggah
    for (const file of files) {
      const fileSize = file.data.length;
      const ext = path.extname(file.name);
      const fileName = uuidv4() + ext;
      const url = `${req.protocol}://${req.get("host")}/videos/pelatihan/${fileName}`;

      // Validasi ekstensi dan ukuran file
      if (!allowedExt.includes(ext.toLowerCase())) {
        return res.status(422).json({ msg: "Silakan unggah file video saja." });
      }

      if (fileSize > maxFileSize) {
        return res.status(422).json({ msg: `Ukuran file ${file.name} terlalu besar, maksimal 1000 MB.` });
      }

      // Pindahkan file video baru ke direktori
      await file.mv(`public/videos/pelatihan/${fileName}`, async (err) => {
        if (err) {
          return res.status(500).json({ msg: "Gagal memindahkan file video." });
        }

        // Simpan informasi video ke database
        const video = await VideoPel.create({
          pelatihanId: pelatihan.pelatihanId,
          urlVideo: url,
          title, // Judul video dari body atau default
          deskripsi: req.body.deskripsi || null,  // Deskripsi dari body atau null
        });

        uploadedVideos.push({
          fileName,
          url,
          videoId: video.videoPelId,
        });
      });
    }

    // Mengirimkan response setelah semua video berhasil diunggah
    res.status(200).json({
      msg: "Video pelatihan berhasil diunggah.",
      uploadedVideos, // Mengembalikan daftar video yang berhasil diunggah
    });
  } catch (error) {
    console.error("Error uploading video:", error);
    res.status(500).json({ msg: "Terjadi kesalahan pada server." });
  }
};
  

and in the frontend

export const uploadMultiplePelatihanVideo = async (files, id, onUploadProgress) => {
  const token = sessionStorage.getItem("authToken"); // Mendapatkan token otentikasi dari sessionStorage
  

  try {
    const response = await axios.post(
      `${API_URL}/pelatihan/${id}/upload-full-video`, 
      files, 
      {
        headers: {
          Authorization: `Bearer ${token}`, // Menyertakan token otentikasi
          "Content-Type": "multipart/form-data", // Mengatur tipe konten
        },
        onUploadProgress: onUploadProgress,
        timeout: 0, // Set timeout to 0 (no timeout)
      }
    );

    // Menampilkan notifikasi sukses menggunakan SweetAlert2
    Swal.fire({
      icon: "success",
      title: "Berhasil mengupload video",
      text: "Semua video telah berhasil diupload ke pelatihan.",
    });

    return response.data; // Mengembalikan data respons dari server
  } catch (error) {
    // Menampilkan notifikasi error menggunakan SweetAlert2
    Swal.fire({
      icon: "error",
      title: "Gagal mengupload video",
      text: error.response?.data?.msg || "Terjadi kesalahan, silakan coba lagi.",
    });

    throw error; // Lempar error agar bisa ditangani di tempat lain jika diperlukan
  }
};
function editPelatihan(){
const [previewVideos, setPreviewVideos] = useState([]);
const [uploadProgress, setUploadProgress] = useState(0);


const handleMultipleVideoSubmit = async (e) => {
  e.preventDefault();
  const { videoPel, title } = formVideo;

  if (videoPel.length === 0) {
    Swal.fire({
      icon: "warning",
      title: "Video pelatihan tidak ada",
      text: "Silakan unggah video pelatihan terlebih dahulu.",
    });
    return;
  }

  try {
    const videoFormData = new FormData();
    videoPel.forEach(file => videoFormData.append('files', file));
    videoFormData.append('title', title);

    await uploadMultiplePelatihanVideo(videoFormData, pelatihanId, (progressEvent) => {
      const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
      setUploadProgress(percentCompleted);
    });

    Swal.fire({
      icon: "success",
      title: "Video pelatihan berhasil diunggah",
      text: "Semua video pelatihan telah berhasil ditambahkan ke pelatihan.",
    });
    setFormVideo({ 
      videoPel: [],
      title: "", // Reset title setelah upload
    });
    setPreviewVideos([]);
    setUploadProgress(0); // Reset progress after upload
  } catch (error) {
    Swal.fire({
      icon: "error",
      title: "Gagal mengunggah video pelatihan",
      text: "Terjadi kesalahan saat mengunggah video pelatihan.",
    });
  }
};

return (
      <form className="space-y-4 mt-4">
          {/* Upload Video Pelatihan */}
          <div>
            <label htmlFor="videoPel" className="block text-sm font-medium text-gray-300">
              Upload Video Pelatihan
            </label>
            <input
              type="file"
              id="videoPel"
              name="videoPel"
              accept="video/*"
              multiple
              onChange={handleChange}
              className="mt-1 block w-full text-sm border border-gray-700 rounded-lg cursor-pointer text-gray-400 focus:outline-none bg-gray-700 placeholder-gray-400"
            />
            <input
              type="text"
              id="title"
              name="title"
              placeholder="Masukkan judul video"
              value={formVideo.title}
              onChange={handleChange}
              className="mt-1 block w-full text-sm border border-gray-300 rounded-lg shadow-sm focus:outline-none focus:ring-1 focus:ring-blue-500"
            />
            {previewVideos.length > 0 && (
              <div className="mt-2">
                {previewVideos.map((videoUrl, index) => (
                  <video key={index} src={videoUrl} controls className="mt-2 w-full max-h-64 object-cover rounded-md" />
                ))}
              </div>
            )}
            <button
              onClick={handleMultipleVideoSubmit}
              className="mt-2 bg-green-500 hover:bg-green-600 text-white py-2 px-4 rounded-lg"
            >
              Unggah Video Pelatihan
            </button>
          </div>
            <div className="mt-4">
              {uploadProgress > 0 && uploadProgress < 100 && (
                <div>
                  <progress value={uploadProgress} max="100" className="w-full" />
                  <span>{uploadProgress}%</span>
                </div>
              )}
            </div>
        </form>
)


}

Stuck like this: Screenshot

upload-full-video(failed)net::ERR_CONNECTION_CLOSEDxhr
Server side logs: No files uploaded.

The server has no upload limits.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật