Skip to content

Commit f91a5c6

Browse files
committed
ova building
1 parent 0cdf42c commit f91a5c6

13 files changed

Lines changed: 488 additions & 0 deletions

.github/workflows/build-ova.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Build OVF Image
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
core_tag:
7+
description: "defguard core image tag"
8+
required: true
9+
proxy_tag:
10+
description: "defguard proxy image tag"
11+
required: true
12+
gateway_tag:
13+
description: "defguard gateway image tag"
14+
required: true
15+
16+
jobs:
17+
build:
18+
runs-on: [self-hosted, Linux, X64]
19+
20+
defaults:
21+
run:
22+
working-directory: ova
23+
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v4
27+
28+
- name: Install dependencies
29+
run: |
30+
sudo apt-get update -qq
31+
sudo apt-get install -y --no-install-recommends \
32+
qemu-kvm \
33+
qemu-utils \
34+
ovmf \
35+
cpu-checker
36+
37+
- name: Check KVM availability
38+
run: kvm-ok
39+
40+
- name: Setup Packer
41+
uses: hashicorp/setup-packer@main
42+
with:
43+
version: latest
44+
45+
- name: Cache ISO
46+
uses: actions/cache@v4
47+
with:
48+
path: ova/ubuntu-24.04.4-live-server-amd64.iso
49+
key: ubuntu-24.04.4-live-server-amd64-iso
50+
51+
- name: Download ISO (if not cached)
52+
run: |
53+
if [ ! -f ubuntu-24.04.4-live-server-amd64.iso ]; then
54+
curl -fL -o ubuntu-24.04.4-live-server-amd64.iso \
55+
https://releases.ubuntu.com/24.04.4/ubuntu-24.04.4-live-server-amd64.iso
56+
fi
57+
58+
- name: Packer init
59+
run: packer init defguard.pkr.hcl
60+
61+
- name: Packer build
62+
run: |
63+
packer build \
64+
-var "iso_url=file://$PWD/ubuntu-24.04.4-live-server-amd64.iso" \
65+
-var "core_tag=${{ github.event.inputs.core_tag }}" \
66+
-var "proxy_tag=${{ github.event.inputs.proxy_tag }}" \
67+
-var "gateway_tag=${{ github.event.inputs.gateway_tag }}" \
68+
defguard.pkr.hcl
69+
70+
- name: Print OVA size
71+
run: ls -lh output/defguard/defguard.ova

ova/build-ova.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
TAG="2.0.0-alpha2"
5+
ISO_PATH="${PWD}/ubuntu-24.04.4-live-server-amd64.iso"
6+
7+
if [ ! -f "$ISO_PATH" ]; then
8+
echo "Missing ISO: $ISO_PATH" >&2
9+
echo "Download it first with:" >&2
10+
echo " curl -fL -o ubuntu-24.04.4-live-server-amd64.iso https://releases.ubuntu.com/24.04.4/ubuntu-24.04.4-live-server-amd64.iso" >&2
11+
exit 1
12+
fi
13+
14+
packer init defguard.pkr.hcl
15+
16+
packer build \
17+
-var "iso_url=file://$ISO_PATH" \
18+
-var "core_tag=$TAG" \
19+
-var "proxy_tag=$TAG" \
20+
-var "gateway_tag=$TAG" \
21+
defguard.pkr.hcl

