bingo: serve datacenter bingo on bingo.asxp.io
Some checks failed
Tests / test (push) Successful in 18s
Build and Deploy to Production / test (push) Successful in 18s
Build and Deploy to Production / build (push) Failing after 2s
Build and Deploy to Production / deploy (push) Has been skipped

Add a second public site to the same process: a 5x5 card of the 25
largest Russian datacenters where a cell is crossed out once an incident
with a public source is recorded (Yandex Sasovo and Kaluga drone strikes
on 2026-10-08/09 are seeded). config.ru dispatches by Host, so it rides
the existing container, DB and bucket instead of a new deploy.

The card is localized ru/en/uk with per-locale columns falling back to
ru. Content is managed from /admin/bingo on asxp.io, reusing AdminAuth
and CSRF. Photos go to the existing bucket under bingo/ and are proxied
by the app, so the bucket stays private and storage needs no change.

The seed data was fact-checked against operator sites and press on
2026-10-10; several entries in the original list were wrong or vague.

Assisted-by: Claude:opus-5
This commit is contained in:
Sergei Poljanski 2026-10-10 04:51:26 +04:00
commit bdb3682e18
Signed by: asxpi
GPG key ID: 4F8851660FA4121B
19 changed files with 1428 additions and 2 deletions

449
db/bingo_seed.json Normal file
View file

