first commit

This commit is contained in:
Antony Messerli 2021-09-06 19:07:15 -05:00
commit 027cd38089
9 changed files with 410 additions and 0 deletions

135
.github/workflows/build.yml vendored Normal file
View File

@ -0,0 +1,135 @@
name: netbootxyz
on:
push:
schedule:
- cron: '0 6 * * 0'
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
fetch-depth: '0'
- name: Set env variables
run: |
echo "GITHUB_DATE=$(date +'%Y-%m-%dT%H:%M:%S')" >> $GITHUB_ENV
echo "GITHUB_SHA=${{ github.sha }}" >> $GITHUB_ENV
- name: Get latest Webapp release version
run: |
WEBAPP_RELEASE=$(curl -sX GET "https://api.github.com/repos/netbootxyz/webapp/releases/latest" | jq -r '. | .tag_name')
echo "WEBAPP_RELEASE=${WEBAPP_RELEASE}" >> $GITHUB_ENV
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Set up QEMU
uses: docker/setup-qemu-action@v1
- name: Login to the GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ secrets.GHCR_USER }}
password: ${{ secrets.GHCR_TOKEN }}
- name: Determine version numbers
id: version_check
continue-on-error: true
run: |
tag=latest
IMAGE=antonym/netbootxyz
TOKEN=$(curl -sX GET \
"https://ghcr.io/token?scope=repository%3Aantonym%2Fnetbootxyz%3Apull" \
| jq -r '.token')
MULTIDIGEST=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${TOKEN}" \
"https://ghcr.io/v2/${IMAGE}/manifests/${tag}" \
| jq -r 'first(.manifests[].digest)')
DIGEST=$(curl -s \
--header "Accept: application/vnd.docker.distribution.manifest.v2+json" \
--header "Authorization: Bearer ${TOKEN}" \
"https://ghcr.io/v2/${IMAGE}/manifests/${MULTIDIGEST}" \
| jq -r '.config.digest')
IMAGE_INFO=$(curl -sL \
--header "Authorization: Bearer ${TOKEN}" \
"https://ghcr.io/v2/${IMAGE}/blobs/${DIGEST}" \
| jq -r '.config')
IMAGE_RELEASE=$(echo ${IMAGE_INFO} | jq -r '.Labels.build_version' | awk '{print $3}')
IMAGE_VERSION=$(echo ${IMAGE_RELEASE} | awk -F'-nbxyz' '{print $1}')
NB_RELEASE_NUMBER=$(echo ${IMAGE_RELEASE} | awk -F'-nbxyz' '{print $2}')
TAG_SHA=$(git rev-list -n 1 ${IMAGE_RELEASE})
if [ -z "${MULTIDIGEST}" ] || [ "${MULTIDIGEST}" == "null" ]; then
echo "**** No existing container build found, assuming first build ****"
VERSION_TAG=${WEBAPP_RELEASE}-nbxyz1
echo "VERSION_TAG=${VERSION_TAG}" >> $GITHUB_ENV
elif [ "${WEBAPP_RELEASE}" == "${IMAGE_VERSION}" ]; then
echo "**** Version ${WEBAPP_RELEASE} unchanged, checking if there is anything to build..."
if [ "${TAG_SHA}" == "${GITHUB_SHA}" ]; then
echo "**** Nothing to do, exiting build... **** "
exit 1
else
echo "**** Changes found... incrementing build number version... ****"
NB_RELEASE_NUMBER=$((NB_RELEASE_NUMBER + 1))
VERSION_TAG=${IMAGE_VERSION}-nbxyz${NB_RELEASE_NUMBER}
echo "VERSION_TAG=${VERSION_TAG}" >> $GITHUB_ENV
fi
else
echo "**** New version ${WEBAPP_RELEASE} found; old version was ${IMAGE_VERSION}. Generating new webapp release... ****"
VERSION_TAG=${WEBAPP_RELEASE}-nbxyz1
echo "VERSION_TAG=${VERSION_TAG}" >> $GITHUB_ENV
fi
- name: Docker meta
if: steps.version_check.outcome == 'success' && steps.version_check.conclusion == 'success'
id: meta
uses: docker/metadata-action@v3
with:
images: netbootxyz/netbootxyz
labels: |
maintainer=antonym
org.opencontainers.image.created=${{ env.GITHUB_DATE }}
org.opencontainers.image.authors=netboot.xyz
org.opencontainers.image.url=https://github.com/netbootxyz/docker-netbootxyz/packages
org.opencontainers.image.documentation=https://netboot.xyz
org.opencontainers.image.source=https://github.com/netbootxyz/docker-netbootxyz
org.opencontainers.image.version=${{ env.VERSION_TAG }}
org.opencontainers.image.revision=${{ env.GITHUB_SHA }}
org.opencontainers.image.vendor=netboot.xyz
org.opencontainers.image.licenses=Apache-2.0
org.opencontainers.image.ref.name=${{ env.GITHUB_SHA }}
org.opencontainers.image.title=netbootxyz
org.opencontainers.image.description=netboot.xyz official docker container - Your favorite operating systems in one place. A network-based bootable operating system installer based on iPXE.
- name: Build and push image
if: steps.version_check.outcome == 'success' && steps.version_check.conclusion == 'success'
uses: docker/build-push-action@v2
with:
push: true
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
build-args: |
WEBAPP_VERSION=${{ env.WEBAPP_RELEASE }}
VERSION=${{ env.VERSION_TAG }}
BUILD_DATE=${{ env.GITHUB_DATE }}
tags: |
ghcr.io/antonym/${{ github.workflow }}:latest
ghcr.io/antonym/${{ github.workflow }}:${{ github.sha }}
ghcr.io/antonym/${{ github.workflow }}:${{ env.VERSION_TAG }}
labels: ${{ steps.meta.outputs.labels }}
- name: Bump version and push tag
if: steps.version_check.outcome == 'success' && steps.version_check.conclusion == 'success'
id: tag_version
uses: anothrNick/github-tag-action@1.26.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CUSTOM_TAG: ${{ env.VERSION_TAG }}
WITH_V: true
RELEASE_BRANCHES: main

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
go.sh

