{"id":34637325,"url":"https://github.com/andiserg/simple-cdn-server","last_synced_at":"2026-04-13T04:02:23.918Z","repository":{"id":186193291,"uuid":"674537957","full_name":"andiserg/simple-cdn-server","owner":"andiserg","description":"🌐☁️Cloud file storage service with file synchronization functionality across different servers.","archived":false,"fork":false,"pushed_at":"2024-08-05T21:08:32.000Z","size":139,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-20T06:50:02.003Z","etag":null,"topics":["aiohttp","cdn","docker","docker-compose","nginx","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andiserg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-04T07:26:24.000Z","updated_at":"2024-08-02T14:04:45.000Z","dependencies_parsed_at":"2024-01-08T20:30:55.449Z","dependency_job_id":"dcf82002-89a3-4a5a-be59-c4b43295fdf4","html_url":"https://github.com/andiserg/simple-cdn-server","commit_stats":null,"previous_names":["andrewsergienko/test-cdn","andrewsergienko/simple-cdn-server","andiserg/simple-cdn-server"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/andiserg/simple-cdn-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andiserg%2Fsimple-cdn-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andiserg%2Fsimple-cdn-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andiserg%2Fsimple-cdn-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andiserg%2Fsimple-cdn-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andiserg","download_url":"https://codeload.github.com/andiserg/simple-cdn-server/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andiserg%2Fsimple-cdn-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28005408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiohttp","cdn","docker","docker-compose","nginx","python"],"created_at":"2025-12-24T17:04:24.356Z","updated_at":"2025-12-24T17:08:37.616Z","avatar_url":"https://github.com/andiserg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003ca href=\"https://ibb.co/gv0Dm98\"\u003e\u003cimg src=\"https://i.ibb.co/JxYzmtT/kindpng-1795925-1.png\" alt=\"kindpng-1795925-1\" border=\"0\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n# Simple CDN server\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://codecov.io/gh/AndrewSergienko/simple-cdn-server\" \u003e\n     \u003cimg src=\"https://codecov.io/gh/AndrewSergienko/simple-cdn-server/branch/master/graph/badge.svg?token=PHAIHK4J5U\"/\u003e\n    \u003c/a\u003e\n    \u003cimg src=\"https://img.shields.io/badge/python-3.10-blue?logo=python\" alt=\"Python Version\"\u003e\n    \u003ca href=\"https://github.com/AndrewSergienko/simple-cdn-server/actions\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/tests-passed-green?logo=github\" alt=\"Actions\"\u003e\n    \u003c/a\u003e\n    \u003ca href=https://results.pre-commit.ci/latest/github/AndrewSergienko/simple-cdn-server/master\u003e\n        \u003cimg src=https://results.pre-commit.ci/badge/github/AndrewSergienko/simple-cdn-server/master.svg\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg src=\"https://img.shields.io/badge/code_style-black-black\" alt=\"black\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Про проект\nСервіс - хмарне сховище файлів. Надає можливість зберігати файли, які завантажаються\nпо посиланню. Після завантаження файлу проводить його реплікацію на інші вказані сервери, з яких він стає доступним для завантаження.\n\n## Як працює сервіс\nНа момент публікації записки, запущені 4 сервери:\n\u003cimg src=\"https://i.ibb.co/RDB2mq1/2023-08-15-11-30-27.png\" alt=\"2023-08-15-11-30-27\" border=\"0\"\u003e\n\nТри файлові серери в різних локаціях: Франкфурт, Нью-Йорк, Сінгапур, та один головний сервер у Франкфурті.\n\nОднією із головних частин є те, що запит надсилається до найближчого сервера від користувача. Для цього\nбув налаштований гео ДНС Gcore. Нижче наведена мапа, на якій показані зони дії кожного сервера.\n\u003cimg src=\"https://i.ibb.co/TMxdhGK/image.png\" alt=\"image\" border=\"0\"\u003e\n\nНа кожному сервері стоїть сервіс **Simple CDN Server** який працює наступним чином:\n- Користувач через головний сервер надсилає посилання для завантаження файлу;\n- Головний ервер визначає, який сервер находиться ближче до файлу та дає йому завдання завантажити файл;\n- Файловий сервер завантажує та зберігає файл;\n- Сервер проводить реплікацію файла на інші сервери;\n- Файл стає доступним для завантаження на всих серверах.\n\nВ результаті, завантажений файл збережений на всих серверах і швидкість його завантаження менше залежить від\nрозташування користувача завдяки багатьом серверам по світу та Geo DNS, який направляє користувача до найближчого сервера.\n\n## Про розробку\nПодійно-орієнтована архітектура додатку спроектована із застосуванням принципу чистої архітектури,\nде програма була поділена на шари, залежніть між якими була організована за допомогою Dependency Injection.\n\nРозробка проводилась по принципу TDD, де перед розробкою функціоналу спочатку розробляються тести для нього,\nв одночас формуються головні та додаткові, неочевидні вимоги.\nДля швидкого та ефективного тестування було створені шари-імітації, що дозволило ефективніше тестувати окремі частини додатку.\nТаким чином, тестуючи сервісний шар, де потрібно протестувати саме сервісний метод\nбез методів адаптерів, які він викликає в собі, сервісний метод викликає натомість функції-заглушки, які повертають\nрезультат очікуваного формату, заощаджучи час тестування.\n\nЗавантаження файлу відбувається в потоковому режимі за для запобігання ситуацій, коли об'єм файлу перевищує об'єм ОЗУ,\nщо викликає собою збій роботи сервера, що є критичним.\n\nДля автоматичних тестів та розгортання був застосований GitHub Actions. Для контейнеризації був застосований Docker.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandiserg%2Fsimple-cdn-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandiserg%2Fsimple-cdn-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandiserg%2Fsimple-cdn-server/lists"}