Сейчас вас научу «плохому» — будем поднимать наше веб-приложение на телефоне и прикрутим к нему публичный домен, что бы все могли пользоваться нашим классным сервисом.
Для этой цели я накидал приложение на go, которое определяет IP адрес, вычисляет город, отправляет запрос во внешний сервис и отдает страницу с данными о погоде в вашей локации. Я не стал упарываться — он просто нужен для демонстрации. https://github.com/itcaat/what-is-the-weather-now. Также там есть кеширование погоды и городов, но скорее всего хабраэффект его положит.
Дисклеймер
В статье мы просто развлекаемся и вообще это не продакшен-реди решение 😉 Но я почти уверен, что для себя вы найдете то, что сможете использовать в работе или пет-проекте.
Что нам нужно:
-
Само веб-приложение.
-
Установленный UserLAnd https://userland.tech/ ( root не потребуется )
-
GitHub Actions чтобы собрать приложение.
-
Бесплатный аккаунт на CloudFlare с нашим подключенным доменом — у меня будет devopsbrain.ru.
Итак, качаем UserLAnd можно с play market. В списке операционных систем выбираем Ubuntu (Minimal → Terminal) и сразу там сделаем sudo passwd userland чтобы установить пароль пользователя userland. У меня не пускало удаленно по ssh если просто passwd сделать. Я не стал разбираться, вроде на github есть какое то issue на эту тему. Поэтому едем дальше.
Теперь посмотрим в настройках wifi свой IP-адрес и подключимся с компа по ssh (порт 2022) и сразу установим пакетики.
ssh userland@192.168.1.75 -p2022 sudo apt update && apt install ca-certificates nano jq unzip -y
Само приложение и его сборка у меня уже готовы. Я собираю сразу под все платформы и архитектуры и качу релиз из main бранчи. Хотя нам нужен только arm64 для нашего эксперимента.
.github/workflows/release.yml
name: Build, Tag, and Release on: push: branches: - main env: appName: what-it-the-weather-now jobs: version: outputs: app_version: ${{ steps.version.outputs.new_tag }} changelog: ${{ steps.version.outputs.changelog }} runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 - name: Bump version and push tag id: version uses: mathieudutour/github-tag-action@v6.2 with: github_token: ${{ secrets.GITHUB_TOKEN }} build: runs-on: ubuntu-latest strategy: matrix: goos: [linux, windows, darwin] goarch: [amd64, arm64] steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.23' - name: Set environment variables run: | echo "GOOS=${{ matrix.goos }}" >> $GITHUB_ENV echo "GOARCH=${{ matrix.goarch }}" >> $GITHUB_ENV - name: Install dependencies run: go mod download - name: Build run: | go build -o ${{ env.appName }}-${{ matrix.goos }}-${{ matrix.goarch }} - name: Package binary into a ZIP file run: | zip -j ${{ env.appName }}-${{ matrix.goos }}-${{ matrix.goarch }}.zip ${{ env.appName }}-${{ matrix.goos }}-${{ matrix.goarch }} - name: List generated files run: ls -lh ${{ env.appName }}-*.zip - name: Upload ZIP artifact uses: actions/upload-artifact@v4 with: name: ${{ env.appName }}-${{ matrix.goos }}-${{ matrix.goarch }} path: ${{ env.appName }}-${{ matrix.goos }}-${{ matrix.goarch }}.zip release: needs: - version - build runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Download all artifacts uses: actions/download-artifact@v4 with: pattern: ${{ env.appName }}-* path: my-artifact merge-multiple: true - name: Create GitHub Release id: create_release uses: ncipollo/release-action@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag: ${{ needs.version.outputs.app_version }} name: Release ${{ needs.version.outputs.app_version }} body: ${{ needs.version.outputs.changelog }} generateReleaseNotes: true - name: List downloaded files run: ls -lh my-artifact - name: Upload all release artifacts run: | for file in ./my-artifact/*.zip; do echo "Uploading $file" gh release upload ${{ needs.version.outputs.app_version }} "$file" done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Деплоить на телефон мы будем максимально просто — сделаем скрипт, который будет находить последний релиз и разворачивать в userland.
/deploy/install_and_run.sh
#!/bin/bash REPO="itcaat/what-it-the-weather-now" INSTALL_DIR="$HOME/what-it-the-weather-now" BIN_NAME="what-it-the-weather-now-linux-arm64" ZIP_FILE="$BIN_NAME.zip" PID_FILE="$INSTALL_DIR/app.pid" VERSION_FILE="$INSTALL_DIR/version" FORCE_UPDATE=false # Check if --force is used if [[ "$1" == "--force" ]]; then FORCE_UPDATE=true echo "Force update enabled. Killing all instances and reinstalling..." fi # Function to stop the application stop_application() { if [[ -f "$PID_FILE" ]]; then APP_PID=$(cat "$PID_FILE") if ps -p "$APP_PID" > /dev/null 2>&1; then echo "Stopping running application (PID: $APP_PID)..." kill "$APP_PID" sleep 2 fi rm -f "$PID_FILE" fi } # Force stop all instances if --force is enabled if [[ "$FORCE_UPDATE" == true ]]; then pkill -f "$BIN_NAME" 2>/dev/null echo "Killed all running instances of $BIN_NAME." rm -f "$PID_FILE" "$VERSION_FILE" fi # 1. Get the latest release tag from GitHub API LATEST_RELEASE=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" | jq -r '.tag_name') if [[ -z "$LATEST_RELEASE" || "$LATEST_RELEASE" == "null" ]]; then echo "Error: Failed to fetch the latest release." exit 1 fi echo "Latest release: $LATEST_RELEASE" # 2. Check if the installed version is already the latest if [[ -f "$VERSION_FILE" && "$FORCE_UPDATE" == false ]]; then INSTALLED_VERSION=$(cat "$VERSION_FILE") if [[ "$INSTALLED_VERSION" == "$LATEST_RELEASE" ]]; then echo "You already have the latest version ($INSTALLED_VERSION). Exiting." exit 0 fi fi # 3. Stop the running application if needed stop_application # 4. Construct the download URL ASSET_URL="https://github.com/$REPO/releases/download/$LATEST_RELEASE/$ZIP_FILE" echo "Downloading: $ASSET_URL" # 5. Create the installation directory if it doesn't exist mkdir -p "$INSTALL_DIR" # 6. Download and extract the new version curl -L "$ASSET_URL" -o "$INSTALL_DIR/$ZIP_FILE" if [[ $? -ne 0 ]]; then echo "Error: Failed to download the file." exit 1 fi echo "Extracting to $INSTALL_DIR" unzip -o "$INSTALL_DIR/$ZIP_FILE" -d "$INSTALL_DIR" chmod +x "$INSTALL_DIR/$BIN_NAME" # 7. Remove the ZIP file after extraction rm "$INSTALL_DIR/$ZIP_FILE" # 8. Store the new version number echo "$LATEST_RELEASE" > "$VERSION_FILE" # 9. Start the updated application in the background echo "Starting the updated application..." nohup "$INSTALL_DIR/$BIN_NAME" > "$INSTALL_DIR/output.log" 2>&1 & echo $! > "$PID_FILE" echo "Application is running in the background (PID: $(cat $PID_FILE)). Logs: $INSTALL_DIR/output.log"
Можно передать параметр --force, который убьет все процессы нашего приложения и заново скачает и запустит все. Также если скрипт обнаружит новый релиз, то также стопнет текущие процессы нашего приложения и раскатит новую версию.
Почему не github actions для деплоя
Пробовал — не хватило памяти запуститься раннеру
Теперь просто кладем его в домашний каталог и запускаем. Он найдет последний релиз, скачает его под нашу платформу arm64 и запустит в фоне приложение. Оно у нас вешается на порт 8080.
Дальше остается просто добавить туннель в cloudflare zerotrust. При активации вас попросит вбить карту — можно скипнуть этот шаг и сразу настроить туннель cloudflared.
По сути нам надо просто выделить либо корневой домен, либо какой то поддомен. Мы сделаем для https://weather.devopsbrain.ru. Обслуживание домена у вас должно быть в cloudflare.
Далее нам нужно выбрать нужную архитектуру и операционную систему. В нашем случае debian arm64 и запустить команду для установки cloudflared.
После установки зароутим трафик в туннель на localhost:8080.
По итогу туннель будет запущен и можно открывать наш супер сайт https://weather.devopsbrain.ru, который хостится прямо на нашем телефоне. SSL также будет из коробки выдан cloudflare. При желании можете в rules настроить редиректы http -> https.
Ну и как вы понимаете, запустить в принципе можно все что хотите (даже с бд-шками) при достаточном количестве памяти. Исходники приложения, скрипты и файлы для сборки лежат в репе https://github.com/itcaat/what-is-the-weather-now.
А на этом все — спасибо за внимание. При желании заглядывайте в тележку https://t.me/devopsbrain. Всем отличного настроения.
ссылка на оригинал статьи https://habr.com/ru/articles/879818/
Добавить комментарий