# Web-приложение на C# Microsoft (.NET) с подключением к SQLite **Чтобы развернуть приложение в Amvera, нужно выполнить следующие простые шаги:** 1. Открываем страницу https://cloud.amvera.ru/projects 2. Нажимаем кнопку *Создать* и выбираем *тип сервиса* **приложение**. 3. Выгружаем все файлы (можно через git, а можно через интерфейс). Не забудьте добавить конфигурационный файл (amvera.yml) и/или Dockerfile. 4. После этого начнется [сборка](https://docs.amvera.ru/applications/build.html) и [развертывание](https://docs.amvera.ru/applications/run.html) приложения. Дождитесь появления статуса «Успешно развернуто». Рассмотрим процесс подробнее. ## Напишем простое веб-приложение, которое при открытии сайта выводит всю информацию из базы данных. Будем использовать веб-фреймворк ASP.NET и базу данных SQLite. ## Создание проекта Для начала создадим новый проект (веб-приложение) с именем "WebService": ```bash $ dotnet new web -n WebService ``` Создалась директория *WebService*, перейдем в нее: ```bash $ cd WebService ``` Так как мы будем использовать SQLite, то необходимо его добавить в проект: ```bash $ dotnet add package System.Data.SQLite ``` ## База данных (SQLite) В файле *Program.cs* (код доступен в конце документации) реализовано взаимодействие с базой данных. Для использования SQLite в Amvera отдельное приложение/контейнер не требуется. Достаточно в коде указать путь для хранения файлов этой БД в постоянное хранилище. Подробнее можно прочитать [здесь](https://docs.amvera.ru/databases/sqlite.html). > **Важно**: обратите внимание на указанный путь к базе данных. Сохранять изменяемые файлы (базы данных и т.д.) нужно именно в постоянное хранилище /data. Это позволит избежать их потери при пересборке. Папка data в коде и постоянное хранилище /data - разные директории. ## Конфигурация ## amvera.yml Написать yaml файл можно как самостоятельно, так и воспользоваться нашим генератором yaml, перейдя по [ссылке](https://manifest.amvera.ru/), либо заполнить в разделе «Конфигурация» личного кабинета. **Пример файла amvera.yml:** ```yaml meta: environment: csharp toolchain: name: dotnet version: 8.0 build: image: mcr.microsoft.com/dotnet/sdk:8.0 run: image: mcr.microsoft.com/dotnet/sdk:8.0 buildFileName: bin/WebService persistenceMount: /data containerPort: 8080 ``` > **Важно:** Поле buildFileName должно быть в формате bin/имя_файла, либо bin/publish/имя_файла если вы делаете через публикацию. > **Важно:** Обратите внимание на *containerPort*. При создании приложения в *Program.cs* порт явно не указывается, поэтому используется значение по умолчанию (8080). Если в файле *amvera.yml* указан неправильный порт, то возникнет ошибка "Service Unavailable 503". Amvera по умолчанию слушает порт 80. Рассмотрим альтернативный способ задания конфигурации - через *Dockerfile*. ## Dockerfile > Замечание: если вы используете Dockerfile, то конфигурационный файл amvera.yml в большинстве случаев можно не добавлять. ### Шаги: 1. Создаем Dockerfile в директории с проектом. 2. В Dockerfile указываем базовый образ для этапа сборки: ```dockerfile FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build ``` > вместо 8.0 можете указать любую другую версию, которая вам нужна. 3. Устанавливаем рабочий каталог внутри контейнера: ```dockerfile WORKDIR /app ``` 4. Копируем файл *WebService.csproj* в контейнер: ```dockerfile COPY WebService.csproj ./ ``` 5. Восстанавливаем зависимости: ```dockerfile RUN dotnet restore ``` 6. Копируем все файлы проекта в контейнер: ```dockerfile COPY . ./ ``` 7. Публикуем приложение для релиза: ```dockerfile RUN dotnet publish -c Release -o WebService ``` 8. Указываем базовый образ для этапа запуска: ```dockerfile FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime ``` 9. Устанавливаем рабочий каталог внутри контейнера: ```dockerfile WORKDIR /app ``` 10. Копируем опубликованный результат из этапа сборки: ```dockerfile COPY --from=build /app/WebService ./ ``` 11. Устанавливаем точку входа для контейнера: ```dockerfile ENTRYPOINT ["dotnet", "WebService.dll"] ``` **Получившийся Dockerfile:** ```dockerfile FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /app COPY WebService.csproj ./ RUN dotnet restore COPY . ./ RUN dotnet publish -c Release -o WebService FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime WORKDIR /app COPY --from=build /app/WebService ./ ENTRYPOINT ["dotnet", "WebService.dll"] ``` **Пример файла amvera.yml при использовании вместе с Dockerfile:** ```yaml meta: environment: docker toolchain: name: docker version: latest build: dockerfile: Dockerfile skip: false run: persistenceMount: /data containerPort: 8080 ``` ## Создание проекта в Amvera Последний шаг - развернуть приложение. В файле *Program.cs* содержится основной код и выполняется подключение к базе данных: **Program.cs** ```C# using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using System; using System.Data.SQLite; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); // Указываем путь к базе данных: var connectionString = "Data Source=../data/people.db;"; using var connection = new SQLiteConnection(connectionString); connection.Open(); var createTableCommand = connection.CreateCommand(); createTableCommand.CommandText = @" CREATE TABLE IF NOT EXISTS People ( Id INTEGER PRIMARY KEY, Name TEXT, Age INTEGER, Occupation TEXT ); "; createTableCommand.ExecuteNonQuery(); var insertDataCommand = connection.CreateCommand(); insertDataCommand.CommandText = @" INSERT OR IGNORE INTO People (Name, Age, Occupation) VALUES ('John Doe', 30, 'Engineer'), ('Jane Smith', 25, 'Teacher'), ('Michael Johnson', 35, 'Doctor'); "; insertDataCommand.ExecuteNonQuery(); app.MapGet("/", async () => { using var selectCommand = connection.CreateCommand(); selectCommand.CommandText = "SELECT * FROM People;"; using var reader = await selectCommand.ExecuteReaderAsync(); string result = "People Database:\n"; while (reader.Read()) { result += $"ID: {reader.GetInt32(0)}, Name: {reader.GetString(1)}, Age: {reader.GetInt32(2)}, Occupation: {reader.GetString(3)}\n"; } return result; }); app.Run(); ``` > При необходимости можете изменить путь к базе данных. > > Если не хотите использовать стандартный порт (8080), то можно указать другой. Но тогда важно учесть это изменение в конфигурационном файле. ## Проверка работоспособности 1. Переходим в настройки проекта и активируем доменное имя. 2. Теперь можно перейти по нему и откроется наш сайт с записями из базы данных. Если что-то не работает, рекомендуем ознакомиться с логами Сборки и Приложения. ## Видеопример ```{eval-rst} .. youtube:: -Ykk7FXpSmQ :align: center :width: 100% ``` ```{eval-rst} .. admonition:: Важно :class: warning Сохраняйте файлы БД и иные изменяемые данные в постоянное хранилище, чтобы избежать их потери при обновлении проекта, когда производится "откат" папки код до состояния обновления репозитория. Папка data в корне проекта и директория /data, это разные директории. Проверить, что сохранение идет в /data, можно зайдя в папку "data" на странице "Репозиторий". ``` ```{eval-rst} .. admonition:: Важно :class: warning Чтобы избежать ошибки 502, измените в вашем коде host 127.0.0.1 (или подобный localhost) на 0.0.0.0, и пропишите в конфигурации порт, который слушает ваше приложение (пример - 8080). ``` Поздравляем, вы успешно создали свое первое приложение в Amvera! ## Если у вас не получается развернуть проект Напишите наблюдаемую вами симптоматику на support@amvera.ru с указанием вашего имени пользователя и названия проекта, мы постараемся вам помочь.