Deploy your projects directly from your local computer to your production server easily.
Airo helps you deploying containers to your self-hosted server, without worrying about configuring pipelines, serverless services or different platforms. Just your self-hosted servers.
Deploying side-projects doesn't have to be complicated or expensive. Kubernetes, Platform as a Service (PaaS) and CI/CD pipelines are a powerful and exciting solutions, but sometimes they're more complex than your project requires. If you enjoy managing your server, it can be significantly cheaper and offer greater control over the technical details.
I want to automate this process and deploy easily to my own server. That's why I've created Airo:
- 🚀 Focus on building your product, not managing infrastructure.
- 🐳 Build and deliver Docker images via a registry or direct copy.
- ⚡️ Deploy instantly with a single command from your computer.
- 🔑 Easily update configurations and containers securely using SSH.
- 🌐 Set up HTTPS and reverse proxy automatically using Caddy.
Deploying with Airo is easy:
- Define your services in a
compose.ymlfile. - Configure your deployment details in
env.yml(server details, Docker images, transport, etc.). - Prepare your Dockerfile.
- Set up your Caddyfile for automatic HTTPS and reverse proxy.
After this initial setup, deploying new updates is just a simple command away:
airo deploygit clone https://github.com/yourusername/airo.git
cd airo
make install
airo deployIf you have a fresh server that doesn't have Docker installed yet, you can use the init command to set everything up:
airo initThis command will:
- Update all system packages
- Install Docker and Docker Compose
- Add your user to the docker group
- Verify the installation
Note: After running init, you may need to log out and back in to the server for docker group permissions to take effect.
-
Create a new project directory and navigate to it:
mkdir my-project/.deploy cd my-project/.deploy -
Configure your
env.ymlfile:# Image delivery method: "registry" (default) or "copy" transport: registry server: your-server-ip user: your-ssh-user ssh_key: /path/to/your/ssh/key # add all your services that will be built here services: - name: nextjs image: your-registry/api:latest build: /home/user/your-project
-
Add a Dockerfile to your project:
FROM node:20-alpine WORKDIR /app COPY . . RUN npm install
-
Configure your
compose.ymlfile with your services:services: postgres: image: postgres:latest restart: unless-stopped ports: - '5432:5432' volumes: - ./postgres_data:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: some-temporary-password nextjs: image: your-registry/front:latest restart: unless-stopped ports: - '3000:3000' volumes: - ./.env:/app/.env
-
Deploy your project:
airo deploy
- Registry (default): builds locally, pushes to your registry, and pulls on the server.
- Copy: builds locally, saves as tar, uploads over SSH, and loads on the server.
To use copy mode, set in env.yml:
transport: copy-
Update compose configuration without building images:
airo compose
-
Update Caddyfile configuration:
airo caddy
-
Initialize a fresh server (install Docker and updates):
airo init
By default, Airo looks for config files (env.yml, compose.yml, Caddyfile) in the current directory. You can specify a different directory using the --config flag:
airo deploy --config /path/to/config/directory
airo compose --config ./my-project/.deploy
airo caddy --config ../configs
airo init --config ./server-configsThis is useful when:
- You have multiple deployment configurations
- Your config files are in a different directory
- You want to organize your deployment files separately