---
title: "Установка и первый сервер"
description: "Установка Fiber и первый сервер на Go: go mod init, go get, fiber.New, app.Listen. Построчный разбор hello world, проверка через curl и настройка fiber.Config."
course: "Fiber: экспресс-подобный веб-фреймворк на Fasthttp"
url: "https://golangmaster.ru/courses/fiber/lessons/02-pervyj-server/"
published: "2026-09-19"
updated: "2026-09-21"
minutes: 18
---

# Установка и первый сервер

*Курс «Fiber: экспресс-подобный веб-фреймворк на Fasthttp», урок 2 из 25. ~18 минут. Обновлено 21.09.2026. Источник: https://golangmaster.ru/courses/fiber/lessons/02-pervyj-server/*

Первый сервер на Fiber — это один файл и три терминальные команды. Установим Fiber через go get, соберём fiber hello world построчно, проверим ответ через curl и настроим приложение через fiber.Config: таймауты, лимит тела, имя сервиса.

### Готовим окружение: Go и модуль

Понадобится локальный Go — свежая стабильная версия. Fiber v3 собран под новые версии языка, точный минимум указан в README репозитория (на момент написания это Go 1.26+), так что если ваш тулчейн старее, обновитесь заранее. Браузерная песочница этого сайта сетевые приложения не запускает, поэтому весь код урока — для вашего терминала: без локального Go его не проверить.

Go-проекты живут внутри модулей. Модуль — это папка с файлом go.mod, где записаны имя проекта, версия языка и список зависимостей. Создаём папку, инициализируем модуль — и только потом ставим Fiber.

### Три команды в терминале

```go
mkdir hello-fiber && cd hello-fiber
go mod init example.com/hello-fiber
go get github.com/gofiber/fiber/v3
```

Первая команда создаёт папку проекта и переходит в неё. go mod init делает папку модулем и пишет файл go.mod — example.com/hello-fiber это имя модуля, для локального эксперимента подойдёт любое уникальное, при публикации в открытом репозитории оно совпадёт с адресом. go get скачивает Fiber v3 и добавляет его в зависимости в go.mod — вместе с fasthttp и остальными внутренними пакетами.

> **v2 или v3 — не смешивать.** В туториалах прошлых лет вы встретите v2: go get github.com/gofiber/fiber/v2, импорт .../fiber/v2 и хендлеры с *fiber.Ctx (указатель). В v3 контекст — интерфейс fiber.Ctx без звёздочки. Пример одной версии не скомпилируется с другой — выбирайте v3 для новых проектов и держите версию единой внутри модуля.

### Hello, World: полный код

Создайте в папке проекта файл main.go и вставьте код ниже. Это полноценный сервер: после запуска он отвечает на запросы к корню и держит соединение, пока вы его не остановите. Если вы прошли [базовый курс](/courses/go-basics/), незнакомым здесь будет только импорт fiber и сам объект app — всё остальное вы уже видели.

### main.go

```go
package main

import (
        "log"

        "github.com/gofiber/fiber/v3"
)

func main() {
        app := fiber.New()

        app.Get("/", func(c fiber.Ctx) error {
                return c.SendString("Hello, World!")
        })

        log.Fatal(app.Listen(":3000"))
}
```

По строкам. Импорты: log — стандартный пакет для фатальных ошибок, fiber — сам фреймворк, версия видна в пути (v3). fiber.New() создаёт приложение с настройками по умолчанию. app.Get("/", ...) регистрирует маршрут «GET /». Хендлер — функция func(c fiber.Ctx) error: контекст даёт доступ к запросу и ответу, а возврат error обязателен — если вернуть не nil, ошибку обработает ErrorHandler (подробнее в уроке про ошибки). c.SendString пишет строку в тело ответа. app.Listen(":3000") поднимает сервер и блокирует выполнение; log.Fatal напечатает ошибку и завершит процесс с кодом 1, если она случится.

### Что происходит при запросе

Вы запустили сервер — Fasthttp открыл порт 3000 и слушает TCP-соединения. Клиент присылает GET /, движок парсит запрос и передаёт его Fiber; тот находит маршрут и вызывает ваш хендлер, передавая Ctx — фасад над запросом и ответом. Хендлер вернул nil — Fiber завершает ответ и возвращает контекст обратно в пул. Не уничтожает, а переиспользует: аллокаций меньше, скорость выше.

