LaraGram Armada
- Introduction
- Installation and Setup
- Starting and Stopping Armada
- Executing Commands
- Telegram Bot API Servers
- Receiving Updates
- Running the Application
- Interacting With Databases
- PHP and Node Versions
- Debugging With Xdebug
- Customization
- Production
Introduction
LaraGram Armada is a command-line interface for working with LaraGram's Docker environment. It gives you PHP, Composer, Node, your databases, and a Telegram Bot API server without installing anything on your machine except Docker.
Armada is built around a compose.yaml file stored in the root of your project and an armada script installed in vendor/bin. It supports macOS, Linux, and Windows through WSL2, and PHP 8.3, 8.4, and 8.5.
Armada is derived from Laravel Sail, and adds what a Telegram application needs: the official and LaraGram Bot API servers, long polling and webhook delivery, and the MTProto, Luna, Surge, Sentinel, and Watchdog processes. It can also generate the Docker files for deploying your application.
Installation and Setup
Install Armada as a development dependency, then run the armada:install command:
composer require laraxgram/armada --dev
php laragram armada:installThe command asks which database and cache services you want, which Bot API server the bot should use, how it should receive updates, and which processes should run. It then writes compose.yaml, updates your .env file, and prepares the images.
You may answer the same questions with options, which is useful in scripts:
php laragram armada:install \
--with=mysql,redis \
--bot-api=official \
--server=surge \
--updates=webhook \
--processes=queue,schedule,watchdog \
--php=8.5 \
--no-interaction| Option | Values |
|---|---|
--with | mysql, pgsql, mariadb, mongodb, redis, valkey, memcached, or none |
--bot-api | cloud, official, or laragram |
--server | serve or surge. Defaults to surge when Surge is installed. |
--updates | polling or webhook |
--processes | A comma-separated list of processes, or none |
--php | 8.3, 8.4, or 8.5 |
--devcontainer | Also create a devcontainer configuration |
Configuring a Shell Alias
Armada's commands are invoked through vendor/bin/armada. To shorten them, add an alias to your shell's configuration file, such as ~/.zshrc or ~/.bashrc:
alias armada='sh $([ -f armada ] && echo armada || echo vendor/bin/armada)'The remaining examples on this page assume this alias exists.
Adding Services
To add services to an existing installation, use the armada:add command:
php laragram armada:add valkey,mongodbThe same command changes the Bot API server, the application server, the update method, or the processes. Only the settings you pass are changed:
php laragram armada:add --bot-api=laragram
php laragram armada:add --processes=queue,schedule,mtprotoUsing Devcontainers
Pass the --devcontainer option to the armada:install command to publish a .devcontainer/devcontainer.json file:
php laragram armada:install --devcontainerStarting and Stopping Armada
To start all of the containers, run the up command. Add -d to run them in the background:
armada up
armada up -dStop them with Ctrl+C, or with the stop command when they run in the background:
armada stopUnknown commands are passed to Docker Compose, so armada ps, armada logs -f, and armada down work as expected.
Executing Commands
Your application's commands should be run inside the containers, where the correct PHP version and services are available:
armada laragram migrate
armada laragram webhook:info
armada probe
armada watchdog
armada php --version
armada composer require laraxgram/surge
armada npm run build| Command | Description |
|---|---|
armada laragram ... | Run a Commander command. armada lg is a shorthand. |
armada probe | Start a Probe session. |
armada watchdog | Tail the application logs with Watchdog. |
armada php ... | Run PHP. |
armada composer ... | Run Composer. |
armada node, npm, npx, pnpm, pnpx, yarn, bun, bunx | Run Node tools. |
armada bin ... | Run a binary from vendor/bin. |
armada run ... | Run any command in the application container. |
armada shell | Start a shell in the application container. armada root-shell starts one as root. |
Telegram Bot API Servers
Choosing a Server
Armada can run your own Bot API server next to your application, in a container named bot-api:
| Value | Server |
|---|---|
cloud | No container. The bot talks to api.telegram.org. |
official | Telegram's official telegram-bot-api server. |
laragram | The LaraGram API Server. |
Both servers listen on port 8081 in local mode, so you may switch between them at any time. Switching is safe for your code because the API is the same:
php laragram armada:add --bot-api=officialWhen a server is selected, Armada sets API_ENDPOINT=http://bot-api:8081 in your .env file. The port is also published on 127.0.0.1 of your machine; you may change it with the FORWARD_BOT_API_PORT variable.
Credentials and Logging Out
Both servers need an API_ID and API_HASH from my.telegram.org. Armada asks for them during installation, or you may add them to your .env file later:
API_ID=123456
API_HASH=0123456789abcdef0123456789abcdefA bot must be logged out of the cloud Bot API once before it can use your own server. Armada reads BOT_TOKEN from your .env file and does this for you:
armada bot-api logoutWARNING
After logging out, a bot cannot log back in to api.telegram.org for 10 minutes.
Managing the Server
armada bot-api status
armada bot-api logs
armada bot-api restartSet the BOT_API_VERBOSITY variable to 2 or higher when a bot does not respond as expected; login failures are logged at the warning level.
Each server also publishes its statistics on port 8082 inside the Docker network. This port is never published on your machine because the page lists your bot tokens. When Sentinel is installed, Armada sets SENTINEL_API_SERVER_STATS_URL so its API Server page works without any further configuration.
Local Files
In local mode, getFile returns an absolute path instead of a download URL. Armada mounts the server's data at /var/lib/bot-api in both the bot-api and application containers, and runs both as your user, so your application can read the returned path directly and upload files using file:// paths in that directory.
Server Images
Telegram does not publish a Docker image for its server, so LaraGram builds one from the official source and publishes it, along with the LaraGram API Server, to the GitHub Container Registry:
ghcr.io/laraxgram/telegram-bot-apighcr.io/laraxgram/apiserver
Armada pulls these images. If an image cannot be pulled, it is built from source instead. Compiling the official server takes between 15 and 40 minutes and several gigabytes of memory the first time.
Because armada build rebuilds every service that has a build section, prefer naming the service when you only want to rebuild your application:
armada build laragram.testReceiving Updates
The ARMADA_UPDATES variable in your .env file controls how the bot receives updates:
pollingruns the bot with long polling next to the server. It needs no public URL, so it is the default when using the cloud Bot API.webhookexpects Telegram to call your application.
A local Bot API server can reach your application inside the Docker network, so webhooks work without a tunnel or a public URL. In this case Armada sets BOT_URL=http://laragram.test, and you only need to register the webhook once:
armada laragram webhook:setWith the cloud Bot API, webhooks require a public HTTPS URL that forwards to your application, set as BOT_URL.
NOTE
Long polling fails while the bot has a webhook. Remove it first with armada laragram webhook:delete.
Running the Application
The application is served on port 80 of the container, which is published on the port given by the APP_PORT variable. You may change the settings below in your .env file, then apply them with armada up -d.
Surge
The ARMADA_SERVER variable chooses the server, either serve or surge. When Surge is installed it is selected automatically. Armada watches your files and reloads the workers when the chokidar Node package is installed in your project:
armada npm install --save-dev chokidarBackground Processes
The ARMADA_PROCESSES variable is a comma-separated list of processes that run next to the server, in the same container. Their output appears in armada logs, and each is restarted if it crashes.
ARMADA_PROCESSES=queue,schedule,watchdog| Process | Command |
|---|---|
queue | queue:listen --tries=1 --timeout=0 |
schedule | schedule:work |
watchdog | watchdog --timeout=0 |
mtproto | client:start --all |
ssr | luna:start-ssr |
sentinel-queue | sentinel:queue |
sentinel-check | sentinel:check |
vite | The dev script of your package.json, using the project's package manager |
During installation, Armada only offers the processes that match the packages your project has installed.
NOTE
php laragram dev is not needed under Armada. It binds to localhost inside the container, while the processes above already run the same commands.
MTProto
Armada's images include every extension MTProto needs. Sessions should be authorized interactively before the client starts:
armada laragram client:auth
armada restartUnder Surge, the MTProto client runs as a Surge process, so the mtproto process is not offered. Otherwise, the mtproto process runs client:start --all.
Luna
Run the Vite development server with the vite process or with armada npm run dev -- --host. It is published on the port given by the VITE_PORT variable. To use server-side rendering, build the SSR bundle and add the ssr process:
armada npm run buildTelegram only opens Mini Apps over HTTPS, so testing inside the Telegram client requires a public HTTPS URL that forwards to your application.
Sentinel
Add sentinel-check to record server metrics, and sentinel-queue when your application uses a Redis queue. Do not combine sentinel-queue with queue.
Interacting With Databases
Armada creates a persistent volume for each database, and configures your .env file to use it. A testing database is also created for MySQL, MariaDB, and PostgreSQL.
armada mysql
armada mariadb
armada psql
armada mongodb
armada redis
armada valkeyFrom your machine, you may connect through localhost and the published port, which is changed with variables such as FORWARD_DB_PORT and FORWARD_REDIS_PORT. To remove the volumes and start over, run armada down -v.
PHP and Node Versions
Choose the PHP version when installing:
php laragram armada:install --php=8.4To change it later, update the PHP_VERSION argument and image of the laragram.test service in your compose.yaml file, then rebuild. The same args section accepts NODE_VERSION and PHP_EXTENSIONS, a space-separated list of additional extensions:
laragram.test:
build:
args:
WWWGROUP: '${WWWGROUP}'
PHP_VERSION: '8.4'
NODE_VERSION: '22'
PHP_EXTENSIONS: 'ldap soap'
image: armada-8.4/apparmada build --no-cache laragram.test
armada up -dDebugging With Xdebug
Xdebug is included but disabled. Enable it in your .env file before starting Armada:
ARMADA_XDEBUG_MODE=develop,debug,coverageTo debug a Commander command, use the debug command:
armada debug migrateOn Linux hosts running a Docker version older than 20.10, set ARMADA_XDEBUG_CONFIG="client_host=<your-ip>".
Customization
Publish Armada's Docker files to the docker directory of your project and rebuild:
armada laragram armada:publish
armada build --no-cache laragram.testThe compose.yaml file is updated to use the published files. You may set SUPERVISOR_PHP_COMMAND on the service to replace the command that serves the application entirely. To combine Compose files, set the ARMADA_FILES variable to a colon-separated list of paths.
Production
Generating the Production Files
The armada:production command creates a multi-stage Dockerfile in docker/production, a .dockerignore file, and a compose.production.yaml file:
php laragram armada:productionIt accepts --with, --bot-api, --server, --updates, --roles, and --php. The server is either surge or fpm, which runs Nginx and PHP-FPM. Use --force to overwrite an existing Compose file.
The production image contains your code, its Composer dependencies, and your built assets, without development tools such as Xdebug. It runs as an unprivileged user, and OPcache does not check for file changes.
Deploying
The production file reads your .env file. Passwords and Bot API credentials are required, and no database port is published. Set your production values, then build your image and start the containers:
armada prod build app
armada prod up -dEvery Armada command works with the prod prefix:
armada prod laragram migrate --force
armada prod laragram webhook:set
armada prod logs -f appSet ARMADA_MIGRATE=1 to run migrations each time the web container starts. Caches are built automatically on start, so .env is read when a container starts rather than when the image is built. Rebuild and run armada prod up -d to deploy a new version.
The application is published on the port given by the APP_PORT variable, 8000 by default. Armada does not terminate TLS: place a reverse proxy in front of it when your bot uses the cloud Bot API, because Telegram only delivers webhooks over HTTPS, or for Mini Apps. With a local Bot API server, webhooks are delivered inside the Docker network and BOT_URL is set to http://app:8000 for you.
WARNING
The armada-bot-api volume contains the session of every bot, and armada-storage contains your MTProto sessions. Back them up and restrict access to the Docker host accordingly.
Container Roles
Each role runs in its own container from the same image, selected by the ARMADA_ROLE variable. The command chooses roles based on your installed packages, and --roles overrides them:
| Role | Command |
|---|---|
queue | queue:work --tries=3 --max-time=3600 |
sentinel-queue | sentinel:queue |
schedule | schedule:work |
poller | poll |
mtproto | client:start --all |
ssr | luna:start-ssr |
sentinel-check | sentinel:check |
Authorize MTProto sessions before starting the mtproto role, with armada prod laragram client:auth. Watchdog needs no container in production: its Telegram reporting runs inside your application.