build docker image in ci
This commit is contained in:
parent
0f8cfc34e7
commit
5263175182
5 changed files with 594 additions and 21 deletions
39
.gitignore
vendored
39
.gitignore
vendored
|
|
@ -1,25 +1,24 @@
|
|||
# Created by https://gitignore.org
|
||||
# Rust.gitignore
|
||||
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
debug
|
||||
target
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
# Rust
|
||||
/target/
|
||||
Cargo.lock
|
||||
**/*.rs.bk
|
||||
|
||||
# MSVC Windows builds of rustc generate these, which store debugging information
|
||||
*.pdb
|
||||
|
||||
# Generated by cargo mutants
|
||||
# Contains mutation testing data
|
||||
**/mutants.out*/
|
||||
# Database files
|
||||
*.db
|
||||
*.db-shm
|
||||
*.db-wal
|
||||
|
||||
# RustRover
|
||||
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# Docker
|
||||
data/
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
|
|
|||
138
.gitlab-ci.yml
Normal file
138
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
# GitLab CI/CD Configuration for Towerops Agent
|
||||
# Builds and publishes Docker image to GitLab Container Registry
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- release
|
||||
|
||||
variables:
|
||||
# GitLab Container Registry
|
||||
REGISTRY: registry.gitlab.com
|
||||
IMAGE_NAME: graham/towerops-agent
|
||||
# Docker BuildKit for better caching
|
||||
DOCKER_BUILDKIT: 1
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
|
||||
# Test stage - compile and check code
|
||||
test:
|
||||
stage: test
|
||||
image: rust:1.75-alpine
|
||||
before_script:
|
||||
- apk add --no-cache musl-dev
|
||||
script:
|
||||
- cargo check --release
|
||||
- cargo fmt -- --check
|
||||
- cargo clippy -- -D warnings
|
||||
only:
|
||||
- branches
|
||||
- merge_requests
|
||||
cache:
|
||||
key: ${CI_COMMIT_REF_SLUG}-cargo
|
||||
paths:
|
||||
- target/
|
||||
- .cargo/
|
||||
|
||||
# Build Docker image for branches (test build)
|
||||
build:test:
|
||||
stage: build
|
||||
image: docker:24-dind
|
||||
services:
|
||||
- docker:24-dind
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- |
|
||||
docker build \
|
||||
--tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_SLUG \
|
||||
--tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA \
|
||||
.
|
||||
- docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_REF_SLUG
|
||||
- docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
|
||||
only:
|
||||
- branches
|
||||
except:
|
||||
- main
|
||||
- tags
|
||||
|
||||
# Build and push for main branch
|
||||
build:main:
|
||||
stage: build
|
||||
image: docker:24-dind
|
||||
services:
|
||||
- docker:24-dind
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- |
|
||||
docker build \
|
||||
--tag $REGISTRY/$IMAGE_NAME:latest \
|
||||
--tag $REGISTRY/$IMAGE_NAME:main-$CI_COMMIT_SHORT_SHA \
|
||||
.
|
||||
- docker push $REGISTRY/$IMAGE_NAME:latest
|
||||
- docker push $REGISTRY/$IMAGE_NAME:main-$CI_COMMIT_SHORT_SHA
|
||||
- echo "IMAGE_TAG=latest" >> build.env
|
||||
artifacts:
|
||||
reports:
|
||||
dotenv: build.env
|
||||
only:
|
||||
- main
|
||||
|
||||
# Release build for tags (versioned releases)
|
||||
release:
|
||||
stage: release
|
||||
image: docker:24-dind
|
||||
services:
|
||||
- docker:24-dind
|
||||
before_script:
|
||||
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
script:
|
||||
- |
|
||||
# Extract version from tag (assumes tags like v0.1.0)
|
||||
VERSION=${CI_COMMIT_TAG#v}
|
||||
|
||||
docker build \
|
||||
--tag $REGISTRY/$IMAGE_NAME:$VERSION \
|
||||
--tag $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG \
|
||||
--tag $REGISTRY/$IMAGE_NAME:latest \
|
||||
.
|
||||
|
||||
docker push $REGISTRY/$IMAGE_NAME:$VERSION
|
||||
docker push $REGISTRY/$IMAGE_NAME:$CI_COMMIT_TAG
|
||||
docker push $REGISTRY/$IMAGE_NAME:latest
|
||||
|
||||
echo "Released version: $VERSION"
|
||||
echo "IMAGE_TAG=$VERSION" >> release.env
|
||||
artifacts:
|
||||
reports:
|
||||
dotenv: release.env
|
||||
only:
|
||||
- tags
|
||||
except:
|
||||
- branches
|
||||
|
||||
# Optional: Multi-architecture build (amd64 + arm64)
|
||||
# Uncomment if you need ARM support (e.g., for Raspberry Pi)
|
||||
#
|
||||
# build:multiarch:
|
||||
# stage: build
|
||||
# image: docker:24-dind
|
||||
# services:
|
||||
# - docker:24-dind
|
||||
# before_script:
|
||||
# - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
|
||||
# # Enable buildx for multi-arch
|
||||
# - docker buildx create --use --name multiarch-builder
|
||||
# - docker buildx inspect --bootstrap
|
||||
# script:
|
||||
# - |
|
||||
# VERSION=${CI_COMMIT_TAG#v}
|
||||
#
|
||||
# docker buildx build \
|
||||
# --platform linux/amd64,linux/arm64 \
|
||||
# --tag $REGISTRY/$IMAGE_NAME:$VERSION \
|
||||
# --tag $REGISTRY/$IMAGE_NAME:latest \
|
||||
# --push \
|
||||
# .
|
||||
# only:
|
||||
# - tags
|
||||
387
DEPLOYMENT.md
Normal file
387
DEPLOYMENT.md
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
# Towerops Agent - Deployment Guide
|
||||
|
||||
## GitLab CI/CD Pipeline
|
||||
|
||||
The agent uses GitLab CI/CD to automatically build and publish Docker images to the GitLab Container Registry.
|
||||
|
||||
### Pipeline Stages
|
||||
|
||||
1. **Test** - Compile, format check, and lint
|
||||
2. **Build** - Build Docker image
|
||||
3. **Release** - Tag and publish versioned releases
|
||||
|
||||
### Image Tags
|
||||
|
||||
| Git Action | Image Tags | Example |
|
||||
|------------|------------|---------|
|
||||
| Push to branch | `<branch>`, `<commit-sha>` | `feat-snmp`, `abc123` |
|
||||
| Push to main | `latest`, `main-<sha>` | `latest`, `main-abc123` |
|
||||
| Create tag | `<version>`, `<tag>`, `latest` | `0.1.0`, `v0.1.0`, `latest` |
|
||||
|
||||
### Registry Location
|
||||
|
||||
All images are pushed to:
|
||||
```
|
||||
registry.gitlab.com/graham/towerops-agent
|
||||
```
|
||||
|
||||
## Creating a Release
|
||||
|
||||
### 1. Update Version
|
||||
|
||||
**In `Cargo.toml`**:
|
||||
```toml
|
||||
[package]
|
||||
name = "towerops-agent"
|
||||
version = "0.2.0" # ← Update this
|
||||
edition = "2021"
|
||||
```
|
||||
|
||||
### 2. Commit and Tag
|
||||
|
||||
```bash
|
||||
git add Cargo.toml
|
||||
git commit -m "Release v0.2.0"
|
||||
git tag v0.2.0
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
### 3. CI Pipeline Runs
|
||||
|
||||
GitLab CI will automatically:
|
||||
- Run tests (cargo check, fmt, clippy)
|
||||
- Build Docker image
|
||||
- Tag as: `0.2.0`, `v0.2.0`, `latest`
|
||||
- Push to registry
|
||||
|
||||
### 4. Verify Release
|
||||
|
||||
Check the Container Registry:
|
||||
```
|
||||
https://gitlab.com/graham/towerops-agent/container_registry
|
||||
```
|
||||
|
||||
You should see:
|
||||
- `latest` (updated)
|
||||
- `0.2.0` (new)
|
||||
- `v0.2.0` (new)
|
||||
|
||||
## Using the Images
|
||||
|
||||
### Pull Latest
|
||||
|
||||
```bash
|
||||
docker pull registry.gitlab.com/graham/towerops-agent:latest
|
||||
```
|
||||
|
||||
### Pull Specific Version
|
||||
|
||||
```bash
|
||||
docker pull registry.gitlab.com/graham/towerops-agent:0.1.0
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
|
||||
Update `docker-compose.yml`:
|
||||
```yaml
|
||||
services:
|
||||
towerops-agent:
|
||||
image: registry.gitlab.com/graham/towerops-agent:latest
|
||||
# Or pin to specific version:
|
||||
# image: registry.gitlab.com/graham/towerops-agent:0.1.0
|
||||
environment:
|
||||
- TOWEROPS_API_URL=https://app.towerops.com
|
||||
- TOWEROPS_AGENT_TOKEN=${AGENT_TOKEN}
|
||||
volumes:
|
||||
- ./data:/data
|
||||
```
|
||||
|
||||
## Customer Deployment
|
||||
|
||||
### Provide to Customers
|
||||
|
||||
**Option 1: Docker Compose (Recommended)**
|
||||
|
||||
Create `docker-compose.yml`:
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
towerops-agent:
|
||||
image: registry.gitlab.com/graham/towerops-agent:latest
|
||||
container_name: towerops-agent
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TOWEROPS_API_URL=https://app.towerops.com
|
||||
- TOWEROPS_AGENT_TOKEN=<GET_FROM_UI>
|
||||
volumes:
|
||||
- ./data:/data
|
||||
```
|
||||
|
||||
Instructions for customer:
|
||||
```bash
|
||||
# 1. Get agent token from Towerops UI
|
||||
# 2. Replace <GET_FROM_UI> in docker-compose.yml
|
||||
# 3. Start agent
|
||||
docker-compose up -d
|
||||
|
||||
# 4. Check logs
|
||||
docker-compose logs -f
|
||||
|
||||
# 5. Check status
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
**Option 2: Docker Run**
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name towerops-agent \
|
||||
--restart unless-stopped \
|
||||
-e TOWEROPS_API_URL=https://app.towerops.com \
|
||||
-e TOWEROPS_AGENT_TOKEN=<token> \
|
||||
-v $(pwd)/data:/data \
|
||||
registry.gitlab.com/graham/towerops-agent:latest
|
||||
```
|
||||
|
||||
## CI/CD Configuration
|
||||
|
||||
### Required GitLab Variables
|
||||
|
||||
No additional CI/CD variables needed. GitLab provides these automatically:
|
||||
- `CI_REGISTRY` - GitLab Container Registry URL
|
||||
- `CI_REGISTRY_USER` - Username for registry login
|
||||
- `CI_REGISTRY_PASSWORD` - Password for registry login
|
||||
|
||||
These are automatically available in all GitLab CI/CD pipelines.
|
||||
|
||||
### Pipeline Triggers
|
||||
|
||||
**Automatic**:
|
||||
- Push to any branch → test + build with branch tag
|
||||
- Push to main → test + build + tag as `latest`
|
||||
- Create tag (e.g., `v0.1.0`) → test + build + release
|
||||
|
||||
**Manual**: No manual triggers configured (all automatic)
|
||||
|
||||
### Viewing Pipeline Status
|
||||
|
||||
1. Go to: https://gitlab.com/graham/towerops-agent/-/pipelines
|
||||
2. Click on a pipeline to see detailed logs
|
||||
3. Check job logs if build fails
|
||||
|
||||
## Local Development
|
||||
|
||||
### Build Locally
|
||||
|
||||
```bash
|
||||
# Development build
|
||||
cargo build
|
||||
|
||||
# Release build (optimized)
|
||||
cargo build --release
|
||||
|
||||
# Build Docker image locally
|
||||
docker build -t towerops-agent:local .
|
||||
|
||||
# Test local image
|
||||
docker run --rm \
|
||||
-e TOWEROPS_API_URL=http://host.docker.internal:4000 \
|
||||
-e TOWEROPS_AGENT_TOKEN=test-token \
|
||||
-v $(pwd)/test-data:/data \
|
||||
towerops-agent:local
|
||||
```
|
||||
|
||||
### Test Before Pushing
|
||||
|
||||
```bash
|
||||
# Check compilation
|
||||
cargo check --release
|
||||
|
||||
# Format check
|
||||
cargo fmt -- --check
|
||||
|
||||
# Lint check
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
# All together (what CI runs)
|
||||
cargo check --release && \
|
||||
cargo fmt -- --check && \
|
||||
cargo clippy -- -D warnings
|
||||
```
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
### If Latest Version Has Issues
|
||||
|
||||
**Option 1: Revert Tag**
|
||||
```bash
|
||||
# Find previous working version
|
||||
git tag -l
|
||||
|
||||
# Delete bad tag locally and remotely
|
||||
git tag -d v0.2.0
|
||||
git push origin :refs/tags/v0.2.0
|
||||
|
||||
# Customers can use previous version
|
||||
docker pull registry.gitlab.com/graham/towerops-agent:0.1.0
|
||||
```
|
||||
|
||||
**Option 2: Quick Fix**
|
||||
```bash
|
||||
# Fix the issue
|
||||
git commit -m "Hotfix: fix critical bug"
|
||||
|
||||
# Create patch version
|
||||
git tag v0.2.1
|
||||
git push origin main --tags
|
||||
|
||||
# New pipeline builds v0.2.1 and updates latest
|
||||
```
|
||||
|
||||
**Option 3: Pin Customers to Known Good Version**
|
||||
|
||||
Update customer docker-compose.yml:
|
||||
```yaml
|
||||
image: registry.gitlab.com/graham/towerops-agent:0.1.0 # Pin to working version
|
||||
```
|
||||
|
||||
## Multi-Architecture Support (Optional)
|
||||
|
||||
To support ARM devices (Raspberry Pi, etc.), uncomment the multi-arch section in `.gitlab-ci.yml`.
|
||||
|
||||
This will build for:
|
||||
- `linux/amd64` (x86_64 servers)
|
||||
- `linux/arm64` (ARM servers, Raspberry Pi 4+)
|
||||
|
||||
**Note**: Multi-arch builds take longer (~2x build time).
|
||||
|
||||
## Monitoring Deployments
|
||||
|
||||
### Check Image Size
|
||||
|
||||
```bash
|
||||
docker images registry.gitlab.com/graham/towerops-agent
|
||||
```
|
||||
|
||||
Expected size: 10-20 MB
|
||||
|
||||
### Check Registry Usage
|
||||
|
||||
GitLab provides 10 GB of free registry storage. Monitor usage at:
|
||||
```
|
||||
https://gitlab.com/graham/towerops-agent/-/packages
|
||||
```
|
||||
|
||||
### Cleanup Old Images
|
||||
|
||||
GitLab has automatic cleanup policies. Configure at:
|
||||
```
|
||||
Settings → Packages & Registries → Container Registry → Cleanup policies
|
||||
```
|
||||
|
||||
Recommended settings:
|
||||
- Keep most recent: 10 tags
|
||||
- Keep tags matching: `^v\d+\.\d+\.\d+$` (versions)
|
||||
- Remove tags older than: 90 days
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Pipeline Fails at Test Stage
|
||||
|
||||
**Symptom**: `cargo check` or `cargo clippy` fails
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Run locally to see errors
|
||||
cargo check --release
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
# Fix issues and push
|
||||
git add .
|
||||
git commit -m "Fix clippy warnings"
|
||||
git push
|
||||
```
|
||||
|
||||
### Pipeline Fails at Build Stage
|
||||
|
||||
**Symptom**: Docker build fails
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Test Docker build locally
|
||||
docker build -t test .
|
||||
|
||||
# Check Dockerfile syntax
|
||||
# Check .dockerignore isn't excluding needed files
|
||||
```
|
||||
|
||||
### Image Too Large
|
||||
|
||||
**Symptom**: Image is >50 MB
|
||||
|
||||
**Fix**:
|
||||
- Check release profile in Cargo.toml (should have `strip = true`)
|
||||
- Verify multi-stage build is working
|
||||
- Check for large files in context (review .dockerignore)
|
||||
|
||||
### Can't Pull Image
|
||||
|
||||
**Symptom**: `docker pull` fails with authentication error
|
||||
|
||||
**Fix**:
|
||||
```bash
|
||||
# Login to GitLab registry
|
||||
docker login registry.gitlab.com
|
||||
# Username: your GitLab username
|
||||
# Password: personal access token with read_registry scope
|
||||
|
||||
# Or use deploy token (for customers)
|
||||
# Create at: Settings → Repository → Deploy tokens
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
### Container Scanning (Optional)
|
||||
|
||||
Add to `.gitlab-ci.yml` for security scanning:
|
||||
|
||||
```yaml
|
||||
include:
|
||||
- template: Security/Container-Scanning.gitlab-ci.yml
|
||||
|
||||
container_scanning:
|
||||
stage: test
|
||||
variables:
|
||||
CS_IMAGE: $REGISTRY/$IMAGE_NAME:$CI_COMMIT_SHORT_SHA
|
||||
```
|
||||
|
||||
### Private Registry Access
|
||||
|
||||
For customers needing private access:
|
||||
|
||||
1. Create deploy token:
|
||||
- Go to: Settings → Repository → Deploy tokens
|
||||
- Name: `customer-deploy-token`
|
||||
- Scopes: `read_registry`
|
||||
- Copy username and token
|
||||
|
||||
2. Provide to customer:
|
||||
```bash
|
||||
docker login registry.gitlab.com
|
||||
# Username: <deploy-token-username>
|
||||
# Password: <deploy-token>
|
||||
```
|
||||
|
||||
## Support
|
||||
|
||||
For issues with deployment:
|
||||
1. Check pipeline logs in GitLab
|
||||
2. Review CLAUDE.md for architecture details
|
||||
3. Test locally with `docker build`
|
||||
4. Check GitLab registry status page
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: January 9, 2026
|
||||
**Registry**: registry.gitlab.com/graham/towerops-agent
|
||||
**Current Version**: 0.1.0 (pre-release)
|
||||
10
README.md
10
README.md
|
|
@ -17,6 +17,14 @@ The Towerops agent enables customers to deploy SNMP polling infrastructure on th
|
|||
|
||||
## Quick Start
|
||||
|
||||
### Using Pre-built Image
|
||||
|
||||
Pull the latest image from GitLab Container Registry:
|
||||
|
||||
```bash
|
||||
docker pull registry.gitlab.com/graham/towerops-agent:latest
|
||||
```
|
||||
|
||||
### Using Docker Compose
|
||||
|
||||
1. Create a `docker-compose.yml` file:
|
||||
|
|
@ -25,7 +33,7 @@ The Towerops agent enables customers to deploy SNMP polling infrastructure on th
|
|||
version: '3.8'
|
||||
services:
|
||||
towerops-agent:
|
||||
image: towerops/agent:latest
|
||||
image: registry.gitlab.com/graham/towerops-agent:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- TOWEROPS_API_URL=https://app.towerops.com
|
||||
|
|
|
|||
41
docker-compose.example.yml
Normal file
41
docker-compose.example.yml
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
towerops-agent:
|
||||
image: registry.gitlab.com/graham/towerops-agent:latest
|
||||
container_name: towerops-agent
|
||||
restart: unless-stopped
|
||||
|
||||
environment:
|
||||
# Required: Your Towerops API URL
|
||||
- TOWEROPS_API_URL=https://app.towerops.com
|
||||
|
||||
# Required: Agent authentication token (from Towerops web UI)
|
||||
# Get this from: Organization > Agents > Create New Agent
|
||||
- TOWEROPS_AGENT_TOKEN=your-agent-token-here
|
||||
|
||||
# Optional: How often to refresh configuration (seconds)
|
||||
# Default: 300 (5 minutes)
|
||||
# - CONFIG_REFRESH_SECONDS=300
|
||||
|
||||
# Optional: Database path for metrics buffering
|
||||
# Default: /data/towerops-agent.db
|
||||
# - DATABASE_PATH=/data/towerops-agent.db
|
||||
|
||||
# Optional: Log level (error, warn, info, debug, trace)
|
||||
# Default: info
|
||||
# - RUST_LOG=info
|
||||
|
||||
volumes:
|
||||
# Persistent storage for metrics buffering
|
||||
- ./data:/data
|
||||
|
||||
# Optional: Resource limits
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
reservations:
|
||||
cpus: '0.1'
|
||||
memory: 128M
|
||||
Loading…
Add table
Reference in a new issue