56
Dockerfile Normal file
View File

@ -0,0 +1,56 @@
FROM alpine:3.14
# set version label
ARG BUILD_DATE
ARG VERSION
ARG WEBAPP_VERSION
LABEL build_version="netboot.xyz version: ${VERSION} Build-date: ${BUILD_DATE}"
LABEL maintainer="antonym"
RUN \
apk add --no-cache --virtual=build-dependencies \
nodejs npm && \
echo "**** install runtime packages ****" && \
apk add --no-cache \
bash \
busybox \
curl \
git \
jq \
nghttp2-dev \
nginx \
nodejs \
shadow \
sudo \
supervisor \
syslog-ng \
tar \
tftp-hpa
RUN \
groupmod -g 1000 users && \
useradd -u 911 -U -d /config -s /bin/false nbxyz && \
usermod -G users nbxyz && \
mkdir /app \
/config \
/defaults && \
if [ -z ${WEBAPP_VERSION+x} ]; then \
WEBAPP_VERSION=$(curl -sX GET "https://api.github.com/repos/netbootxyz/webapp/releases/latest" \
| awk '/tag_name/{print $4;exit}' FS='[""]'); \
fi && \
curl -o \
/tmp/webapp.tar.gz -L \
"https://github.com/netbootxyz/webapp/archive/${WEBAPP_VERSION}.tar.gz" && \
tar xf \
/tmp/webapp.tar.gz -C \
/app/ --strip-components=1 && \
npm config set unsafe-perm true && \
npm install --prefix /app
EXPOSE 3000
COPY root/ /
# default command
CMD ["sh","/start.sh"]

69
README.md Normal file
View File