ova/defguard.pkr.hcl

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
packer {
2+
required_plugins {
3+
qemu = {
4+
version = ">= 1.0.9"
5+
source = "github.com/hashicorp/qemu"
6+
}
7+
}
8+
}
9+
10+
variable "vm_name" { default = "defguard" }
11+
variable "disk_size" { default = "20G" }
12+
variable "memory" { default = 2048 }
13+
variable "cpus" { default = 2 }
14+
variable "ssh_user" { default = "ubuntu" }
15+
variable "iso_url" { default = "https://releases.ubuntu.com/24.04.4/ubuntu-24.04.4-live-server-amd64.iso" }
16+
variable "core_tag" { type = string }
17+
variable "proxy_tag" { type = string }
18+
variable "gateway_tag" { type = string }
19+
20+
source "qemu" "ubuntu24" {
21+
iso_url = var.iso_url
22+
iso_checksum = "sha256:e907d92eeec9df64163a7e454cbc8d7755e8ddc7ed42f99dbc80c40f1a138433"
23+
24+
vm_name = var.vm_name
25+
memory = var.memory
26+
cpus = var.cpus
27+
disk_size = var.disk_size
28+
accelerator = "kvm"
29+
format = "qcow2"
30+
output_directory = "output/${var.vm_name}"
31+
32+
net_device = "virtio-net"
33+
disk_interface = "virtio"
34+
machine_type = "q35"
35+
36+
ssh_username = var.ssh_user
37+
ssh_password = "ubuntu"
38+
ssh_timeout = "40m"
39+
ssh_handshake_attempts = 100
40+
41+
http_content = {
42+
"/meta-data" = file("${path.root}/http/meta-data")
43+
"/user-data" = file("${path.root}/http/user-data")
44+
}
45+
boot_wait = "5s"
46+
boot_command = [
47+
"c<wait5>",
48+
"linux /casper/vmlinuz autoinstall 'ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/'<enter><wait5>",
49+
"initrd /casper/initrd<enter><wait5>",
50+
"boot<enter>"
51+
]
52+
53+
shutdown_command = "sudo shutdown -P now"
54+
headless = true
55+
}
56+
57+
build {
58+
sources = ["source.qemu.ubuntu24"]
59+
60+
provisioner "file" {
61+
source = "files/docker-setup.sh"
62+
destination = "/tmp/docker-setup.sh"
63+
}
64+
65+
provisioner "file" {
66+
source = "files/99-defguard.cfg"
67+
destination = "/tmp/99-defguard.cfg"
68+
}
69+
70+
provisioner "file" {
71+
source = "files/docker-compose.yaml"
72+
destination = "/tmp/docker-compose.yaml"
73+
}
74+
75+
provisioner "file" {
76+
source = "files/docker-compose.standalone.yaml"
77+
destination = "/tmp/docker-compose.standalone.yaml"
78+
}
79+
80+
provisioner "file" {
81+
source = "files/generate-env.sh"
82+
destination = "/tmp/generate-env.sh"
83+
}
84+
85+
provisioner "file" {
86+
source = "files/start.sh"
87+
destination = "/tmp/start.sh"
88+
}
89+
90+
provisioner "file" {
91+
source = "files/defguard-init.service"
92+
destination = "/tmp/defguard-init.service"
93+
}
94+
95+
provisioner "shell" {
96+
inline = [
97+
"sudo bash /tmp/docker-setup.sh",
98+
"sudo mkdir -p /opt/defguard",
99+
"sudo mv /tmp/docker-compose.yaml /opt/defguard/docker-compose.yaml",
100+
"sudo mv /tmp/docker-compose.standalone.yaml /opt/defguard/docker-compose.standalone.yaml",
101+
"sudo mv /tmp/generate-env.sh /opt/defguard/generate-env.sh",
102+
"sudo chmod +x /opt/defguard/generate-env.sh",
103+
"sudo mv /tmp/start.sh /opt/defguard/start.sh",
104+
"sudo chmod +x /opt/defguard/start.sh",
105+
"echo 'DEFGUARD_CORE_TAG=${var.core_tag}' | sudo tee /opt/defguard/.image-tags > /dev/null",
106+
"echo 'DEFGUARD_PROXY_TAG=${var.proxy_tag}' | sudo tee -a /opt/defguard/.image-tags > /dev/null",
107+
"echo 'DEFGUARD_GATEWAY_TAG=${var.gateway_tag}' | sudo tee -a /opt/defguard/.image-tags > /dev/null",
108+
"sudo mv /tmp/99-defguard.cfg /etc/cloud/cloud.cfg.d/99-defguard.cfg",
109+
"sudo mv /tmp/defguard-init.service /etc/systemd/system/defguard-init.service",
110+
"sudo systemctl daemon-reload",
111+
"sudo systemctl enable docker.service",
112+
"sudo chown -R ubuntu:ubuntu /opt/defguard",
113+
"sudo rm -f /etc/netplan/00-installer-config.yaml /etc/netplan/50-cloud-init.yaml",
114+
"sudo cloud-init clean --logs",
115+
"sudo rm -f /etc/ssh/ssh_host_*",
116+
"sudo rm -f /root/.ssh/authorized_keys",
117+
"sudo rm -f /home/ubuntu/.ssh/authorized_keys",
118+
"sudo truncate -s 0 /home/ubuntu/.bash_history || true",
119+
"sudo truncate -s 0 /root/.bash_history || true",
120+
# Expire default password so it must be changed on first login
121+
"sudo chage -d 0 ubuntu"
122+
]
123+
}
124+
125+
post-processor "shell-local" {
126+
inline = [
127+
"qemu-img convert -f qcow2 -O vmdk output/${var.vm_name}/${var.vm_name} output/${var.vm_name}/${var.vm_name}.vmdk",
128+
"cp files/ubuntu.vmx output/${var.vm_name}/${var.vm_name}.vmx",
129+
"ovftool --lax --diskMode=thin output/${var.vm_name}/${var.vm_name}.vmx output/${var.vm_name}/${var.vm_name}.ova"
130+
]
131+
}
132+
}

ova/files/99-defguard.cfg

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#cloud-config
2+
runcmd:
3+
- systemctl start defguard-init.service

