1
0
mirror of https://github.com/esphome/esphome.git synced 2025-04-19 01:00:28 +01:00

[docker] Use new base image for better caching

This commit is contained in:
Jesse Hills 2024-09-02 18:38:51 +12:00
parent 854bafbd4a
commit 89edd86de9
No known key found for this signature in database
GPG Key ID: BEAAE804EFD8E83A
7 changed files with 50 additions and 191 deletions

View File

@ -111,4 +111,5 @@ config/
examples/ examples/
Dockerfile Dockerfile
.git/ .git/
tests/build/ tests/
.*

View File

@ -7,11 +7,11 @@ inputs:
target: target:
description: "Target to build" description: "Target to build"
required: true required: true
example: "docker" example: "final / lint"
baseimg: build_type:
description: "Base image type" description: "Image type to build"
required: true required: true
example: "docker" example: "docker / hassio"
suffix: suffix:
description: "Suffix to add to tags" description: "Suffix to add to tags"
required: true required: true
@ -55,7 +55,7 @@ runs:
cache-from: type=gha cache-from: type=gha
cache-to: ${{ steps.cache-to.outputs.value }} cache-to: ${{ steps.cache-to.outputs.value }}
build-args: | build-args: |
BASEIMGTYPE=${{ inputs.baseimg }} BUILD_TYPE=${{ inputs.build_type }}
BUILD_VERSION=${{ inputs.version }} BUILD_VERSION=${{ inputs.version }}
outputs: | outputs: |
type=image,name=ghcr.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true type=image,name=ghcr.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true
@ -78,7 +78,7 @@ runs:
cache-from: type=gha cache-from: type=gha
cache-to: ${{ steps.cache-to.outputs.value }} cache-to: ${{ steps.cache-to.outputs.value }}
build-args: | build-args: |
BASEIMGTYPE=${{ inputs.baseimg }} BUILD_TYPE=${{ inputs.build_type }}
BUILD_VERSION=${{ inputs.version }} BUILD_VERSION=${{ inputs.version }}
outputs: | outputs: |
type=image,name=docker.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true type=image,name=docker.io/${{ steps.tags.outputs.image_name }},push-by-digest=true,name-canonical=true,push=true

View File

@ -111,8 +111,8 @@ jobs:
uses: ./.github/actions/build-image uses: ./.github/actions/build-image
with: with:
platform: ${{ matrix.platform }} platform: ${{ matrix.platform }}
target: docker target: final
baseimg: docker build_type: docker
suffix: "" suffix: ""
version: ${{ needs.init.outputs.tag }} version: ${{ needs.init.outputs.tag }}
@ -120,8 +120,8 @@ jobs:
uses: ./.github/actions/build-image uses: ./.github/actions/build-image
with: with:
platform: ${{ matrix.platform }} platform: ${{ matrix.platform }}
target: hassio target: final
baseimg: hassio build_type: hassio
suffix: "hassio" suffix: "hassio"
version: ${{ needs.init.outputs.tag }} version: ${{ needs.init.outputs.tag }}
@ -130,7 +130,7 @@ jobs:
with: with:
platform: ${{ matrix.platform }} platform: ${{ matrix.platform }}
target: lint target: lint
baseimg: docker build_type: docker
suffix: lint suffix: lint
version: ${{ needs.init.outputs.tag }} version: ${{ needs.init.outputs.tag }}

View File

