Skip to content

Commit 2d4a243

Browse files
committed
readme: document slim base and fleet contracts
1 parent 7bc09a6 commit 2d4a243

1 file changed

Lines changed: 60 additions & 127 deletions

File tree

README.md

Lines changed: 60 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,34 @@
11
# Canis Base
22

3-
Two images for the DataCite Canis family of Rails services.
3+
Shared Docker images for DataCite Canis Rails services (Lupo, Levriero, Events, Volpino, Sashimi).
44

55
### Images
66

7-
| Image | Purpose | Recommended for |
8-
|------------------------------|----------------------------------------------|--------------------------|
9-
| `canis-base` | Slim shared foundation | All services |
10-
| `canis-base-tools` | `canis-base` + Percona Toolkit + AWS CLI + dockerize | Lupo and heavy services |
7+
| Image | Purpose | Recommended for |
8+
|-------|---------|-----------------|
9+
| `canis-base` | Slim shared foundation | Most services |
10+
| `canis-base-tools` | `canis-base` + Percona Toolkit + AWS CLI | Lupo (ops extras) |
1111

1212
### Philosophy
1313

14-
- Keep the core base as small as reasonably possible.
15-
- Put heavy operational tooling (Percona Toolkit, AWS CLI) into a separate image that builds on top of the base.
16-
- Most services are being merged into Lupo, so we only need two images for now.
17-
- Operational simplicity remains the top priority.
14+
- Keep the core base to the **intersection** of shared needs across Canis services.
15+
- Put Lupo-heavy operational tooling (Percona Toolkit, AWS CLI) in the tools image.
16+
- Service-specific packages and scripts stay in each app's Dockerfile.
17+
- Match existing fleet contracts (SSH, Passenger env, NTP, Shoryuken guards) so adoption is a thin Dockerfile change.
1818

19-
## Quick Start
19+
## Quick start
2020

21-
The release workflow will automatically build and push both images to **both Docker Hub (`datacite/...`) and GHCR (`ghcr.io/datacite/...`)** using `github.ref_name` (the tag, e.g. `v1.2.3`) + the commit hash.
22-
23-
### Build both images locally (for testing)
21+
### Build both images locally
2422