ova/files/defguard-init.service

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[Unit]
2+
Description=DefGuard first-boot initialisation
3+
After=network-online.target docker.service
4+
Wants=network-online.target docker.service
5+
6+
[Service]
7+
Type=oneshot
8+
WorkingDirectory=/opt/defguard
9+
StandardOutput=append:/var/log/defguard-startup.log
10+
StandardError=append:/var/log/defguard-startup.log
11+
ExecStart=/bin/bash /opt/defguard/generate-env.sh
12+
ExecStart=/bin/bash /opt/defguard/start.sh
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
services:
2+
core:
3+
restart: always
4+
profiles: [core]
5+
image: ghcr.io/defguard/defguard:${DEFGUARD_CORE_TAG:?DEFGUARD_CORE_TAG is required}
6+
env_file: .env
7+
environment:
8+
DEFGUARD_DB_HOST: db
9+
DEFGUARD_DB_PORT: 5432
10+
depends_on:
11+
- db
12+
ports:
13+
- "8000:8000"
14+
15+
edge:
16+
restart: always
17+
profiles: [edge]
18+
image: ghcr.io/defguard/defguard-proxy:${DEFGUARD_PROXY_TAG:?DEFGUARD_PROXY_TAG is required}
19+
volumes:
20+
- ./.volumes/certs/edge:/etc/defguard/certs
21+
ports:
22+
- "8080:8080"
23+
- "50051:50051"
24+
25+
gateway:
26+
restart: always
27+
profiles: [gateway]
28+
image: ghcr.io/defguard/gateway:${DEFGUARD_GATEWAY_TAG:?DEFGUARD_GATEWAY_TAG is required}
29+
cap_add:
30+
- NET_ADMIN
31+
volumes:
32+
- ./.volumes/certs/gateway:/etc/defguard/certs
33+
network_mode: "host"
34+
environment:
35+
DEFGUARD_STATS_PERIOD: 10
36+
HEALTH_PORT: 55003
37+
38+
npm:
39+
image: "jc21/nginx-proxy-manager:latest"
40+
restart: unless-stopped
41+
profiles: [edge, core]
42+
43+
ports:
44+
- "80:80" # HTTP Port
45+
- "443:443" # HTTPS Port
46+
- "81:81" # Admin Web Port
47+
48+
db:
49+
restart: always
50+
profiles: [core]
51+
image: postgres:18-alpine
52+
env_file: .env
53+
volumes:
54+
- ./.volumes/db:/var/lib/postgresql

ova/files/docker-compose.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
services:
2+
core:
3+
restart: always
4+
image: ghcr.io/defguard/defguard:${DEFGUARD_CORE_TAG:?DEFGUARD_CORE_TAG is required}
5+
env_file: .env
6+
environment:
7+
DEFGUARD_DB_HOST: db
8+
DEFGUARD_DB_PORT: 5432
9+
DEFGUARD_ADOPT_EDGE: "edge:50051"
10+
DEFGUARD_ADOPT_GATEWAY: "host.docker.internal:50066"
11+
extra_hosts:
12+
- "host.docker.internal:host-gateway"
13+
depends_on:
14+
- db
15+
- edge
16+
- gateway
17+
ports:
18+
- "8000:8000"
19+
20+
edge:
21+
restart: always
22+
image: ghcr.io/defguard/defguard-proxy:${DEFGUARD_PROXY_TAG:?DEFGUARD_PROXY_TAG is required}
23+
volumes:
24+
- ./.volumes/certs/edge:/etc/defguard/certs
25+
ports:
26+
- "8080:8080"
27+
28+
gateway:
29+
restart: always
30+
image: ghcr.io/defguard/gateway:${DEFGUARD_GATEWAY_TAG:?DEFGUARD_GATEWAY_TAG is required}
31+
cap_add:
32+
- NET_ADMIN
33+
volumes:
34+
- ./.volumes/certs/gateway:/etc/defguard/certs
35+
environment:
36+
DEFGUARD_STATS_PERIOD: 10
37+
HEALTH_PORT: 55003
38+
network_mode: "host"
39+
40+
npm:
41+
image: "jc21/nginx-proxy-manager:latest"
42+
restart: unless-stopped
43+
44+
ports:
45+
- "80:80" # HTTP Port
46+
- "443:443" # HTTPS Port
47+
- "81:81" # Admin Web Port
48+
49+
environment:
50+
TZ: "UTC"
51+
52+
volumes:
53+
- ./.volumes/npm/data:/data
54+
- ./.volumes/npm/letsencrypt:/etc/letsencrypt
55+
56+
db:
57+
restart: always
58+
image: postgres:18-alpine
59+
env_file: .env
60+
volumes:
61+
- ./.volumes/db:/var/lib/postgresql

ova/files/docker-setup.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
set -e
3+
4+
apt-get update
5+
apt-get install -y ca-certificates curl
6+
install -m 0755 -d /etc/apt/keyrings
7+
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
8+
chmod a+r /etc/apt/keyrings/docker.asc
9+
10+
. /etc/os-release
11+
CODENAME="${UBUNTU_CODENAME:-$VERSION_CODENAME}"
12+
13+
tee /etc/apt/sources.list.d/docker.sources <<EOF
14+
Types: deb
15+
URIs: https://download.docker.com/linux/ubuntu
16+
Suites: ${CODENAME}
17+
Components: stable
18+
Signed-By: /etc/apt/keyrings/docker.asc
19+
EOF
20+
21+
apt-get update
22+
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
23+
usermod -aG docker ubuntu

0 commit comments

Comments
 (0)