@ -0,0 +1,449 @@
{
"datacenters": [
{
"slug": "ix-mos5",
"name_ru": "IXcellerate MOS5",
"name_en": "IXcellerate MOS5",
"name_uk": "IXcellerate MOS5",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "IXcellerate",
"mw": "64",
"status": "operational",
"year": 2021,
"photo_source_url": "https://www.ixcellerate.com/wp-content/uploads/2025/04/mos5_2-scaled.jpg",
"photo_credit": "© IXcellerate",
"info_url": "https://www.ixcellerate.com/data-centers/moscow-south-campus/",
"position": 1
},
{
"slug": "yandex-kaluga",
"name_ru": "Яндекс Калуга",
"name_en": "Yandex Kaluga",
"name_uk": "Яндекс Калуга",
"city_ru": "Калуга",
"city_en": "Kaluga",
"city_uk": "Калуга",
"operator": "Яндекс",
"mw": "63",
"status": "operational",
"year": 2023,
"photo_source_url": "https://storage.yandexcloud.net/cloud-www-assets/blog-assets/ru/posts/2022/scale/cloud-data-center-kaluga/kaluga_2.jpg",
"photo_credit": "© Yandex Cloud (визуализация)",
"info_url": "https://yandex.cloud/ru/blog/posts/2022/09/cloud-data-center-kaluga",
"position": 2
},
{
"slug": "kalininsky",
"name_ru": "ЦОД «Калининский»",
"name_en": "Kalininsky DC",
"name_uk": "ЦОД «Калінінський»",
"city_ru": "Удомля",
"city_en": "Udomlya",
"city_uk": "Удомля",
"operator": "Атомдата / Ростелеком",
"mw": "48",
"status": "operational",
"year": 2019,
"photo_source_url": "https://upload.wikimedia.org/wikipedia/commons/c/c8/%D0%A6%D0%9E%D0%94_%D0%9A%D0%B0%D0%BB%D0%B8%D0%BD%D0%B8%D0%BD%D1%81%D0%BA%D0%B8%D0%B9.jpg",
"photo_credit": "Sergei2709 / Wikimedia Commons, CC BY-SA 4.0",
"info_url": "https://www.comnews.ru/content/121093/2019-07-29/rostelekom-vvel-centr-obrabotki-dannyh-udomlya-v-promyshlennuyu-ekspluataciyu",
"position": 3
},
{
"slug": "yandex-vladimir-2",
"name_ru": "Яндекс Владимир-2",
"name_en": "Yandex Vladimir-2",
"name_uk": "Яндекс Владимир-2",
"city_ru": "Владимир",
"city_en": "Vladimir",
"city_uk": "Владимир",
"operator": "Яндекс",
"mw": ">40",
"status": "building",
"year": 2027,
"photo_source_url": "https://www.tadviser.ru/images/d/d9/Yan1.jpg",
"photo_credit": "Госстройнадзор Владимирской обл. / TAdviser",
"info_url": "https://www.cableman.ru/content/yandeks-zapuskaet-data-tsentr-vo-vladimirskoi-oblasti-s-moshchnostyu-bolee-40-mvt",
"position": 4
},
{
"slug": "ix-mos11",
"name_ru": "IXcellerate MOS11 «Вёшки»",
"name_en": "IXcellerate MOS11 Vyoshki",
"name_uk": "IXcellerate MOS11 «Вьошки»",
"city_ru": "Мытищи",
"city_en": "Mytishchi",
"city_uk": "Митищі",
"operator": "IXcellerate",
"mw": "40",
"status": "building",
"year": 2026,
"photo_source_url": "https://www.ixcellerate.com/wp-content/uploads/2025/12/vyoshki-campus5.jpg",
"photo_credit": "© IXcellerate (визуализация)",
"info_url": "https://www.ixcellerate.com/data-centers/moscow-veshki-campus/",
"position": 5
},
{
"slug": "rtk-medvedkovo-2",
"name_ru": "РТК-ЦОД Медведково-2",
"name_en": "RTK-DC Medvedkovo-2",
"name_uk": "РТК-ЦОД Медведково-2",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "РТК-ЦОД",
"mw": "36",
"status": "operational",
"year": 2024,
"photo_source_url": "https://upload.wikimedia.org/wikipedia/commons/b/b5/%D0%A6%D0%B5%D0%BD%D1%82%D1%80_%D0%BE%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B8_%D0%B4%D0%B0%D0%BD%D0%BD%D1%8B%D1%85_%28%D0%9C%D0%B5%D0%B4%D0%B2%D0%B5%D0%B4%D0%BA%D0%BE%D0%B2%D0%BE%29_20260621_121548.jpg",
"photo_credit": "Lesless / Wikimedia Commons, CC BY-SA 4.0",
"info_url": "https://www.interfax.ru/business/976641",
"position": 6
},
{
"slug": "atomdata-moskva-2",
"name_ru": "Атомдата «Москва-2»",
"name_en": "Atomdata Moskva-2",
"name_uk": "Атомдата «Москва-2»",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "Атомдата",
"mw": "36",
"status": "operational",
"year": 2024,
"photo_source_url": "https://atomdata.ru/upload/iblock/671/gchj4a2c7gwg0v18v1nqehosu4c8zgtz.jpg",
"photo_credit": "© АО «Атомдата»",
"info_url": "https://habr.com/ru/articles/795381/",
"position": 7
},
{
"slug": "3data-hsm",
"name_ru": "3data HyperScale Медведково",
"name_en": "3data HyperScale Medvedkovo",
"name_uk": "3data HyperScale Медведково",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "3data",
"mw": "36",
"status": "operational",
"year": 2023,
"photo_source_url": "https://3data.ru/1024/upload/1691061832_01.jpg",
"photo_credit": "© 3data",
"info_url": "https://3data.ru/dc/hsm",
"position": 8
},
{
"slug": "ix-mos3",
"name_ru": "IXcellerate MOS3",
"name_en": "IXcellerate MOS3",
"name_uk": "IXcellerate MOS3",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "IXcellerate",
"mw": "30",
"status": "operational",
"year": 2025,
"photo_source_url": "https://www.ixcellerate.com/wp-content/uploads/2025/11/IXC_0111-2.jpg",
"photo_credit": "© IXcellerate",
"info_url": "https://www.ixcellerate.com/data-centers/moscow-north-campus/",
"position": 9
},
{
"slug": "datapro-moscow-3",
"name_ru": "DataPro Moscow III",
"name_en": "DataPro Moscow III",
"name_uk": "DataPro Moscow III",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "DataPro",
"mw": "30",
"status": "operational",
"year": 2022,
"photo_source_url": "https://www.datapro.ru/assets/images/pages/data-centers/3/0.png",
"photo_credit": "© DataPro (иллюстрация)",
"info_url": "https://www.datapro.ru/data-centers/datapro-moscow-iii",
"position": 10
},
{
"slug": "mws-avantazh",
"name_ru": "MWS «Авантаж»",
"name_en": "MWS Avantazh",
"name_uk": "MWS «Авантаж»",
"city_ru": "Лыткарино",
"city_en": "Lytkarino",
"city_uk": "Литкаріно",
"operator": "MWS / МТС",
"mw": "20",
"status": "operational",
"year": 2018,
"photo_source_url": "https://habrastorage.org/r/w1560/webt/f3/mb/1a/f3mb1avrss4og8wlza4pspv4hzu.jpeg",
"photo_credit": "Т1 / Техносерв, Хабр",
"info_url": "https://www.comnews.ru/content/239118/2025-05-06/2025-w19/1010/mws-attestovala-odin-krupneyshikh-codov-rossii-vysshemu-urovnyu-zaschity-personalnykh-dannykh",
"position": 11
},
{
"slug": "oxygen-msk1",
"name_ru": "OXYGEN МСК-1",
"name_en": "OXYGEN MSK-1",
"name_uk": "OXYGEN МСК-1",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "OXYGEN",
"mw": "≈17",
"status": "operational",
"year": 2011,
"photo_source_url": "https://oxygen.cloud/wp-content/uploads/2024/09/msk_1.jpg",
"photo_credit": "© OXYGEN",
"info_url": "https://oxygen.cloud/data-center/",
"position": 12
},
{
"slug": "datahouse-m1",
"name_ru": "DataHouse «Магистральный-1»",
"name_en": "DataHouse Magistralny-1",
"name_uk": "DataHouse «Магістральний-1»",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "DataHouse",
"mw": "15",
"status": "operational",
"year": 2024,
"photo_source_url": "https://datahouse.ru/wp-content/themes/datahouse/frontend/build/src/img/dc-page-m1-01-01.jpg",
"photo_credit": "© DataHouse (визуализация)",
"info_url": "https://datahouse.ru/datacenter/magistralnyj-1/",
"position": 13
},
{
"slug": "megafon-spb",
"name_ru": "МегаФон Санкт-Петербург",
"name_en": "MegaFon St Petersburg",
"name_uk": "МегаФон Санкт-Петербург",
"city_ru": "Санкт-Петербург",
"city_en": "St Petersburg",
"city_uk": "Санкт-Петербург",
"operator": "МегаФон",
"mw": "до 14",
"status": "operational",
"year": 2025,
"photo_source_url": null,
"photo_credit": null,
"info_url": "https://corp.megafon.ru/press/news/federalnye_novosti/federal/20251009-1139.html",
"position": 14
},
{
"slug": "ix-mos1",
"name_ru": "IXcellerate MOS1",
"name_en": "IXcellerate MOS1",
"name_uk": "IXcellerate MOS1",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "IXcellerate",
"mw": "13,7",
"status": "operational",
"year": 2012,
"photo_source_url": "https://www.ixcellerate.com/wp-content/uploads/2022/04/mos1_3-scaled.jpg",
"photo_credit": "© IXcellerate",
"info_url": "https://www.ixcellerate.com/data-centers/moscow-north-campus/",
"position": 15
},
{
"slug": "ix-mos2",
"name_ru": "IXcellerate MOS2",
"name_en": "IXcellerate MOS2",
"name_uk": "IXcellerate MOS2",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "IXcellerate",
"mw": "13",
"status": "operational",
"year": 2019,
"photo_source_url": "https://ixcellerate.ru/wp-content/uploads/2025/07/mos2_8.jpg",
"photo_credit": "© IXcellerate",
"info_url": "https://ixcellerate.ru/data-centers/moscow-north-campus/",
"position": 16
},
{
"slug": "linx-spb",
"name_ru": "Linx Санкт-Петербург",
"name_en": "Linx St Petersburg",
"name_uk": "Linx Санкт-Петербург",
"city_ru": "Санкт-Петербург",
"city_en": "St Petersburg",
"city_uk": "Санкт-Петербург",
"operator": "Linx",
"mw": "12",
"status": "operational",
"year": null,
"photo_source_url": "https://linx.ru/upload/iblock/684/auw00pdcma1b24pxlgj2b0kewwppnkrl/Sp_10.jpg.webp",
"photo_credit": "© Linx",
"info_url": "https://linx.ru/datacenter/colocation/",
"position": 17
},
{
"slug": "keypoint-ekb",
"name_ru": "Key Point Екатеринбург",
"name_en": "Key Point Yekaterinburg",
"name_uk": "Key Point Єкатеринбург",
"city_ru": "Берёзовский",
"city_en": "Beryozovsky",
"city_uk": "Березовський",
"operator": "Key Point",
"mw": "11",
"status": "operational",
"year": 2026,
"photo_source_url": null,
"photo_credit": null,
"info_url": "https://rg.ru/2026/07/15/reg-urfo/cennost-tehnologij.html",
"position": 18
},
{
"slug": "datapro-moscow-2",
"name_ru": "DataPro Moscow II",
"name_en": "DataPro Moscow II",
"name_uk": "DataPro Moscow II",
"city_ru": "Химки",
"city_en": "Khimki",
"city_uk": "Хімки",
"operator": "DataPro",
"mw": "11",
"status": "operational",
"year": 2020,
"photo_source_url": "https://www.datapro.ru/assets/images/pages/data-centers/2/0.png",
"photo_credit": "© DataPro (иллюстрация)",
"info_url": "https://www.datapro.ru/data-centers/datapro-moscow-ii",
"position": 19
},
{
"slug": "selectel-berzarina",
"name_ru": "Selectel Берзарина",
"name_en": "Selectel Berzarina",
"name_uk": "Selectel Берзаріна",
"city_ru": "Москва",
"city_en": "Moscow",
"city_uk": "Москва",
"operator": "Selectel",
"mw": "10",
"status": "operational",
"year": null,
"photo_source_url": "https://selectel.ru/images/components/content/data-centers/berzarina-2.jpg",
"photo_credit": "© Selectel (машзал)",
"info_url": "https://selectel.ru/about/data-centers/",
"position": 20
},
{
"slug": "selectel-tsvetochnaya-2",
"name_ru": "Selectel Цветочная-2",
"name_en": "Selectel Tsvetochnaya-2",
"name_uk": "Selectel Цвєточна-2",
"city_ru": "Санкт-Петербург",
"city_en": "St Petersburg",
"city_uk": "Санкт-Петербург",
"operator": "Selectel",
"mw": "10",
"status": "operational",
"year": 2015,
"photo_source_url": "https://habrastorage.org/r/w1560/getpro/habr/post_images/215/75d/111/21575d1111b364f3112d7f76e9f8fcab.png",
"photo_credit": "Selectel, Хабр",
"info_url": "https://selectel.ru/about/data-centers/",
"position": 21
},
{
"slug": "yandex-sasovo",
"name_ru": "Яндекс Сасово",
"name_en": "Yandex Sasovo",
"name_uk": "Яндекс Сасово",
"city_ru": "Сасово",
"city_en": "Sasovo",
"city_uk": "Сасово",
"operator": "Яндекс",
"mw": null,
"status": "operational",
"year": 2014,
"photo_source_url": null,
"photo_credit": null,
"info_url": "https://www.vedomosti.ru/technology/articles/2026/10/08/1235289-chto-izvestno",
"position": 22
},
{
"slug": "rtk-ekb-3",
"name_ru": "РТК-ЦОД Екатеринбург-3",
"name_en": "RTK-DC Yekaterinburg-3",
"name_uk": "РТК-ЦОД Єкатеринбург-3",
"city_ru": "Екатеринбург",
"city_en": "Yekaterinburg",
"city_uk": "Єкатеринбург",
"operator": "РТК-ЦОД",
"mw": "6",
"status": "operational",
"year": 2018,
"photo_source_url": null,
"photo_credit": null,
"info_url": "https://www.comnews.ru/content/244980/2026-04-27/2026-w18/1007/bitva-za-ural-kto-zagruzit-novye-cody-ekaterinburga",
"position": 23
},
{
"slug": "rtk-nn",
"name_ru": "РТК-ЦОД Нижний Новгород",
"name_en": "RTK-DC Nizhny Novgorod",
"name_uk": "РТК-ЦОД Нижній Новгород",
"city_ru": "Нижний Новгород",
"city_en": "Nizhny Novgorod",
"city_uk": "Нижній Новгород",
"operator": "РТК-ЦОД",
"mw": "5",
"status": "operational",
"year": 2025,
"photo_source_url": "https://habrastorage.org/r/w1560/getpro/habr/upload_files/f8f/6b6/417/f8f6b6417ff5810a2efc00b7f71355c4.jpg",
"photo_credit": "РТК-ЦОД, Хабр",
"info_url": "https://www.comnews.ru/content/239515/2025-06-02/2025-w23/1011/rtk-cod-zapustil-data-centr-nizhnem-novgorode",
"position": 24
},
{
"slug": "selectel-dubrovka-1",
"name_ru": "Selectel Дубровка-1",
"name_en": "Selectel Dubrovka-1",
"name_uk": "Selectel Дубровка-1",
"city_ru": "Невская Дубровка",
"city_en": "Nevskaya Dubrovka",
"city_uk": "Невська Дубровка",
"operator": "Selectel",
"mw": "2,5",
"status": "operational",
"year": null,
"photo_source_url": "https://habrastorage.org/r/w1560/webt/c7/ye/v5/c7yev5bghjanyobpg0_mnxoiwlm.jpeg",
"photo_credit": "Selectel, Хабр",
"info_url": "https://selectel.ru/about/data-centers/",
"position": 25
}
],
"incidents": [
{
"slug": "yandex-sasovo",
"occurred_on": "2026-10-08",
"kind": "strike",
"title_ru": "Атака БПЛА и пожар, работа ЦОД полностью остановлена",
"title_en": "Drone strike and fire; the datacenter is fully shut down",
"title_uk": "Атака БПЛА та пожежа, роботу ЦОД повністю зупинено",
"url": "https://www.vedomosti.ru/technology/articles/2026/10/08/1235289-chto-izvestno"
},
{
"slug": "yandex-kaluga",
"occurred_on": "2026-10-09",
"kind": "strike",
"title_ru": "Удары БПЛА: часть инфраструктуры повреждена, несколько модулей выведены из строя",
"title_en": "Drone strikes: part of the infrastructure damaged, several modules knocked out",
"title_uk": "Удари БПЛА: частину інфраструктури пошкоджено, кілька модулів виведено з ладу",
"url": "https://www.bfm.ru/news/620355"
}
]
}

View file

@ -0,0 +1,39 @@
Sequel.migration do
change do
# Datacenter bingo (served on BINGO_HOST). Localized fields are plain
# per-locale columns; ru is the source of truth, en/uk fall back to it.
create_table(:bingo_datacenters) do
primary_key :id
String :slug, null: false, unique: true
Integer :position, null: false
String :name_ru, null: false
String :name_en
String :name_uk
String :city_ru, null: false
String :city_en
String :city_uk
String :operator, null: false
String :mw # free-form number: "64", "≈36", "25–30"
String :status, null: false, default: 'operational' # | building
Integer :year
String :photo_key # MinIO key under bingo/
String :photo_source_url, text: true
String :photo_credit
String :info_url, text: true
DateTime :created_at, null: false
end
create_table(:bingo_incidents) do
primary_key :id
foreign_key :datacenter_id, :bingo_datacenters, null: false, on_delete: :cascade
Date :occurred_on, null: false
String :kind, null: false # strike | fire | outage | flood | cooling | other
String :title_ru, null: false
String :title_en
String :title_uk
String :url, text: true
DateTime :created_at, null: false
index :datacenter_id
end
end
end