Skip to content

Commit 6dc4d0f

Browse files
committed
Add canis base image (slim design)
Shared base + tools for Canis services, aligned with fleet contracts: passenger_app_env, root PUBLIC_KEY ssh, amazon ntp pool, guarded shoryuken, no migrate in base, slim packages, tools without dockerize.
1 parent 1709339 commit 6dc4d0f

13 files changed

Lines changed: 503 additions & 3 deletions

File tree

.dockerignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Ignore files that are not needed for building the base image
2+
.git
3+
.gitignore
4+
README.md
5+
*.md
6+
LICENSE
7+
examples/
8+
.github/
9+
Dockerfile*
10+
.dockerignore
11+
12+
# Common unnecessary files
13+
**/.DS_Store
14+
**/*~
15+
**/*.log
16+
tmp/
17+
log/
18+
vendor/bundle/ # if present in context
19+
node_modules/

.github/workflows/build.yml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
name: Build
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [main, master]
7+
workflow_dispatch:
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
packages: write
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Set up Docker Buildx
21+
uses: docker/setup-buildx-action@v3
22+
23+
- name: Login to GHCR
24+
uses: docker/login-action@v3
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Compute temporary tag (for PR verification only)
31+
id: temp
32+
run: |
33+
if [ "${{ github.event_name }}" = "pull_request" ]; then
34+
TEMP_TAG="pr-${{ github.event.pull_request.number }}-${{ github.sha }}"
35+
else
36+
TEMP_TAG="main-${{ github.sha }}"
37+
fi
38+
echo "temp_tag=$TEMP_TAG" >> $GITHUB_OUTPUT
39+
40+
# Build and push the slim base with a temporary tag.
41+
# This makes the base image available in GHCR so the tools step can pull it
42+
# via the build-arg (avoids local driver / local-tag visibility problems
43+
# and the cache-export limitation of the docker driver).
44+
- name: Build and push slim base (temporary tag)
45+
uses: docker/build-push-action@v6
46+
with:
47+
context: .
48+
file: Dockerfile
49+
platforms: linux/amd64
50+
push: true
51+
tags: |
52+
ghcr.io/datacite/canis-base:${{ steps.temp.outputs.temp_tag }}
53+
ghcr.io/datacite/canis-base:${{ github.sha }}
54+
cache-from: type=gha
55+
cache-to: type=gha,mode=max
56+
57+
# Build the tools variant. It will resolve BASE_IMAGE from GHCR using the temp tag.
58+
# We do not push the tools image here (verification only).
59+
- name: Build tools variant
60+
uses: docker/build-push-action@v6
61+
with:
62+
context: .
63+
file: Dockerfile.tools
64+
platforms: linux/amd64
65+
push: false
66+
build-args: |
67+
BASE_IMAGE=ghcr.io/datacite/canis-base:${{ steps.temp.outputs.temp_tag }}
68+
cache-from: type=gha
69+
cache-to: type=gha,mode=max
70+
71+
# Always attempt to delete the temporary base image after the build/checks
72+
# (whether the job passed or failed).
73+
- name: Cleanup temporary base image
74+
if: always()
75+
run: |
76+
TEMP_TAG="${{ steps.temp.outputs.temp_tag }}"
77+
echo "Attempting to delete temporary tag: $TEMP_TAG"
78+
# Find the version ID for this exact tag
79+
VERSION_ID=$(gh api \
80+
"/users/${{ github.repository_owner }}/packages/container/canis-base/versions" \
81+
--jq ".[] | select(.metadata.container.tags | index(\"$TEMP_TAG\")) | .id" 2>/dev/null || echo "")
82+
if [ -n "$VERSION_ID" ]; then
83+
echo "Deleting version ID $VERSION_ID"
84+
gh api -X DELETE \
85+
"/users/${{ github.repository_owner }}/packages/container/canis-base/versions/$VERSION_ID" \
86+
|| echo "Warning: delete may have failed or insufficient permissions (manual cleanup may be needed in the GitHub UI)"
87+
else
88+
echo "No matching version found for tag $TEMP_TAG"
89+
fi

