Skip to content

Commit

Permalink
nvim: change base image from fedora to alpine
Browse files Browse the repository at this point in the history
feat: add slim / userbase image without neovim (25MB)
  - unvendor nvim-treesitter; install from alpine repos
  - remove redundant nvim plugin build step
  - compile hub

image size is now ~280 MB instead of ~600MB

ci: fix publish
  • Loading branch information
legobeat committed Jul 5, 2024
1 parent 56ec847 commit c129e76
Show file tree
Hide file tree
Showing 11 changed files with 471 additions and 148 deletions.
16 changes: 15 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
localhost/l7/node:latest
localhost/l7/node:20-bookworm
- name: nvim
file: Containerfile
file: Containerfile.nvim
context: .
tags: localhost/l7/nvim:latest
steps:
Expand Down Expand Up @@ -80,6 +80,20 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Build and load base image
if: ${{ matrix.name == 'nvim' || matrix.name == 'node' }}
uses: docker/build-push-action@v6
with:
context: .
file: Containerfile.slim
tags: localhost/l7/alpine:3.20
build-args: |
ALPINE_VERSION=3.20
load: true
push: true
cache-from: type=gha
cache-to: type=gha,mode=max

- name: Build and load ${{ matrix.name }} image
uses: docker/build-push-action@v6
with:
Expand Down
76 changes: 74 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,80 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

publish-image:
publish-image-base:
needs: publish-image-pre
runs-on: ubuntu-latest
services:
registry:
image: registry:2
ports:
- 80:5000
permissions:
contents: read
packages: write
attestations: write
id-token: write
strategy:
matrix:
include:
- name: slim
file: Containerfile.slim
context: .
tags: |
localhost/l7/alpine:3.20
ghcr.io/legobeat/l7-devenv/alpine:latest
ghcr.io/legobeat/l7-devenv/alpine:3.20
ghcr.io/legobeat/l7-devenv/alpine:${{ github.ref_name }}
ghcr.io/legobeat/l7-devenv/alpine:3.20-${{ github.ref_name }}
build-args: |
CADDY_IMAGE=ghcr.io/legobeat/l7-devenv/caddy:${{ github.ref_name }}
# exact duplicate of publish steps for other images. yaml anchors not supported in gha
steps:
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Log in to the Container registry
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 #v3.2.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 #v5.5.1
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.name }}

- name: allow cleartext http to localhost container registry
run: |
echo '{"insecure-registries" : [ "localhost" ]}' | sudo tee /etc/docker/daemon.json
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: network=host

- uses: actions/checkout@v4
with:
submodules: true

- name: Build and publish ${{ matrix.name }} image
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: '${{ matrix.file }}'
build-args: ${{ matrix.build-args }}
tags: ${{ matrix.tags }}
labels: ${{ steps.meta.outputs.labels }}
load: true
push: true
cache-from: type=gha
cache-to: type=gha,mode=max

publish-image:
needs: publish-image-base
runs-on: ubuntu-latest
services:
registry:
image: registry:2
Expand Down Expand Up @@ -141,12 +212,13 @@ jobs:
build-args: |
CADDY_IMAGE=ghcr.io/legobeat/l7-devenv/caddy:${{ github.ref_name }}
- name: nvim
file: Containerfile
file: Containerfile.nvim
context: .
tags: |
ghcr.io/legobeat/l7-devenv/nvim:latest
ghcr.io/legobeat/l7-devenv/nvim:${{ github.ref_name }}
build-args: |
BASE_IMAGE=ghcr.io/legobeat/l7-devenv/alpine:${{ github.ref_name }}
CADDY_IMAGE=ghcr.io/legobeat/l7-devenv/caddy:${{ github.ref_name }}
steps:
- name: Set up QEMU
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
[submodule "contrib/l7-scripts"]
path = contrib/l7-scripts
url = https://github.com/legobeat/l7-scripts
[submodule "nvim/plugins/nvim-treesitter"]
path = contrib/nvim-plugins/nvim-treesitter
url = https://github.com/nvim-treesitter/nvim-treesitter.git
[submodule "nvim/plugins/nvim-lspconfig"]
path = contrib/nvim-plugins/nvim-lspconfig
url = https://github.com/neovim/nvim-lspconfig.git
Expand Down
125 changes: 23 additions & 102 deletions Containerfile
Original file line number Diff line number Diff line change
@@ -1,57 +1,22 @@
# syntax=docker/dockerfile:1.4-labs
ARG BASE_IMAGE=localhost/l7/alpine:3.20
ARG CADDY_IMAGE=localhost/l7/caddy:latest
FROM registry.fedoraproject.org/fedora-minimal:40 AS base
FROM alpine:3.20 AS base