Отсюда правило, которое ломает новичков: после return из хендлера контекст жить перестал. Сохраните c.Params("id") в глобальную переменную и через секунду прочитаете там id чужого запроса. Нужны данные вне хендлера — копируйте значения в свои переменные и структуры, а не держите ссылку на Ctx. Пул переиспользования — та самая «zero allocation» архитектура из первого урока, у которой есть последствия.

### Проверьте себя

**Вопрос:** Почему нельзя сохранить fiber.Ctx в глобальную переменную и пользоваться им после return из хендлера?

- Ctx нельзя сохранить в переменную — так запрещено компилятором
- ✅ Контекст переиспользуется пулом для следующих запросов
- Ctx обнуляется сборщиком мусора через минуту
- Так делают только для скорости, ограничений нет

Fiber держит пул контекстов: после завершения ответа объект уходит на обработку следующего запроса. Данные из Ctx нужно копировать, а не ссылаться на сам контекст.

### Проверяем в curl

Запустите сервер командой go run . (точка означает «текущий пакет») и в другом окне терминала отправьте запрос. Флаг -i у curl заставит показать не только тело, но и служебные заголовки — для веб-разработчика это привычный способ заглянуть под капот.

### Запрос и ответ

```go
curl -i http://localhost:3000/

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 13
Date: Sat, 07 Feb 2026 12:00:00 GMT

Hello, World!
```

Разбор ответа. Статус 200 Fiber проставил сам, потому что хендлер вернул nil. Content-Type: text/plain — тело строка, Fiber понял это из SendString. Content-Length: 13 — длина строки «Hello, World!», посчитайте сами: тринадцать символов. Date — время ответа, стандарт для HTTP. Если увидели ровно это — сервер работает, первый fiber hello world готов.

> **Порт занят.** Если на 3000 уже кто-то слушает, Listen вернёт ошибку вида «listen tcp :3000: bind: address already in use», log.Fatal напечатает её, и процесс завершится. Чаще всего порт держит старый go run, который вы не остановили по Ctrl+C. Смените адрес в Listen, например на ":8080", — первый аргумент это host:port.

### Что получит клиент при запросе GET /status к маршруту из кода?

```go
app.Get("/status", func(c fiber.Ctx) error {
        return c.SendStatus(fiber.StatusNotFound)
})
```

**Что выведет программа?**

- Код 404 и пустое тело ответа
- ✅ Код 404 и тело «Not Found»
- Код 200 и тело «Not Found»
- JSON вида {"code": 404}

SendStatus ставит код и, если тело ответа ещё пустое, пишет в него название статуса — «Not Found». Так Fiber экономит пару строк для простых ответов. Полностью пустое тело даст метод NoContent() или 204.

### Настройка приложения: fiber.Config

fiber.New() без аргументов — это настройки по умолчанию. Для серьёзного приложения их переопределяют структурой fiber.Config. Самые ходовые поля: AppName — имя сервиса, его видно в баннере при старте; ReadTimeout, WriteTimeout и IdleTimeout — таймауты в формате time.Duration, защита от клиентов, которые держат соединение и молчат; BodyLimit — максимальный размер тела запроса в байтах, по умолчанию 4 МБ; ErrorHandler — единая точка обработки ошибок, к нему вернёмся в отдельном уроке.

### fiber.New с конфигом

```go
package main

import (
        "log"
        "time"

        "github.com/gofiber/fiber/v3"
)

func main() {
        app := fiber.New(fiber.Config{
                AppName:      "hello-fiber",
                ReadTimeout:  5 * time.Second,
                WriteTimeout: 10 * time.Second,
                BodyLimit:    2 * 1024 * 1024, // 2 МБ вместо 4
        })

        app.Get("/", func(c fiber.Ctx) error {
                return c.SendString("OK")
        })

        log.Fatal(app.Listen(":3000"))
}
```

ReadTimeout: 5 * time.Second — пять секунд на чтение запроса, дальше соединение рвётся. WriteTimeout: 10 * time.Second — столько даётся на запись ответа. BodyLimit: 2 * 1024 * 1024 — два мегабайта в байтах: 2 умножаем на 1024 (килобайты) и ещё раз на 1024 (мегабайты). Для API, который принимает только JSON, четырёх мегабайт по умолчанию много — режьте лимит, крупные тела запросов часто признак проблемы на клиенте.