.github/workflows/release.yml

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types: [published]
6+
workflow_dispatch:
7+
inputs:
8+
version:
9+
description: 'Semantic version'
10+
required: true
11+
12+
jobs:
13+
release:
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
packages: write
18+
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v3
25+
26+
- name: Login to GHCR
27+
uses: docker/login-action@v3
28+
with:
29+
registry: ghcr.io
30+
username: ${{ github.repository_owner }}
31+
password: ${{ secrets.GITHUB_TOKEN }}
32+
33+
- name: Determine version
34+
id: version
35+
run: |
36+
if [ "${{ github.event_name }}" = "release" ]; then
37+
VERSION="${{ github.ref_name }}"
38+
else
39+
VERSION="${{ github.event.inputs.version }}"
40+
fi
41+
echo "version=$VERSION" >> $GITHUB_OUTPUT
42+
echo "sha=${{ github.sha }}" >> $GITHUB_OUTPUT
43+
44+
- name: Cache Docker layers
45+
uses: actions/cache@v4
46+
with:
47+
path: /tmp/.buildx-cache
48+
key: ${{ runner.os }}-buildx-${{ github.sha }}
49+
restore-keys: |
50+
${{ runner.os }}-buildx-
51+
52+
# Build and push slim base with semantic + hash tags (GHCR only for now)
53+
- name: Build and push slim base
54+
uses: docker/build-push-action@v6
55+
with:
56+
context: .
57+
file: Dockerfile
58+
platforms: linux/amd64
59+
push: true
60+
tags: |
61+
ghcr.io/datacite/canis-base:latest
62+
ghcr.io/datacite/canis-base:${{ steps.version.outputs.version }}
63+
ghcr.io/datacite/canis-base:${{ steps.version.outputs.sha }}
64+
cache-from: type=local,src=/tmp/.buildx-cache
65+
cache-to: type=local,dest=/tmp/.buildx-cache
66+
67+
# Build and push tools variant on top of the exact base SHA (GHCR only for now)
68+
- name: Build and push tools variant
69+
uses: docker/build-push-action@v6
70+
with:
71+
context: .
72+
file: Dockerfile.tools
73+
platforms: linux/amd64
74+
push: true
75+
tags: |
76+
ghcr.io/datacite/canis-base-tools:latest
77+
ghcr.io/datacite/canis-base-tools:${{ steps.version.outputs.version }}
78+
ghcr.io/datacite/canis-base-tools:${{ steps.version.outputs.sha }}
79+
build-args: |
80+
BASE_IMAGE=ghcr.io/datacite/canis-base:${{ steps.version.outputs.sha }}
81+
cache-from: type=local,src=/tmp/.buildx-cache
82+
cache-to: type=local,dest=/tmp/.buildx-cache

Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# syntax=docker/dockerfile:1.7
2+
#
3+
# DataCite Canis Base Image (slim core)
4+
#
5+
# This is the minimal shared base used by all services.
6+
# Heavy operational tools live in Dockerfile.tools.
7+
8+
FROM phusion/passenger-ruby40:3.1.6
9+
10+
LABEL maintainer="support@datacite.org" \
11+
org.opencontainers.image.source="https://github.com/datacite/docker-canis-base" \
12+
org.opencontainers.image.description="DataCite Canis Base (slim core)"
13+
14+
ENV HOME=/home/app \
15+
LC_ALL=en_US.UTF-8 \
16+
LANG=en_US.UTF-8 \
17+
DEBIAN_FRONTEND=noninteractive
18+
19+
# ============================================================================
20+
# Core system packages + common native gem build dependencies
21+
# ============================================================================
22+
RUN apt-get update && apt-get upgrade -y -o Dpkg::Options::="--force-confold" && \
23+
apt-get install -y --no-install-recommends \
24+
ntp wget ca-certificates tzdata shared-mime-info \
25+
nano tmux \
26+
build-essential libxslt1-dev libyaml-dev zlib1g-dev pkg-config \
27+
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
28+
29+
# ============================================================================
30+
# User permissions
31+
# ============================================================================
32+
RUN usermod -a -G docker_env app
33+
34+
# ============================================================================
35+
# Ruby 4 + modern Bundler baseline
36+
# ============================================================================
37+
RUN bash -lc 'rvm --default use ruby-4.0.1 && gem install rubygems-update -v 3.5.6 && gem install bundler -v 2.6.9'
38+
39+
# ============================================================================
40+
# Standard Phusion layout
41+
# ============================================================================
42+
RUN rm -f /etc/service/nginx/down && \
43+
rm -f /etc/nginx/sites-enabled/default && \
44+
mkdir -p /etc/nginx/templates /etc/service/shoryuken /etc/my_init.d /etc/nginx/conf.d
45+
46+
# Copy common configuration and scripts from the base repo's vendor/docker/.
47+
# These match the layout used in other DataCite repos (lupo, levriero, etc.).
48+
# Apps can still override any of these by COPY-ing their own version later in their Dockerfile.
49+
COPY vendor/docker/ntp.conf /etc/ntp.conf
50+
COPY vendor/docker/00_app_env.conf /etc/nginx/conf.d/00_app_env.conf
51+
COPY vendor/docker/10_ssh.sh /etc/my_init.d/10_ssh.sh
52+
COPY vendor/docker/shoryuken.sh /etc/service/shoryuken/run
53+
54+
# Make sure init scripts are executable
55+
RUN chmod +x /etc/my_init.d/10_ssh.sh \
56+
/etc/service/shoryuken/run
57+
58+
# Enable SSH (fleet standard: root + PUBLIC_KEY via 10_ssh.sh)
59+
RUN rm -f /etc/service/sshd/down && \
60+
/etc/my_init.d/00_regen_ssh_host_keys.sh
61+
62+
WORKDIR /home/app/webapp
63+
CMD ["/sbin/my_init"]
64+
EXPOSE 80