# EXTRA_BASE_PKGS get installed in both build and runtime. Example of useful packages:
### golang LSP support
## ARG EXTRA_PKGS='go golang-x-tools-gopls'
ARG EXTRA_BASE_PKGS=''

RUN microdnf -y update \
&& microdnf -y install --setopt=install_weak_deps=False \
make automake patch \
curl wget jq yq moreutils tar \
git gnupg2 \
neovim python3-neovim \
RUN apk add --no-cache \
bash \
curl wget jq tar \
git \
neovim \
$EXTRA_BASE_PKGS \
&& ln -sf nvim /usr/bin/vim

##################################
##### NEOVIM PLUGINS BUILDER #####

FROM base AS nvim-builder

ARG EXTRA_BUILD_PKGS=''
# enable/disable treesitter language parsers. These are fetched remotely.
ARG TREESITTER_INSTALL='bash c dockerfile hcl javascript lua make markdown nix python ruby typescript vim vimdoc yaml'
ENV HOME=/tmp/1001-home

# TODO: not supported on podman ubuntu-22.03
# Using RUN --mount is more efficient than COPY for stuff only used during image build.
# RUN --mount=source=contrib/nvim-plugins,target=/etc/xdg/nvim/pack/build-l7ide/start,rw=true \
COPY contrib/nvim-plugins /etc/xdg/nvim/pack/build-l7ide/start
RUN \
microdnf install -y --setopt=install_weak_deps=False \
# lua-lunitx binutils \
lua \
gcc gcc-c++ cpp \
$EXTRA_BUILD_PKGS \
&& cd /etc/xdg/nvim/pack/build-l7ide/start \
# install TreeSitter parsers
&& nvim --headless \
-c 'packadd nvim-treesitter' \
-c 'packloadall' \
-c "TSEnable ${TREESITTER_INSTALL}" \
-c "TSUpdateSync ${TREESITTER_INSTALL}" \
-c "TSEnable ${TREESITTER_INSTALL}" \
-c q \
&& mkdir -p /out/plugins \
&& cd /out \
&& microdnf clean all \
&& cp -a /etc/xdg/nvim/pack/build-l7ide/start/* /out/plugins/


# this assumes we already have a locally built caddy image
# the image contains a pregenerated ca root cert for mitm, which we copy here
# TODO: provide a nicer way to manage the rootcert
Expand All @@ -60,95 +25,51 @@ FROM ${CADDY_IMAGE} AS fwdproxy
##### FINAL IMAGE #####
FROM base

# EXTRA_PKGS get installed in final image. examples of useful extra packages:
### golang LSP support
## ARG EXTRA_PKGS='go golang-x-tools-gopls'
### secrets injection
## ARG EXTRA_PKGS='age pass gopass'
### TUI file managers
## ARG EXTRA_PKGS='ranger vifm'
### open links in host browser
## ARG EXTRA_PKGS='xdg-open'
### yes, you can integrate with system clipboard
## ARG EXTRA_PKGS='xsel xclip wl-clipboard'
## ARG EXTRA_PKGS='terminus-fonts fontawesome-fonts-all gdouros-symbola-fonts'
### monitoring etc, probably more useful on host
## ARG EXTRA_PKGS='htop sysstat ncdu net-tools'
### wip / not working / notes
## ARG EXTRA_PKGS='tree-sitter-cli' # repo version errors right now? try again later

ARG EXTRA_PKGS='bat'
ARG EXTRA_PKGS="iproute2"

ARG HOME=/home/user
ENV HOME=${HOME}
ARG SHELL=/usr/bin/zsh
ARG SHELL=/bin/bash
ARG UID=1000
ARG GID=1000

WORKDIR ${HOME}

RUN microdnf -y install --setopt=install_weak_deps=False \
diffutils tree fzf ripgrep \
sshpass \
git-lfs hub gh tig \
libnotify \
ip openssl procps-ng psmisc \
man-db \
podman-remote containers-common \
# devenv-in-denvenv
gettext-envsubst mkpasswd \
screen \
w3m \
which \
zsh \
RUN apk add --no-cache \
openssl \
envsubst \
# build-deps
shadow \
${EXTRA_PKGS} \
&& ln -sf nvim /usr/bin/vim \

# create user entry or podman will mess up /etc/passwd entry
&& bash -c "groupadd -g ${GID} userz || true" \
&& bash -c "useradd -u ${UID} -g ${GID} -d /home/user -m user -s "${SHELL}" && chown -R ${UID}:${GID} /home/user || true" \
# https://github.com/gabyx/container-nesting/blob/7efbd79707e1be366bee462f6200443ca23bc077/src/podman/container/Containerfile#L46
&& mkdir -p /etc/containers .config/containers \
&& sed -e 's|^#mount_program|mount_program|g' \
-e '/additionalimage.*/a "/var/lib/shared",' \
-e 's|^mountopt[[:space:]]*=.*$|mountopt = "nodev,fsync=0"|g' \
/usr/share/containers/storage.conf \
> /etc/containers/storage.conf \
&& sed -e 's|^graphroot|#graphroot|g' \
-e 's|^runroot|#runroot|g' \
/etc/containers/storage.conf > .config/containers/storage.conf \
&& rpm --setcaps shadow-utils 2>/dev/null \
&& microdnf -y install podman-remote fuse-overlayfs openssh-clients --exclude container-selinux \
&& microdnf clean all