2523
```bash
26-
# 1. Build the slim core base
24+
# 1. Slim core base
2725
docker buildx build \
2826
--platform linux/amd64 \
2927
--tag canis-base:local \
3028
--load \
3129
-f Dockerfile .
3230

33-
# 2. Build the tools variant on top of the local base
31+
# 2. Tools variant on top of the local base
3432
docker buildx build \
3533
--platform linux/amd64 \
3634
--tag canis-base-tools:local \
@@ -41,149 +39,84 @@ docker buildx build \
4139

4240
### Usage in application Dockerfiles
4341

44-
**Lupo (and other heavy services):**
42+
**Lupo:**
4543

4644
```dockerfile
47-
FROM ghcr.io/datacite/canis-base-tools:v1.2.3
45+
FROM ghcr.io/datacite/canis-base-tools:1.2.3
4846
```
4947

50-
For maximum reproducibility you can also pin to the exact hash:
48+
**Other Canis services:**
5149

5250
```dockerfile
53-
FROM ghcr.io/datacite/canis-base-tools:7f3a2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f
51+
FROM ghcr.io/datacite/canis-base:1.2.3
5452
```
5553

56-
**Lighter services:**
57-
58-
```dockerfile
59-
FROM ghcr.io/datacite/canis-base:v1.2.3
60-
```
54+
Pin to a full commit SHA for maximum reproducibility if needed.
6155

6256
## What's in each image
6357

64-
**`canis-base`** (slim core)
65-
- `phusion/passenger-ruby40` base (Ubuntu 24.04)
66-
- Ruby 4.0 + rubygems 3.5.6 + bundler 2.6.9
67-
- Passenger + Nginx setup
68-
- Common native gem build dependencies (mysql2, nokogiri, etc.)
69-
- Basic operational tools (ntp, curl, git, jq, etc.)
70-
- Standard Phusion layout and permissions
71-
- Common `vendor/docker/` files baked in (see below)
72-
73-
**`canis-base-tools`** (adds on top of the base)
58+
**`canis-base`**
59+
- `phusion/passenger-ruby40` (Ubuntu 24.04)
60+
- Ruby 4.0.1 + rubygems 3.5.6 + bundler 2.6.9
61+
- Passenger + Nginx enabled; default site removed
62+
- Common packages: ntp, wget, ca-certificates, tzdata, shared-mime-info, nano, tmux
63+
- Common native gem build deps: build-essential, libxslt1-dev, libyaml-dev, zlib1g-dev, pkg-config
64+
- `app` in `docker_env` group
65+
- SSH enabled; `PUBLIC_KEY` installed for **root** at startup
66+
- Baked shared config/scripts (see below)
67+
- Guarded Shoryuken runit service
68+
69+
**`canis-base-tools`** (on top of base)
7470
- Percona Toolkit 3.7.1 + Perl DBI libraries
75-
- AWS CLI v2 (used by Lupo for Passenger → CloudWatch metrics)
76-
- dockerize
77-
78-
## Common `vendor/docker/` files (now in the base)
79-
80-
Previously, every app duplicated files in their own `vendor/docker/`. We have centralized the common ones here so they match the naming and structure used in other DataCite repos (lupo, levriero, volpino, etc.).
81-
82-
The following files are now provided by the base image (baked in during the base image build) from `vendor/docker/`:
71+
- AWS CLI v2 (e.g. Lupo Passenger → CloudWatch metrics)
8372

84-
- `vendor/docker/00_app_env.conf` -> `/etc/nginx/conf.d/00_app_env.conf` (common env passthrough; apps can override)
85-
- `vendor/docker/ntp.conf` -> `/etc/ntp.conf`
86-
- `vendor/docker/10_ssh.sh` -> `/etc/my_init.d/10_ssh.sh`
87-
- `vendor/docker/90_migrate.sh` -> `/etc/my_init.d/90_migrate.sh`
88-
- `vendor/docker/shoryuken.sh` -> `/etc/service/shoryuken/run`
73+
Not in either image (add in the app when needed): MySQL client headers, ImageMagick/graphics libs, Chrome, dockerize, migrate-on-boot scripts.
8974

90-
**How to customize:**
91-
- If your service needs a different version of any of these, simply `COPY` your own file from your app's `vendor/docker/` in your Dockerfile *after* the `FROM` line. It will override the baked-in version from the base.
92-
- Service-specific files (e.g. custom `webapp.conf` / `webapp.conf.template`, Lupo's `70_nginx_templates.sh`, Volpino's `70_precompile.sh`, Lupo's metrics script) should remain in your app's own `vendor/docker/`.
75+
## Baked `vendor/docker/` files
9376

94-
See `vendor/docker/` in this repo for the exact current versions of the shared files. This naming makes it easy to compare with the files in your app repo.
77+
| Source | Destination | Behavior |
78+
|--------|-------------|----------|
79+
| `00_app_env.conf` | `/etc/nginx/conf.d/00_app_env.conf` | `passenger_app_env development;` (overridable via `PASSENGER_APP_ENV`) |
80+
| `ntp.conf` | `/etc/ntp.conf` | Amazon NTP pool (fleet standard) |
81+
| `10_ssh.sh` | `/etc/my_init.d/10_ssh.sh` | `PUBLIC_KEY``/root/.ssh/authorized_keys` |
82+
| `shoryuken.sh` | `/etc/service/shoryuken/run` | Starts only if `AWS_REGION` is set and `DISABLE_QUEUE_WORKER` is unset |
9583

96-
## Tagging Strategy (Semantic Versioning)
84+
**Migrations are not in the base.** Apps that migrate on boot should keep their own `90_migrate.sh` and `COPY` it into `/etc/my_init.d/`.
9785

98-
All DataCite images follow semantic versioning.
86+
**Overrides:** `COPY` your own file after `FROM` to replace a baked path. Keep service-only files in the app (`webapp.conf`, metrics, nginx templates, precompile, etc.).
9987

100-
Releases are driven by git tags (e.g. `1.2.3`).
88+
## Runtime env conventions
10189

102-
The workflow uses `github.ref_name` (the tag name) for the semantic version and `github.sha` for the full commit hash.
90+
| Variable | Role |
91+
|----------|------|
92+
| `PUBLIC_KEY` | SSH public key for root |
93+
| `PASSENGER_APP_ENV` | Overrides Passenger app env (default development via conf) |
94+
| `AWS_REGION` | Required for Shoryuken to start |
95+
| `DISABLE_QUEUE_WORKER` | If set (any non-empty value), Shoryuken does not start |
96+
| `SERVER_ROLE` | Used by app-owned migrate scripts (not the base) |
10397

104-
For each release the following tags are pushed for both images:
98+
## Tagging
10599

106-
- `latest`
107-
- `1.2.3` (from `github.ref_name`)
108-
- `<full 40-character commit SHA>` (the hash)
109-
110-
Example production pins:
100+
Releases are driven by git tags. Tags pushed for both images typically include `latest`, the version tag, and the commit SHA. Prefer pinning apps to a version tag:
111101

112102
```dockerfile
113-
# Recommended (human readable + reproducible)
114-
FROM ghcr.io/datacite/canis-base-tools:1.2.3
115-
116-
# Maximum reproducibility (pin to the exact hash)
117-
FROM ghcr.io/datacite/canis-base-tools:7f3a2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0
103+
FROM ghcr.io/datacite/canis-base:1.2.3
118104
```
119105

120-
The `canis-base-tools` image is always built against the **exact same commit** of `canis-base` (via the build arg using the SHA). This guarantees that `canis-base-tools:1.2.3` was built on top of `canis-base:1.2.3` (same tree).
106+
`canis-base-tools` is built against the same commit of `canis-base` for a given release.
121107

122108
## Ruby version
123109

124-
Both images only support **Ruby 4.x**.
125-
126-
## Example Usage
127-
128-
### Lupo (or other heavy services)
129-
130-
```dockerfile
131-
# syntax=docker/dockerfile:1.7
132-
FROM ghcr.io/datacite/canis-base-tools:1.2.3
133-
134-
LABEL maintainer="support@datacite.org"
110+
Both images support **Ruby 4.x** only. Services still on Ruby 3 need to finish that upgrade before adopting this base (or use an interim approach).
135111