@ -0,0 +1,69 @@
# docker-netbootxyz
## Overview
The netboot.xyz docker image allows you to easily set up a local instance of netboot.xyz with a single command. The container is built from Alpine Linux and contains several components:
* netboot.xyz [webapp](https://github.com/netbootxyz/webapp)
* Nginx for hosting local assets from the container
* tftp-hpa
* syslog for providing tftp activity logs
Services are managed in the container by [supervisord](http://supervisord.org/).
## Usage
The following snippets are examples of starting up the container.
### docker-cli
```
docker run -d \
--name=netbootxyz \
-e MENU_VERSION=2.0.47 `# optional` \
-p 3000:3000 \ # sets webapp port
-p 69:69/udp \ # sets tftp port
-p 8080:80 `# optional` \
-v /local/path/to/config:/config `# optional` \
-v /local/path/to/assets:/assets `# optional` \
--restart unless-stopped \
ghcr.io/netbootxyz/netbootxyz
```
### docker-compose
```
---
version: "2.1"
services:
netbootxyz:
image: ghcr.io/netbootxyz/netbootxyz
container_name: netbootxyz
environment:
- MENU_VERSION=2.0.47 # optional
volumes:
- /local/path/to/config:/config # optional
- /local/path/to/assets:/assets # optional
ports:
- 3000:3000
- 69:69/udp
- 8080:80 #optional
restart: unless-stopped
```
Once the container is started, the netboot.xyz web application can be accessed by the web configuration interface at http://localhost:3000 or via the specified port.
Downloaded web assets will be available at http://localhost:8080 or the specified port. If you have specified the assets volume, the assets will be available at http://localhost:8080.
If you wish to start over from scratch, you can remove the local configuration folders and upon restart of the container, it will load the default configurations.
## Parameters:
Container images are configured using parameters passed at runtime (such as those above). These parameters are separated by a colon and indicate `<external>:<internal>` respectively. For example, `-p 8080:80` would expose port `80` from inside the container to be accessible from the host's IP on port `8080` outside the container.
| Parameter | Function |
| :----: | --- |
| `-p 3000` | Web configuration interface. |
| `-p 69/udp` | TFTP Port. |
| `-p 80` | NGINX server for hosting assets. |
| `-e MENU_VERSION=2.0.47` | Specify a specific version of boot files you want to use from netboot.xyz (unset pulls latest) |
| `-v /config` | Storage for boot menu files and web application config |
| `-v /assets` | Storage for netboot.xyz bootable assets (live CDs and other files) |

7
root/defaults/default Normal file
View File

@ -0,0 +1,7 @@
server {
listen 80;
location / {
root /assets;
autoindex on;
}
}

26
root/defaults/nginx.conf Normal file
View File

@ -0,0 +1,26 @@
user nbxyz;
worker_processes 4;
pid /run/nginx.pid;
include /etc/nginx/modules/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 0;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /config/log/nginx/access.log;
error_log /config/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /config/nginx/site-confs/*;
}
daemon off;

1
root/donate.txt Normal file
View File

@ -0,0 +1 @@
netboot.xyz: https://opencollective.com/netbootxyz/donate

33
root/etc/supervisor.conf Normal file
View File

@ -0,0 +1,33 @@
[supervisord]
nodaemon=true
user=root
[program:syslog-ng]
command=/usr/sbin/syslog-ng --foreground --no-caps
stdout_syslog=true
stdout_capture_maxbytes=1MB
priority = 1
[program:nginx]
command = /usr/sbin/nginx -c /config/nginx/nginx.conf
startretries = 2
daemon=off
priority = 2
[program:webapp]
environment=NODE_ENV="production",PORT=3000
command=/usr/bin/node app.js
user=nbxyz
directory=/app
priority = 3
[program:in.tftpd]
command=/usr/sbin/in.tftpd -Lvvv --user nbxyz --secure /config/menus
stdout_logfile=/config/tftpd.log
redirect_stderr=true
priority = 4
[program:messages-log]
command=tail -f /var/log/messages
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0

82
root/start.sh Executable file
View File

@ -0,0 +1,82 @@
#!/bin/bash
# make our folders
mkdir -p \
/assets \
/config/nginx/site-confs \
/config/log/nginx \
/run \
/var/lib/nginx/tmp/client_body \
/var/tmp/nginx
# copy config files
[[ ! -f /config/nginx/nginx.conf ]] && \
cp /defaults/nginx.conf /config/nginx/nginx.conf
[[ ! -f /config/nginx/site-confs/default ]] && \
cp /defaults/default /config/nginx/site-confs/default
# Ownership
chown -R nbxyz:nbxyz /assets
chown -R nbxyz:nbxyz /var/lib/nginx
chown -R nbxyz:nbxyz /var/log/nginx
# create local logs dir
mkdir -p \
/config/menus/remote \
/config/menus/local
# download menus if not found
if [[ ! -f /config/menus/remote/menu.ipxe ]]; then
if [[ -z ${MENU_VERSION+x} ]]; then \
MENU_VERSION=$(curl -sL "https://api.github.com/repos/netbootxyz/netboot.xyz/releases/latest" | jq -r '.tag_name')
fi
echo "[netbootxyz-init] Downloading netboot.xyz at ${MENU_VERSION}"
# menu files
curl -o \
/config/endpoints.yml -sL \
"https://raw.githubusercontent.com/netbootxyz/netboot.xyz/${MENU_VERSION}/endpoints.yml"
curl -o \
/tmp/menus.tar.gz -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/menus.tar.gz"
tar xf \
/tmp/menus.tar.gz -C \
/config/menus/remote
# boot files
curl -o \
/config/menus/remote/netboot.xyz.kpxe -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz.kpxe"
curl -o \
/config/menus/remote/netboot.xyz-undionly.kpxe -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz-undionly.kpxe"
curl -o \
/config/menus/remote/netboot.xyz.efi -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz.efi"
curl -o \
/config/menus/remote/netboot.xyz-snp.efi -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz-snp.efi"
curl -o \
/config/menus/remote/netboot.xyz-snponly.efi -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz-snponly.efi"
curl -o \
/config/menus/remote/netboot.xyz-arm64.efi -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz-arm64.efi"
curl -o \
/config/menus/remote/netboot.xyz-arm64.efi -sL \
"https://github.com/netbootxyz/netboot.xyz/releases/download/${MENU_VERSION}/netboot.xyz-rpi4-snp.efi"
# layer and cleanup
echo -n ${MENU_VERSION} > /config/menuversion.txt
cp -r /config/menus/remote/* /config/menus
rm -f /tmp/menus.tar.gz
fi
# Ownership
chown -R nbxyz:nbxyz /config
echo " _ _ _ "
echo " _ __ ___| |_| |__ ___ ___ | |_ __ ___ _ ____ "
echo "| '_ \ / _ \ __| '_ \ / _ \ / _ \| __| \ \/ / | | |_ / "
echo "| | | | __/ |_| |_) | (_) | (_) | |_ _ > <| |_| |/ / "
echo "|_| |_|\___|\__|_.__/ \___/ \___/ \__(_)_/\_\\__, /___| "
echo " |___/ "
supervisord -c /etc/supervisor.conf