COPY --from=nvim-builder --chown=2:2 \
/out/plugins /etc/xdg/nvim/pack/l7ide/start
&& apk del shadow


COPY --chmod=755 --chown=root contrib/bin/* contrib/*/bin/* /usr/local/bin/
ARG NODE_BINS="npm7 npm9 npm10 pnpm9 yarn1 yarn3 yarn4 allow-scripts corepack glob lavamoat-ls mkdirp node-gyp node-which nopt npx pnpx resolve semver yarn-deduplicate"
RUN for bin in ${NODE_BINS}; do ln -s l7-run-node "/usr/local/bin/${bin}"; done

COPY skel/.config/containers/containers.conf /etc/containers/containers.conf
COPY --chown=${UID}:${GID} skel/ /home/user/

# default trust github.com known ssh key
COPY contrib/data/ssh_known_hosts /etc/ssh/ssh_known_hosts
# https://docs.fedoraproject.org/en-US/quick-docs/using-shared-system-certificates/

COPY --from=fwdproxy \
--chmod=444 \
/data/caddy/pki/authorities/local/root.crt \
/etc/pki/ca-trust/source/anchors/l7-fwd-proxy.crt
RUN update-ca-trust \
/usr/local/share/ca-certificates/l7-fwd-proxy.crt

RUN cat /usr/local/share/ca-certificates/l7-fwd-proxy.crt >> /etc/ssl/certs/ca-certificates.crt \
&& cat /home/user/.env >> /etc/profile \
# podman quirk: `COPY --from` messes up ownership so rechown needs to come last
&& chown -R ${UID}:${GID} \
/home/user \
# treesitter needs write to parsers dirs?
/etc/xdg/nvim/pack/l7ide/start/nvim-treesitter/parser{-info,} \
&& ln -s \
podman-remote /usr/bin/podman


/home/user

USER ${UID}:${GID}
WORKDIR /src
ENTRYPOINT ${SHELL}

Loading

0 comments on commit c129e76

Please sign in to comment.