136-
ENV NGINX_ENVSUBST_OUTPUT_DIR=/etc/nginx/sites-enabled
112+
## Examples
137113

138-
# Lupo-specific files
139-
COPY vendor/docker/webapp.conf.template /etc/nginx/templates/webapp.conf.template
140-
COPY vendor/docker/70_nginx_templates.sh /etc/my_init.d/70_nginx_templates.sh
114+
See `examples/`:
141115

142-
RUN mkdir -p /etc/service/passenger-metrics
143-
COPY vendor/docker/passenger-metrics-run.sh /etc/service/passenger-metrics/run
144-
145-
COPY vendor/docker/00_app_env.conf /etc/nginx/conf.d/00_app_env.conf
146-
COPY vendor/docker/ntp.conf /etc/ntp.conf
147-
148-
RUN mkdir -p /etc/service/shoryuken
149-
COPY vendor/docker/shoryuken.sh /etc/service/shoryuken/run
150-
151-
COPY vendor/docker/10_ssh.sh /etc/my_init.d/10_ssh.sh
152-
COPY vendor/docker/90_migrate.sh /etc/my_init.d/90_migrate.sh
153-
154-
COPY . /home/app/webapp/
155-
RUN mkdir -p tmp/pids tmp/storage && \
156-
chown -R app:app /home/app/webapp && \
157-
chmod -R 755 /home/app/webapp
158-
159-
WORKDIR /home/app/webapp
160-
RUN mkdir -p vendor/bundle && \
161-
chown -R app:app . && \
162-
/sbin/setuser app bundle config set --local path 'vendor/bundle' && \
163-
/sbin/setuser app bundle install
164-
165-
EXPOSE 80
166-
```
167-
168-
### Lighter services
169-
170-
```dockerfile
171-
FROM ghcr.io/datacite/canis-base:1.0.1
172-
173-
# Add only what is unique to your service
174-
```
175-
176-
## Building Locally
177-
178-
```bash
179-
# Slim core base
180-
docker build -f Dockerfile -t canis-base:local .
181-
182-
# Tools variant
183-
docker build -f Dockerfile.tools -t canis-base-tools:local .
184-
```
116+
- `lupo.Dockerfile` — tools image + Lupo-only packages/scripts
117+
- `light-service.Dockerfile` — slim base + app-only bits
185118

186119
## Maintenance
187120

188-
- Rebuild `Dockerfile` when changing core packages or Ruby setup.
189-
- Rebuild `Dockerfile.tools` mainly when updating Percona Toolkit or AWS CLI.
121+
- Change `Dockerfile` for core packages, Ruby, or shared scripts.
122+
- Change `Dockerfile.tools` when updating Percona Toolkit or AWS CLI.

0 commit comments

Comments
 (0)