• Как написать Docker файл для связки Front+Back+DB?

    И вам привет.

    Docker-compose вам в помощь, для начала. Голыми командами докера оперировать достаточно муторно, да и не требуется в реальных условиях.

    Возможно ли это всё запихнуть в контейнер и связать вместе?


    В один контейнер все это дело запихнуть однозначно можно, но - не нужно. Как понять, из какого набора контейнеров будет состоять ваша платформа? Очень просто.

    есть проект состоящий из Front (JS+React) + Back (бинарник на Go + config files) + DB (PostgreSQL)


    Вот и определились. Ваше приложение - состоит из frontend, backend и database. Названия взяты исключительно ради примера, но я не думаю, что в реалиях разработки продуктовых систем - вашему тим лиду понравится название "binarnik_na_go" вместо названия "backend" на код-ревью.

    Нужно ли в этот Docker файл интегрировать саму среду PostgreSQL или можно только базу данных?


    В каждом контейнере - содержится только одно приложение. Каждый контейнер - выполняет только одну команду. Если говорить о вашем бинарнике на Go, то команда, которую будет выполнять контейнер с backend - будет именем бинарника. Если это контейнер с БД, то в нем будет выполнятся только одна команда - запускающая сервер PostgreSQL. Для фронта - это будет команда pm2, или другая, с помощью которой вы запускаете сервер frontend.

    Бинарник бэка запускается на определённом порту, будет ли доступ к этому бинарнику по порту из-вне?


    Когда вы напишите конфигурацию своих сервисов в docker-compose.yml - и сделаете docker-compose up, docker-compose создаст виртуальную сеть. Сеть будет называться в формате <наименование директории, где лежит ваш docker-compose.yml>_default. Внутри этой сети, все сервисы будут иметь доступ друг к другу по имени сервиса и порту, указанному в EXPOSE в Dockerfile сервиса. Соответственно, ваш backend будет доступен по имени backend и порту, который вы укажите при сборке образа. Например, http://backend:8080. При этом, вы не сможете обратиться к этому имени/порту за пределами виртуальной сети. Чтобы вытащить порт "наружу", потребуется настроить биндинг портов от контейнера с backend на локальный хост, делается это с помощью директивы ports в описании сервиса в файле docker-compose.yml.

    Спрашиваю потому, что если запущу несколько подобных контейнеров не будут ли они конфликтовать за порты?


    Внутри сети - конфликтов не будет. Т.к. запустить несколько контейнеров с одинаковым именем их сервиса - не возможно. Но, можно скалировать контейнеры - с помощью определенных команд, о которых на данном этапе говорить нет смысла. На локальный хост, соответственно, вытащить два и более сервиса на один и тот же порт не получится, по понятным причинам.

    Или каждый образ надо кофигурировать под отдельный порт?


    Конфигурировать разные порты не требуется, т.к. каждый сервис имеет свое уникальное имя внутри сети контейнеров.

    К практике.

    Dockerfile для backend-а на Go может выглядеть так:

    # Тут берем официальный образ Golang для компиляции бинарника
    # В нем есть все для сборки, за редким исключением
    FROM golang:stretch as builder
    
    # Устанавливаем рабочую директорию внутри образа сборки бинарника
    WORKDIR /app
    
    # Копируем содержимое директории с вашим проектом в образ для сборки
    COPY . .
    
    # Скачиваем зависимости
    RUN go get -d -v
    
    # Собираем бинарник в директорию /app/bin
    RUN GOOS=linux GOARCH=amd64 go build -i -o bin/backend main.go
    
    # А теперь берем минимальный образ для запуска бинарника
    FROM scratch
    
    # Из образа для сборки, копируем готовый бинарник backend-а
    COPY --from=builder /app/bin/backend /app/bin/backend
    
    # Назначаем полученный бинарник точкой входа в контейнер
    ENTRYPOINT ["/app/bin/backend"]


    Теперь, если зайти в директорию с проектом backend и выполнить:

    docker build -t backend:latest .

    У вас соберется image с именем backend и тегом latest. Можно запускать, собственно.

    Образ для frontend собирите своими силами, зато разберетесь. Там суть таже, первым этапом можно взять image с node-js, собрать в нем frontend, а для запуска - использовать image c pm2 - скопировав директорию с приложением из этапа сборки.

    Как будет выглядеть ваш docker-compose.yml:

    version: "3.7"
    
    volumes:
      database:
    
    services:
    
      # Postgres. Берем готовый официальный образ
      database:
        image: postgres:12-alpine
        # Вот собственно тут и указывается, какие порты будут видны на вашей локали
        ports:
          - 5432:5432
        # Там выше в volumes указывали набор volumes. Используем вольюм database, чтобы хранить БД
        volumes:
          - database:/var/lib/postgresql/data
        restart: always
    
      # Backend. Берем образ, что собрали выше
      backend:
        image: backend:latest
        # В Dockerfile мы для гибкости не указывали порт backend-a. Укажем его тут. 
        expose: 
          - 8080
        ports:
          - 8080:8080
        restart: always
    
      # Frontend
      frontend:
        image: frontend:latest
        expose: 
          - 80
        ports:
          - 80:80
        restart: always


    Собственно и все. Остается поправить синтаксические ошибки и запустить, командой docker-compose up. Кстати, в интернетах есть очень много примеров проектов с кучами сервисов, с отдельными сетями для backend/frontend, с проксированием api через nginx/traefik и прочими фишками.

    Удачи.
    Ответ написан
    Комментировать
  • Как настроить Workerman для wss соединения?

    @YourQuestion Автор вопроса
    Проблему решил так:
    $context = array(
        'ssl' => array(
            'local_cert'  => 'ssl/server.crt',
            'local_pk'    => 'ssl/server.key',
            'verify_peer' => false,
        )
    );
    
    // Create a Websocket server with ssl context.
    $ws_worker = new Worker("websocket://domain.com:2346", $context);


    1. В директории со скриптом запуска сервера websocket (start.php) создал папку ssl где создал линки server.crt и server.key к реальным файлам сертификата и прописал путь к ним без __DIR__, через __DIR__ почему-то не работало.
    2. В строке js
    $ws_worker = new Worker("websocket://domain.com:2346", $context);
    прописал доменное имя вместо ip.
    Ответ написан
    Комментировать
  • Насколько будут нагружать сервер ежесекундные ajax запросы?

    @AndryG
    Без keepAlive будет уходить много времени на соединение, а ssl рукопожатия вообще долго могут проходить.
    С keepAlive, насколько я понимаю, каждый пользователь сервера отберет себе монопольно worker, что ограничивает к-во одновременных пользователей.

    Нужно озвучить фичу
    Ответ написан
    2 комментария
  • Насколько будут нагружать сервер ежесекундные ajax запросы?

    Fragster
    @Fragster
    помогло? отметь решением!
    Можно воспользоваться чем-нибудь типа https://github.com/yandex-load/yandex-tank и понять, сколько юзеров выдержит сервер. Но вообще подход с дерганием сервера каждую секунду - почти всегда неоправдан.
    Ответ написан
    Комментировать
  • Загрузка картинок ботом telegram?

    gds1
    @gds1
    Пыха - это наше всё)))
    $bot_url = "Ваш бот";
    $url = $bot_url . "sendPhoto?chat_id=Ваш чат ID" ;     
          $post_fields = array('chat_id' => $chat_id, 'photo' => new CURLFile(realpath($path1)) );
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-Type:multipart/form-data" ));
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    $output = curl_exec($ch);
    Ответ написан
    1 комментарий