@ -1,214 +1,73 @@
# Build these with the build.py script ARG BUILD_TYPE=docker
# Example:
# python3 docker/build.py --tag dev --arch amd64 --build-type docker build
# One of "docker", "hassio" FROM ghcr.io/esphome/docker-base:2024.09.0-pre0 AS base
ARG BASEIMGTYPE=docker
RUN git config --system --add safe.directory "*"
# https://github.com/hassio-addons/addon-debian-base/releases COPY requirements.txt /
FROM ghcr.io/hassio-addons/debian-base:7.2.0 AS base-hassio
# https://hub.docker.com/_/debian?tab=tags&page=1&name=bookworm
FROM debian:12.2-slim AS base-docker
FROM base-${BASEIMGTYPE} AS base
ARG TARGETARCH
ARG TARGETVARIANT
# Note that --break-system-packages is used below because
# https://peps.python.org/pep-0668/ added a safety check that prevents
# installing packages with the same name as a system package. This is
# not a problem for us because we are not concerned about overwriting
# system packages because we are running in an isolated container.
RUN \ RUN \
apt-get update \ uv pip install --no-cache-dir \
# Use pinned versions so that we get updates with build caching -r /requirements.txt
&& apt-get install -y --no-install-recommends \
python3-pip=23.0.1+dfsg-1 \
python3-setuptools=66.1.1-1 \
python3-venv=3.11.2-1+b1 \
python3-wheel=0.38.4-2 \
iputils-ping=3:20221126-1 \
git=1:2.39.2-1.1 \
curl=7.88.1-10+deb12u7 \
openssh-client=1:9.2p1-2+deb12u3 \
python3-cffi=1.15.1-5 \
libcairo2=1.16.0-7 \
libmagic1=1:5.44-3 \
patch=2.7.6-7 \
&& ( \
( \
[ "$TARGETARCH$TARGETVARIANT" = "armv7" ] && \
apt-get install -y --no-install-recommends \
build-essential=12.9 \
python3-dev=3.11.2-1+b1 \
zlib1g-dev=1:1.2.13.dfsg-1 \
libjpeg-dev=1:2.1.5-2 \
libfreetype-dev=2.12.1+dfsg-5+deb12u3 \
libssl-dev=3.0.14-1~deb12u1 \
libffi-dev=3.4.4-1 \
libopenjp2-7=2.5.0-2 \
libtiff6=4.5.0-6+deb12u1 \
cargo=0.66.0+ds1-1 \
pkg-config=1.8.1-1 \
gcc-arm-linux-gnueabihf=4:12.2.0-3 \
) \
|| [ "$TARGETARCH$TARGETVARIANT" != "armv7" ] \
) \
&& rm -rf \
/tmp/* \
/var/{cache,log}/* \
/var/lib/apt/lists/*
ENV \
# Fix click python3 lang warning https://click.palletsprojects.com/en/7.x/python3/
LANG=C.UTF-8 LC_ALL=C.UTF-8 \
# Store globally installed pio libs in /piolibs
PLATFORMIO_GLOBALLIB_DIR=/piolibs
# Support legacy binaries on Debian multiarch system. There is no "correct" way
# to do this, other than using properly built toolchains...
# See: https://unix.stackexchange.com/questions/553743/correct-way-to-add-lib-ld-linux-so-3-in-debian
RUN \
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
ln -s /lib/arm-linux-gnueabihf/ld-linux-armhf.so.3 /lib/ld-linux.so.3; \
fi
RUN \ RUN \
# Ubuntu python3-pip is missing wheel
if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
export PIP_EXTRA_INDEX_URL="https://www.piwheels.org/simple"; \
fi; \
pip3 install \
--break-system-packages --no-cache-dir \
# Keep platformio version in sync with requirements.txt
platformio==6.1.15 \
# Change some platformio settings # Change some platformio settings
&& platformio settings set enable_telemetry No \ platformio settings set enable_telemetry No \
&& platformio settings set check_platformio_interval 1000000 \ && platformio settings set check_platformio_interval 1000000 \
&& mkdir -p /piolibs && mkdir -p /piolibs
COPY script/platformio_install_deps.py platformio.ini /
# First install requirements to leverage caching when requirements don't change RUN /platformio_install_deps.py /platformio.ini --libraries
# tmpfs is for https://github.com/rust-lang/cargo/issues/8719
COPY requirements.txt requirements_optional.txt script/platformio_install_deps.py platformio.ini / FROM base AS base-docker
RUN --mount=type=tmpfs,target=/root/.cargo if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
export PIP_EXTRA_INDEX_URL="https://www.piwheels.org/simple"; \
fi; \
CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse CARGO_HOME=/root/.cargo \
pip3 install \
--break-system-packages --no-cache-dir -r /requirements.txt -r /requirements_optional.txt \
&& /platformio_install_deps.py /platformio.ini --libraries
# Avoid unsafe git error when container user and file config volume permissions don't match
RUN git config --system --add safe.directory '*'
# ======================= docker-type image =======================
FROM base AS docker
# Copy esphome and install
COPY . /esphome
RUN if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
export PIP_EXTRA_INDEX_URL="https://www.piwheels.org/simple"; \
fi; \
pip3 install \
--break-system-packages --no-cache-dir -e /esphome
# Settings for dashboard
ENV USERNAME="" PASSWORD="" ENV USERNAME="" PASSWORD=""
# Expose the dashboard to Docker
EXPOSE 6052 EXPOSE 6052
# Run healthcheck (heartbeat)
HEALTHCHECK --interval=30s --timeout=30s \ HEALTHCHECK --interval=30s --timeout=30s \
CMD curl --fail http://localhost:6052/version -A "HealthCheck" || exit 1 CMD curl --fail http://localhost:6052/version -A "HealthCheck" || exit 1
COPY docker/docker_entrypoint.sh /entrypoint.sh COPY docker/docker_entrypoint.sh /entrypoint.sh
# The directory the user should mount their configuration files to
VOLUME /config VOLUME /config
WORKDIR /config WORKDIR /config
# Set entrypoint to esphome (via a script) so that the user doesn't have to type 'esphome'
# in every docker command twice
ENTRYPOINT ["/entrypoint.sh"] ENTRYPOINT ["/entrypoint.sh"]
# When no arguments given, start the dashboard in the workdir
CMD ["dashboard", "/config"] CMD ["dashboard", "/config"]
FROM base AS base-hassio
# TODO: Install s6-overlay
# ======================= hassio-type image =======================
FROM base AS hassio
RUN \ RUN \
apt-get update \ set -x \
# Use pinned versions so that we get updates with build caching && apt-get update \
&& apt-get install -y --no-install-recommends \ && apt-get install -y --no-install-recommends \
nginx-light=1.22.1-9 \ nginx-light=1.22.1-9 \
&& rm -rf \ && rm -rf \
/tmp/* \ /tmp/* \
/var/{cache,log}/* \ /var/{cache,log}/* \
/var/lib/apt/lists/* /var/lib/apt/lists/* \
/usr/src/*
ARG BUILD_VERSION=dev ARG BUILD_VERSION=dev
# Copy root filesystem
COPY docker/ha-addon-rootfs/ / COPY docker/ha-addon-rootfs/ /
# Copy esphome and install
COPY . /esphome
RUN if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
export PIP_EXTRA_INDEX_URL="https://www.piwheels.org/simple"; \
fi; \
pip3 install \
--break-system-packages --no-cache-dir -e /esphome
# Labels
LABEL \ LABEL \
io.hass.name="ESPHome" \ io.hass.name="ESPHome" \
io.hass.description="Manage and program ESP8266/ESP32 microcontrollers through YAML configuration files" \ io.hass.description="Manage and program microcontrollers through YAML configuration files" \
io.hass.type="addon" \ io.hass.type="addon" \
io.hass.version="${BUILD_VERSION}" io.hass.version="${BUILD_VERSION}"
# io.hass.arch is inherited from addon-debian-base
FROM base-${BUILD_TYPE} AS final
COPY . /esphome
RUN uv pip install --no-cache-dir -e /esphome
# ======================= lint-type image =======================
FROM base AS lint FROM base AS lint
ENV \ # TODO:
PLATFORMIO_CORE_DIR=/esphome/.temp/platformio
RUN \
apt-get update \
# Use pinned versions so that we get updates with build caching
&& apt-get install -y --no-install-recommends \
clang-format-13=1:13.0.1-11+b2 \
clang-tidy-14=1:14.0.6-12 \
patch=2.7.6-7 \
software-properties-common=0.99.30-4.1~deb12u1 \
nano=7.2-1+deb12u1 \
build-essential=12.9 \
python3-dev=3.11.2-1+b1 \
&& rm -rf \
/tmp/* \
/var/{cache,log}/* \
/var/lib/apt/lists/*
COPY requirements_test.txt /
RUN if [ "$TARGETARCH$TARGETVARIANT" = "armv7" ]; then \
export PIP_EXTRA_INDEX_URL="https://www.piwheels.org/simple"; \
fi; \
pip3 install \
--break-system-packages --no-cache-dir -r /requirements_test.txt
VOLUME ["/esphome"]
WORKDIR /esphome

View File

@ -1,13 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from dataclasses import dataclass
import subprocess
import argparse import argparse
from platform import machine from dataclasses import dataclass
import shlex
import re import re
import shlex
import subprocess
import sys import sys
CHANNEL_DEV = "dev" CHANNEL_DEV = "dev"
CHANNEL_BETA = "beta" CHANNEL_BETA = "beta"
CHANNEL_RELEASE = "release" CHANNEL_RELEASE = "release"
@ -57,7 +55,7 @@ manifest_parser = subparsers.add_parser(
class DockerParams: class DockerParams:
build_to: str build_to: str
manifest_to: str manifest_to: str
baseimgtype: str build_type: str
platform: str platform: str
target: str target: str
@ -69,7 +67,7 @@ class DockerParams:
TYPE_LINT: "esphome/esphome-lint", TYPE_LINT: "esphome/esphome-lint",
}[build_type] }[build_type]
build_to = f"{prefix}-{arch}" build_to = f"{prefix}-{arch}"
baseimgtype = { _build_type = {
TYPE_DOCKER: "docker", TYPE_DOCKER: "docker",
TYPE_HA_ADDON: "hassio", TYPE_HA_ADDON: "hassio",
TYPE_LINT: "docker", TYPE_LINT: "docker",
@ -80,14 +78,14 @@ class DockerParams:
ARCH_AARCH64: "linux/arm64", ARCH_AARCH64: "linux/arm64",
}[arch] }[arch]
target = { target = {
TYPE_DOCKER: "docker", TYPE_DOCKER: "final",
TYPE_HA_ADDON: "hassio", TYPE_HA_ADDON: "final",
TYPE_LINT: "lint", TYPE_LINT: "lint",
}[build_type] }[build_type]
return cls( return cls(
build_to=build_to, build_to=build_to,
manifest_to=prefix, manifest_to=prefix,
baseimgtype=baseimgtype, build_type=_build_type,
platform=platform, platform=platform,
target=target, target=target,
) )
@ -149,7 +147,7 @@ def main():
"buildx", "buildx",
"build", "build",
"--build-arg", "--build-arg",
f"BASEIMGTYPE={params.baseimgtype}", f"BUILD_TYPE={params.build_type}",
"--build-arg", "--build-arg",
f"BUILD_VERSION={args.tag}", f"BUILD_VERSION={args.tag}",
"--cache-from", "--cache-from",

View File

@ -9,7 +9,7 @@ tornado==6.4
tzlocal==5.2 # from time tzlocal==5.2 # from time
tzdata>=2021.1 # from time tzdata>=2021.1 # from time
pyserial==3.5 pyserial==3.5
platformio==6.1.15 # When updating platformio, also update Dockerfile platformio==6.1.15
esptool==4.7.0 esptool==4.7.0
click==8.1.7 click==8.1.7
esphome-dashboard==20240620.0 esphome-dashboard==20240620.0
@ -17,6 +17,9 @@ aioesphomeapi==24.6.2
zeroconf==0.132.2 zeroconf==0.132.2
python-magic==0.4.27 python-magic==0.4.27
ruamel.yaml==0.18.6 # dashboard_import ruamel.yaml==0.18.6 # dashboard_import
pillow==10.2.0
cairosvg==2.7.1
# esp-idf requires this, but doesn't bundle it by default # esp-idf requires this, but doesn't bundle it by default
# https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24 # https://github.com/espressif/esp-idf/blob/220590d599e134d7a5e7f1e683cc4550349ffbf8/requirements.txt#L24

View File

@ -1,2 +0,0 @@
pillow==10.2.0
cairosvg==2.7.1