Dockerfile.tools

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# syntax=docker/dockerfile:1.7
2+
#
3+
# DataCite Canis Tools Image
4+
#
5+
# Builds on top of the slim canis-base and adds heavy operational tooling.
6+
# Intended mainly for Lupo (Percona Toolkit + AWS CLI at runtime).
7+
8+
ARG BASE_IMAGE=ghcr.io/datacite/canis-base:latest
9+
FROM ${BASE_IMAGE}
10+
11+
LABEL maintainer="support@datacite.org" \
12+
org.opencontainers.image.source="https://github.com/datacite/docker-canis-base" \
13+
org.opencontainers.image.description="DataCite Canis Base + Tools (Percona + AWS CLI)"
14+
15+
# ============================================================================
16+
# Percona Toolkit 3.7.1 + Perl DBI libraries
17+
# ============================================================================
18+
RUN apt-get update && \
19+
apt-get install -y --no-install-recommends \
20+
libdbd-mysql-perl libdbi-perl libterm-readkey-perl libio-socket-ssl-perl \
21+
unzip && \
22+
wget -q https://downloads.percona.com/downloads/percona-toolkit/3.7.1/binary/debian/noble/x86_64/percona-toolkit_3.7.1-3.noble_amd64.deb -O /tmp/percona-toolkit.deb && \
23+
dpkg -i /tmp/percona-toolkit.deb || apt-get install -y -f --no-install-recommends && \
24+
rm -f /tmp/percona-toolkit.deb && \
25+
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
26+
27+
# ============================================================================
28+
# AWS CLI v2
29+
# ============================================================================
30+
RUN wget -q https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -O /tmp/awscliv2.zip && \
31+
unzip -q /tmp/awscliv2.zip -d /tmp && \
32+
/tmp/aws/install && \
33+
rm -rf /tmp/awscliv2.zip /tmp/aws
34+
35+
WORKDIR /home/app/webapp

0 commit comments

Comments
 (0)