### Чек-лист запуска

1. go mod init example.com/hello-fiber — создать модуль
2. go get github.com/gofiber/fiber/v3 — поставить Fiber
3. Написать main.go: fiber.New, маршрут, app.Listen
4. go run . — запустить сервер
5. curl -i http://localhost:3000/ — проверить ответ
6. Ctrl+C — остановить сервер перед правками кода

### Сервер с конфигом

Допишите структуру конфига и запуск сервера. В поле подсказки — расшифровка имён.

```go
package main

import (
        "log"
        "time"

        "github.com/gofiber/fiber/v3"
)

func main() {
        app := fiber.New(fiber.___{
                AppName:     "todo-api",
                ReadTimeout: 5 * time.___,
                BodyLimit:   1024 * 1024,
        })

        app.Get("/", func(c fiber.Ctx) error {
                return c.SendString("OK")
        })

        log.Fatal(app.___(":3000"))
}
```

Подсказка: fiber.Config — структура настроек; time.Second — длительность в секундах; app.Listen поднимает сервер.

Правильные ответы в пропусках: `Config`, `Second`, `Listen`

### От пустой папки до ответа сервера

Расставьте шаги в порядке выполнения: от инициализации модуля до проверки ответа.

Правильный порядок строк:

1. `go mod init example.com/hello-fiber`
2. `go get github.com/gofiber/fiber/v3`
3. `Написать main.go с fiber.New и app.Get`
4. `go run .`
5. `curl -i http://localhost:3000/`

### Словарь урока

- **go.mod** — Файл модуля Go: имя проекта, версия языка и список зависимостей с версиями.
- **fiber.New()** — Создаёт приложение; аргумент fiber.Config{} переопределяет настройки по умолчанию.
- **fiber.Ctx** — Интерфейс контекста запроса (в v3 без указателя). Переиспользуется пулом — после return данные из него нельзя читать.
- **app.Listen(":3000")** — Поднимает сервер на host:port, блокирует выполнение, возвращает error при неудаче.
- **Config.BodyLimit** — Максимальный размер тела запроса в байтах; по умолчанию 4 МБ.
- **c.SendStatus(404)** — Ставит статус и, если тело пустое, пишет в него название статуса («Not Found»).

### Что дальше

Сервер отвечает, но пока у него один маршрут. В следующем уроке разберём маршрутизацию Fiber: методы HTTP, параметры пути вроде :id и правила, по которым роутер выбирает хендлер: [Урок 3: маршрутизация](/courses/fiber/lessons/03-marshrutizaciya/). Код этого урока проверяется локально — curl и открытый терминал вам в руки.

## Коротко: что запомнить

- Проект на Fiber — обычный Go-модуль: go mod init, затем go get github.com/gofiber/fiber/v3.
- Hello world — это fiber.New(), app.Get с хендлером и log.Fatal(app.Listen(":3000")).
- Хендлер возвращает error: nil — ответ готов, ошибка уходит в ErrorHandler.
- fiber.Ctx переиспользуется пулом: данные из контекста копируйте, ссылку не храните.
- curl -i показывает статус, заголовки и тело — базовый инструмент проверки сервера.
- fiber.Config управляет таймаутами, лимитом тела и ErrorHandler; BodyLimit по умолчанию 4 МБ.

## Домашнее задание

Добавьте в main.go второй маршрут app.Get("/about", ...) с коротким текстом о вашем проекте и поставьте ReadTimeout 3 секунды. Запустите сервер, проверьте оба маршрута через curl -i и найдите в выводе Content-Length каждого ответа — сверьте его с реальной длиной строки.

## Вопросы и ответы по уроку

### Какая версия Go нужна для Fiber v3?

Свежая стабильная: v3 собирается под новые версии языка, минимум указан в README (на момент написания — Go 1.26+). Для v2 требования мягче, но лучше писать под v3.

### Как поменять порт сервера?

В первом аргументе app.Listen — адрес вида host:port. ":3000" слушает все интерфейсы на порту 3000; укажите ":8080" или "127.0.0.1:3000", если нужен только локальный доступ.

### Нужна ли горячая перезагрузка?

Не обязательна: после правок достаточно перезапустить go run . Если надоело, поставьте утилиту air — она пересобирает и перезапускает проект при каждом сохранении файла.
