Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/powerman/alpine-runit-volume
Docker base image to run microservice with a data volume
https://github.com/powerman/alpine-runit-volume
alpine alpine-image base-image docker docker-image runit
Last synced: 12 days ago
JSON representation
Docker base image to run microservice with a data volume
- Host: GitHub
- URL: https://github.com/powerman/alpine-runit-volume
- Owner: powerman
- License: mit
- Created: 2017-09-10T05:27:56.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-12-12T21:51:45.000Z (about 1 month ago)
- Last Synced: 2025-01-02T21:53:04.140Z (13 days ago)
- Topics: alpine, alpine-image, base-image, docker, docker-image, runit
- Language: Shell
- Size: 80.1 KB
- Stars: 3
- Watchers: 3
- Forks: 0
- Open Issues: 34
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Docker base image to run microservice with a data volume
[![Release](https://img.shields.io/github/v/release/powerman/alpine-runit-volume.svg)](https://github.com/powerman/alpine-runit-volume/releases/latest)
[![Docker Automated Build](https://img.shields.io/docker/automated/powerman/alpine-runit-volume.svg)](https://hub.docker.com/r/powerman/alpine-runit-volume/tags)
[![CI](https://github.com/powerman/alpine-runit-volume/workflows/CI/badge.svg?event=push)](https://github.com/powerman/alpine-runit-volume/actions?query=workflow%3ACI%2FCD)**Table of Contents**
- [Overview](#overview)
- [Usage](#usage)
- [How it works](#how-it-works)
- [Alternatives](#alternatives)## Overview
This base docker image is designed to:
- Correctly run microservice with multiple processes:
- Clean up zombie processes.
- Graceful shutdown on `docker stop`.
- Easy to run extra services (syslog, cron, ssh, etc.).
- On essential service crash you can either restart it or stop
container.
- Handle persistent storage permissions and migrations:
- Microservice can run as non-root account "app".
- Account "app" is the owner of attached data volume directory.
- In case of using bind mount this account will have same UID/GID as
mounted directory - so you don't get files with unusual ownership in
this directory as result of running container.
- In case of using new volume it ownership will be changed to random
UID/GID (to better isolate container's data and processes). When
container will start next time using same volume it'll use same
UID/GID.
- Be small and secure, thanks to Alpine Linux.## Usage
```Dockerfile
FROM powerman/alpine-runit-volume:v0.4.0# [OPTIONAL] Change default directory with volume (/data):
ENV VOLUME_DIR=/home/app/var/data# [OPTIONAL] Move syslog log dir to default volume dir:
ENV SYSLOG_DIR=$VOLUME_DIR/syslog# [OPTIONAL] Use anonymous volume if real volume was not provided:
VOLUME $VOLUME_DIR# Add your files:
COPY . .# [OPTIONAL] Use cron service and setup /home/app/crontab for user "app":
RUN ln -s /etc/sv/dcron /etc/service/cron; \
install -m 0600 /home/app/crontab /etc/crontabs/app; \
echo app >> /etc/crontabs/cron.update# Either install your runit services (./init/ directory is just an example):
RUN ln -nsf "$PWD"/init/* /etc/service/
# or run your microservice as PID1 (without runit):
CMD ["my-pid-1-app"]
```These environment variables can be provided when starting container:
- `APP_UID`, `APP_GID`: numeric UID/GID to be used for "app" account and
to set ownership for root directory of attached volume.
- If `APP_UID=0` then both will be ignored.
- I recommend to use values between 1000 and 60000 to avoid conflicts
with existing accounts.
- `VOLUME_DIR`: directory with data volume (`/data` by default)
- `SYSLOG_DIR`: directory with syslog logs (`/var/log` by default)To run your command using "app" account: `chpst -u app …` (use in your
service's `./run` and `./finish` scripts).To gracefully shutdown container on essential service exit/crash add to
that service's `./finish` script (run as root): `sv down . /etc/sv/runsvdir`By default, your service's STDOUT/STDERR will be sent to docker logs
(using "stdout" log stream for both). To redirect your service's STDOUT to
syslog you can pipe output of your service to `logger` tool using this
`./log/run` script for your service:```sh
#!/bin/sh
sv start syslog >/dev/null 2>&1 || exit 1
exec chpst -u app logger
```Syslog service is enabled by default (unless you'll run your app as PID 1)
and save logs into `SYSLOG_DIR`. You can configure maximum log size and
amount of old rotated log files (10 x 1MB files by default) and other
features (duplicating selected log records to docker log, sending to
network syslog by UDP, etc.) using
[/var/log/config](http://smarden.org/runit/svlogd.8.html#sect6).If you enable `/etc/sv/dcron` service you can setup cron tasks using this
[crontab format](https://github.com/dubiousjim/dcron/blob/master/crontab.markdown).## How it works
When container starts `setup-volume` will be executed as `ENTRYPOINT` to:
- create user account "app"
- use UID/GID provided in environment variables `APP_UID`/`APP_GID`
if `APP_UID` is greater than 0
- use UID/GID of current owner of root directory of data volume,
if owner's UID is greater than 0
- generate random UID/GID between 10000 and 42767 (inclusive)
- if `/var/run/docker.sock` exists add user "app" to its group
- ensure root directory of data volume belongs to user "app"
- use path for data volume provided in environment variable `VOLUME_DIR`
or `/data` (if `VOLUME_DIR` is empty)
- run `CMD`If you'll replace `ENTRYPOINT` with your own script make sure it'll finish
with `exec setup-volume "$@"` if it doesn't use account "app" or call
`setup-volume true` before using account "app".## Alternatives
Main rationale to create this project instead of using existing
alternatives was to automate permission/ownership management of data
volume and provide much simpler implementation to run multiple processes.- https://github.com/just-containers/s6-overlay
- https://phusion.github.io/baseimage-docker/