{"id":13587739,"url":"https://github.com/osixia/container-baseimage","last_synced_at":"2026-04-20T23:04:42.778Z","repository":{"id":49958188,"uuid":"39132771","full_name":"osixia/container-baseimage","owner":"osixia","description":"A container base image to build reliable single or multiprocess images quickly 🐳✨🌴","archived":false,"fork":false,"pushed_at":"2024-04-25T19:19:51.000Z","size":29660,"stargazers_count":129,"open_issues_count":15,"forks_count":111,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-04-25T20:32:32.685Z","etag":null,"topics":["alpine","baseimage-docker","container-image","debian","docker","docker-image","dockerfile","ubuntu"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/osixia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-15T11:17:59.000Z","updated_at":"2024-08-01T16:33:45.150Z","dependencies_parsed_at":"2024-01-26T21:48:15.968Z","dependency_job_id":"1294014e-7d63-4984-876b-5dbae3de6d42","html_url":"https://github.com/osixia/container-baseimage","commit_stats":null,"previous_names":["osixia/container-baseimage"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osixia%2Fcontainer-baseimage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osixia%2Fcontainer-baseimage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osixia%2Fcontainer-baseimage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osixia%2Fcontainer-baseimage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osixia","download_url":"https://codeload.github.com/osixia/container-baseimage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248036064,"owners_count":21037092,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alpine","baseimage-docker","container-image","debian","docker","docker-image","dockerfile","ubuntu"],"created_at":"2024-08-01T15:06:20.486Z","updated_at":"2026-04-20T23:04:42.760Z","avatar_url":"https://github.com/osixia.png","language":"Shell","funding_links":[],"categories":["Shell"],"sub_categories":[],"readme":"# Deprecation Notice for Version 1\nAfter many years of v1 being used in production by so many people (thank you 🙏), it’s time to move forward.\n\nThe v1 branch is now officially deprecated and will no longer receive updates or fixes.\n\nIf currently using v1, please consider starting the migration process and take a look at v2 here:\n👉 https://github.com/osixia/container-baseimage/tree/develop\n\nVersion 2 introduces a cleaner foundation and is a complete rewrite in Go, providing improved performance, reliability, and long-term maintainability.\n\nFeedback, testing, ideas, and contributions are always welcome.\nThank you for being part of the community ❤️\n\n\n# osixia/light-baseimage\n\n[![Docker Pulls](https://img.shields.io/docker/pulls/osixia/light-baseimage.svg)][hub]\n[![Docker Stars](https://img.shields.io/docker/stars/osixia/light-baseimage.svg)][hub]\n[![](https://images.microbadger.com/badges/image/osixia/light-baseimage.svg)](http://microbadger.com/images/osixia/light-baseimage \"Get your own image badge on microbadger.com\")\n\n[hub]: https://hub.docker.com/r/osixia/light-baseimage/\n\nLatest release: 1.3.3 [Changelog](CHANGELOG.md)\n | [Docker Hub](https://hub.docker.com/r/osixia/light-baseimage/) \n\nA **Debian 10 (Buster)** based docker image to build reliable image quickly. This image provide a simple opinionated solution to build multiple or single process image with minimum of layers and an optimized build.\n\nThe aims of this image is to be used as a base for your own Docker images. It's base on the awesome work of: [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker)\n\nOther base distribution are available:\n- [Alpine](https://github.com/osixia/docker-light-baseimage/tree/alpine) | [Docker Hub](https://hub.docker.com/r/osixia/alpine-light-baseimage/) | [![](https://images.microbadger.com/badges/image/osixia/alpine-light-baseimage.svg)](http://microbadger.com/images/osixia/alpine-light-baseimage \"Get your own image badge on microbadger.com\")\n\nTable of Contents\n- [osixia/light-baseimage](#osixialight-baseimage)\n  - [Contributing](#contributing)\n  - [Overview](#overview)\n  - [Quick Start](#quick-start)\n    - [Image directories structure](#image-directories-structure)\n    - [Service directory structure](#service-directory-structure)\n    - [Create a single process image](#create-a-single-process-image)\n      - [Overview](#overview-1)\n      - [Dockerfile](#dockerfile)\n      - [Service files](#service-files)\n        - [install.sh](#installsh)\n        - [startup.sh](#startupsh)\n        - [process.sh](#processsh)\n      - [Environment files](#environment-files)\n        - [default.yaml](#defaultyaml)\n        - [default.startup.yaml](#defaultstartupyaml)\n      - [Build and test](#build-and-test)\n        - [Overriding default environment files at run time:](#overriding-default-environment-files-at-run-time)\n    - [Create a multiple process image](#create-a-multiple-process-image)\n      - [Overview](#overview-2)\n      - [Dockerfile](#dockerfile-1)\n      - [Service files](#service-files-1)\n        - [install.sh](#installsh)\n        - [process.sh](#processsh-1)\n      - [Build and test](#build-and-test-1)\n  - [Images Based On Light-Baseimage](#images-based-on-light-baseimage)\n  - [Image Assets](#image-assets)\n    - [Tools](#tools)\n    - [Services available](#services-available)\n  - [Advanced User Guide](#advanced-user-guide)\n    - [Service available](#service-available)\n    - [Fix docker mounted file problems](#fix-docker-mounted-file-problems)\n    - [Distribution packages documentation and locales](#distribution-packages-documentation-and-locales)\n    - [Mastering image tools](#mastering-image-tools)\n      - [run](#run)\n        - [Run command line options](#run-command-line-options)\n        - [Run directory setup](#run-directory-setup)\n        - [Startup files environment setup](#startup-files-environment-setup)\n        - [Startup files execution](#startup-files-execution)\n        - [Process execution](#process-execution)\n          - [Single process image](#single-process-image)\n          - [Multiple process image](#multiple-process-image)\n          - [No process image](#no-process-image)\n        - [Extra environment variables](#extra-environment-variables)\n      - [log-helper](#log-helper)\n      - [complex-bash-env](#complex-bash-env)\n    - [Tests](#tests)\n  - [Changelog](#changelog)\n\n## Contributing\n\nIf you find this image useful here's how you can help:\n\n- Send a pull request with your kickass new features and bug fixes\n- Help new users with [issues](https://github.com/osixia/docker-openldap/issues) they may encounter\n- Support the development of this image and star this repo!\n\n## Overview\n\nThis image takes all the advantages of [phusion/baseimage-docker](https://github.com/phusion/baseimage-docker) but makes programs optional which allow more lightweight images and single process images. It also define simple directory structure and files to quickly set how a program (here called service) is installed, setup and run.\n\nSo major features are:\n - Greats building tools to minimize the image number of layers and optimize image build.\n - Simple way to install services and multiple process image stacks (runit, cron, syslog-ng-core and logrotate) if needed.\n - Getting environment variables from **.yaml** and **.json** files.\n - Special environment files **.startup.yaml** and **.startup.json** deleted after image startup files first execution to keep the image setup secret.\n\n\n## Quick Start\n\n### Image directories structure\n\nThis image use four directories:\n\n- **/container/environment**: for environment files.\n- **/container/service**: for services to install, setup and run.\n- **/container/service-available**: for service that may be on demand downloaded, installed, setup and run.\n- **/container/tool**: for image tools.\n\nBy the way at run time another directory is created:\n- **/container/run**: To store container run environment, state, startup files and process to run based on files in  /container/environment and /container/service directories.\n\nBut this will be dealt with in the following section.\n\n### Service directory structure\n\nThis section define a service directory that can be added in /container/service or /container/service-available.\n\n- **my-service**: root directory\n- **my-service/install.sh**: install script (not mandatory).\n- **my-service/startup.sh**: startup script to setup the service when the container start (not mandatory).\n- **my-service/process.sh**: process to run (not mandatory).\n- **my-service/finish.sh**: finish script run when the process script exit (not mandatory).\n- **my-service/...** add whatever you need!\n\nOk that's pretty all to know to start building our first images!\n\n### Create a single process image\n\n#### Overview\nFor this example we are going to perform a basic nginx install.\n\nSee complete example in: [example/single-process-image](example/single-process-image)\n\nFirst we create the directory structure of the image:\n\n - **single-process-image**: root directory\n - **single-process-image/service**: directory to store the nginx service.\n - **single-process-image/environment**: environment files directory.\n - **single-process-image/Dockerfile**: the Dockerfile to build this image.\n\n**service** and **environment** directories name are arbitrary and can be changed but make sure to adapt their name everywhere and especially in the Dockerfile.\n\nLet's now create the nginx service directory:\n\n - **single-process-image/service/nginx**: service root directory\n - **single-process-image/service/nginx/install.sh**: service installation script.\n - **single-process-image/service/nginx/startup.sh**:  startup script to setup the service when the container start.\n - **single-process-image/service/nginx/process.sh**: process to run.\n\n\n#### Dockerfile\n\nIn the Dockerfile we are going to:\n  - Download nginx from apt-get.\n  - Add the service directory to the image.\n  - Install service and clean up.\n  - Add the environment directory to the image.\n  - Define ports exposed and volumes if needed.\n\n\n        # Use osixia/light-baseimage\n        # https://github.com/osixia/docker-light-baseimage\n        FROM osixia/light-baseimage:1.3.3\n\n        # Download nginx from apt-get and clean apt-get files\n        RUN apt-get -y update \\\n            \u0026\u0026 LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \\\n               nginx \\\n            \u0026\u0026 apt-get clean \\\n            \u0026\u0026 rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n\n        # Add service directory to /container/service\n        ADD service /container/service\n\n        # Use baseimage install-service script\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/install-service\n        RUN /container/tool/install-service\n\n        # Add default env directory\n        ADD environment /container/environment/99-default\n\n        # Set /var/www/ in a data volume\n        VOLUME /var/www/\n\n        # Expose default http and https ports\n        EXPOSE 80 443\n\n\nThe Dockerfile contains directives to download nginx from apt-get but all the initial setup will take place in install.sh file (called by /container/tool/install-service tool) for a better build experience. The time consuming download task is decoupled from the initial setup to make great use of docker build cache. If install.sh file is changed the builder won't have to download again nginx, and will just run install scripts.\n\n#### Service files\n\n##### install.sh\n\nThis file must only contain directives for the service initial setup. Files download and apt-get command takes place in the Dockerfile for a better image building experience (see [Dockerfile](#dockerfile)).\n\nIn this example, for the initial setup we just delete the default nginx debian index file and create a custom index.html:\n\n    #!/bin/bash -e\n    # this script is run during the image build\n\n    rm -rf /var/www/html/index.nginx-debian.html\n    echo \"Hi!\" \u003e /var/www/html/index.html\n\nMake sure install.sh can be executed (chmod +x install.sh).\n\nNote: The install.sh script is run during the docker build so run time environment variables can't be used to customize the setup. This is done in the startup.sh file.\n\n\n##### startup.sh\n\nThis file is used to make process.sh ready to be run and customize the service setup based on run time environment.\n\nFor example at run time we would like to introduce ourselves so we will use an environment variable WHO_AM_I set by command line with --env. So we add WHO_AM_I value to index.html file but we want to do that only on the first container start because on restart the index.html file will already contains our name:\n\n    #!/bin/bash -e\n    FIRST_START_DONE=\"${CONTAINER_STATE_DIR}/nginx-first-start-done\"\n\n    # container first start\n    if [ ! -e \"$FIRST_START_DONE\" ]; then\n      echo \"I'm ${WHO_AM_I}.\"  \u003e\u003e /var/www/html/index.html\n      touch $FIRST_START_DONE\n    fi\n\n    exit 0\n\nMake sure startup.sh can be executed (chmod +x startup.sh).\n\nAs you can see we use CONTAINER_STATE_DIR variable, it contains the directory where container state is saved, this variable is automatically set by run tool. Refer to the [Advanced User Guide](#extra-environment-variables) for more information.\n\n##### process.sh\n\nThis file define the command to run:\n\n    #!/bin/bash -e\n    exec /usr/sbin/nginx -g \"daemon off;\"\n\nMake sure process.sh can be executed (chmod +x process.sh).\n\n*Caution: The command executed must start a foreground process otherwise the container will immediately stops.*\n\nThat why we run nginx with `-g \"daemon off;\"`\n\nThat's it we have a single process image that run nginx!\nWe could already build and test this image but two more minutes to take advantage of environment files!\n\n#### Environment files\n\nLet's create two files:\n - single-process-image/environment/default.yaml\n - single-process-image/environment/default.startup.yaml\n\nFile name *default*.yaml and *default*.startup.yaml can be changed as you want. Also in this example we are going to use yaml files but json files works too.\n\n##### default.yaml\ndefault.yaml file define variables that can be used at any time in the container environment:\n\n    WHO_AM_I: We are Anonymous. We are Legion. We do not forgive. We do not forget. Expect us.\n\n##### default.startup.yaml\ndefault.startup.yaml define variables that are only available during the container **first start** in **startup files**.\n\\*.startup.yaml are deleted right after startup files are processed for the first time,\nthen all variables they contains will not be available in the container environment.\n\nThis helps to keep the container configuration secret. If you don't care all environment variables can be defined in **default.yaml** and everything will work fine.\n\nBut for this tutorial we will add a variable to this file:\n\n    FIRST_START_SETUP_ONLY_SECRET: The database password is KawaaahBounga\n\nAnd try to get its value in **startup.sh** script:\n\n    #!/bin/bash -e\n    FIRST_START_DONE=\"${CONTAINER_STATE_DIR}/nginx-first-start-done\"\n\n    # container first start\n    if [ ! -e \"$FIRST_START_DONE\" ]; then\n      echo ${WHO_AM_I}  \u003e\u003e /var/www/html/index.html\n      touch $FIRST_START_DONE\n    fi\n\n    echo \"The secret is: $FIRST_START_SETUP_ONLY_SECRET\"\n\n    exit 0\n\nAnd in **process.sh** script:\n\n    #!/bin/bash -e\n    echo \"The secret is: $FIRST_START_SETUP_ONLY_SECRET\"\n    exec /usr/sbin/nginx -g \"daemon off;\"\n\nOk it's time for the show!\n\n#### Build and test\n\nBuild the image:\n\n\tdocker build -t example/single-process --rm .\n\nStart a new container:\n\n    docker run -p 8080:80 example/single-process\n\nInspect the output and you should see that the secret is present in startup script:\n\u003e \\*\\*\\* Running /container/run/startup/nginx...\n\n\u003e The secret is: The database password is Baw0unga!\n\nAnd the secret is not defined in the process:\n\u003e \\*\\*\\* Remove file /container/environment/99-default/default.startup.yaml [...]\n\n\u003e \\*\\*\\* Running /container/run/process/nginx/run...\n\n\u003e The secret is:\n\nYes in this case it's not really useful to have a secret variable like this, but a concrete example can be found in [osixia/openldap](https://github.com/osixia/docker-openldap) image.\nThe admin password is available in clear text during the container first start to create a new ldap database where it is saved encrypted. After that the admin password is not available in clear text in the container environment.\n\nOk let's check our name now, go to [http://localhost:8080/](http://localhost:8080/)\n\nYou should see:\n\u003e Hi! We are Anonymous. We are Legion. We do not forgive. We do not forget. Expect us.\n\nAnd finally, let's say who we really are, stop the previous container (ctrl+c or ctrl+d) and start a new one:\n\n    docker run --env WHO_AM_I=\"I'm Jon Snow, what?! i'm dead?\" \\\n    -p 8080:80 example/single-process\n\nRefresh [http://localhost:8080/](http://localhost:8080/) and you should see:\n\u003e Hi! I'm Jon Snow, what?! i'm dead?\n\n\n##### Overriding default environment files at run time:\nLet's create two new environment files:\n  - single-process-image/test-custom-env/env.yaml\n  - single-process-image/test-custom-env/env.startup.yaml\n\nenv.yaml:\n\n    WHO_AM_I: I'm bobby.\n\nenv.startup.yaml:\n\n    FIRST_START_SETUP_ONLY_SECRET: The database password is KawaaahB0unga!!!\n\nAnd we mount them at run time:\n\n    docker run --volume $PWD/test-custom-env:/container/environment/01-custom \\\n    -p 8080:80 example/single-process\n\nTake care to link your environment files folder to `/container/environment/XX-somedir` (with XX \u003c 99 so they will be processed before default environment files) and not  directly to `/container/environment` because this directory contains predefined baseimage environment files to fix container environment (INITRD, LANG, LANGUAGE and LC_CTYPE).\n\nIn the output:\n\u003e \\*\\*\\* Running /container/run/startup/nginx...\n\n\u003e The secret is: The database password is KawaaahB0unga!!!\n\nRefresh [http://localhost:8080/](http://localhost:8080/) and you should see:\n\u003e Hi! I'm bobby.\n\n### Create a multiple process image\n\n#### Overview\n\nThis example takes back the single process image example and add php7.0-fpm to run php scripts.\n\nSee complete example in: [example/multiple-process-image](example/multiple-process-image)\n\nNote: it would have been  ♪ ~~harder~~, faster, better, stronger ♪ to extends the previous image but to make things easier we just copied files.\n\nSo here the image directory structure:\n\n - **multiple-process-image**: root directory\n - **multiple-process-image/service**: directory to store the nginx and php7.0-fpm service.\n - **multiple-process-image/environment**: environment files directory.\n - **multiple-process-image/Dockerfile**: the Dockerfile to build this image.\n\n**service** and **environment** directories name are arbitrary and can be changed but make sure to adapt their name in the Dockerfile.\n\nLet's now create the nginx and php directories:\n\n - **multiple-process-image/service/nginx**: nginx root directory\n - **multiple-process-image/service/nginx/install.sh**: service installation script.\n - **multiple-process-image/service/nginx/startup.sh**:  startup script to setup the service when the container start.\n - **multiple-process-image/service/nginx/process.sh**: process to run.\n\n - **multiple-process-image/service/php**: php root directory\n - **multiple-process-image/service/php/install.sh**: service installation script.\n - **multiple-process-image/service/php/process.sh**: process to run.\n - **multiple-process-image/service/php/config/default**: default nginx server config with\n\n#### Dockerfile\n\nIn the Dockerfile we are going to:\n  - Add the multiple process stack\n  - Download nginx and php7.0-fpm from apt-get.\n  - Add the service directory to the image.\n  - Install service and clean up.\n  - Add the environment directory to the image.\n  - Define ports exposed and volumes if needed.\n\n\n        # Use osixia/light-baseimage\n        # https://github.com/osixia/docker-light-baseimage\n        FROM osixia/light-baseimage:1.3.3\n\n        # Install multiple process stack, nginx and php7.0-fpm and clean apt-get files\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/add-multiple-process-stack\n        RUN apt-get -y update \\\n            \u0026\u0026 /container/tool/add-multiple-process-stack \\\n            \u0026\u0026 LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \\\n                nginx \\\n                php7.0-fpm \\\n            \u0026\u0026 apt-get clean \\\n            \u0026\u0026 rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*\n\n        # Add service directory to /container/service\n        ADD service /container/service\n\n        # Use baseimage install-service script\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/install-service\n        RUN /container/tool/install-service\n\n        # Add default env directory\n        ADD environment /container/environment/99-default\n\n        # Set /var/www/ in a data volume\n        VOLUME /var/www/\n\n        # Expose default http and https ports\n        EXPOSE 80 443\n\n\nThe Dockerfile contains directives to download nginx and php7.0-fpm from apt-get but all the initial setup will take place in install.sh file (called by /container/tool/install-service tool) for a better build experience. The time consuming download task is decoupled from the initial setup to make great use of docker build cache. If an install.sh file is changed the builder will not have to download again nginx and php7.0-fpm add will just run install scripts.\n\nMaybe you already read that in the previous example ?Sorry.\n\n#### Service files\n\nPlease refer to [single process image](#create-a-single-process-image) for the nginx service files description. Here just php service files are described.\n\n##### install.sh\n\nThis file must only contains directives for the service initial setup. Files download and apt-get command takes place in the Dockerfile for a better image building experience (see [Dockerfile](#dockerfile-1) ).\n\nIn this example, for the initial setup we set some php default configuration, replace the default nginx server config and add phpinfo.php file:\n\n    #!/bin/bash -e\n    # this script is run during the image build\n\n    # config\n    sed -i -e \"s/expose_php = On/expose_php = Off/g\" /etc/php/7.0/fpm/php.ini\n    sed -i -e \"s/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g\" /etc/php/7.0/fpm/php.ini\n    sed -i -e \"s/;listen.owner = www-data/listen.owner = www-data/g\" /etc/php/7.0/fpm/php.ini\n    sed -i -e \"s/;listen.group = www-data/listen.group = www-data/g\" /etc/php/7.0/fpm/php.ini\n\n    # create php socket directory\n    mkdir -p /run/php\n\n    # replace default website with php service default website\n    cp -f /container/service/php/config/default /etc/nginx/sites-available/default\n\n    # create phpinfo.php\n    echo \"\u003c?php phpinfo(); \" \u003e /var/www/html/phpinfo.php\n\n\n\nMake sure install.sh can be executed (chmod +x install.sh).\n\n##### process.sh\n\nThis file define the command to run:\n\n    #!/bin/bash -e\n    exec /usr/sbin/php-fpm7.0 --nodaemonize\n\nMake sure process.sh can be executed (chmod +x process.sh).\n\n*Caution: The command executed must start a foreground process otherwise runit (use to supervise multiple process images) will  keep restarting php-fpm7.0.*\n\nThat why we run php  with `--nodaemonize\"`\n\n##### config/default\nnginx server configuration:\n\n    server {\n      listen 80 default_server;\n      listen [::]:80 default_server;\n\n      root /var/www/html;\n\n      # Add index.php to the list if you are using PHP\n      index index.html index.htm index.nginx-debian.html;\n\n      server_name _;\n\n      location / {\n        # First attempt to serve request as file, then\n        # as directory, then fall back to displaying a 404.\n        try_files $uri $uri/ =404;\n      }\n\n      location ~ \\.php$ {\n        fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n        # With php fpm:\n        fastcgi_pass unix:/run/php/php7.0-fpm.sock;\n        fastcgi_index index.php;\n        include fastcgi_params;\n        include fastcgi.conf;\n      }\n    }\n\nThat's it we have a multiple process image that run nginx and php!\n\n#### Build and test\n\n\nBuild the image:\n\n    docker build -t example/multiple-process --rm .\n\nStart a new container:\n\n    docker run -p 8080:80 example/multiple-process\n\nGo to [http://localhost:8080/phpinfo.php](http://localhost:8080/phpinfo.php)\n\n\u003e phpinfo should be printed\n\nSo we have a container with two process supervised by runit running in our container!\n\n\n## Images Based On Light-Baseimage\n\nSingle process images:\n- [osixia/openldap](https://github.com/osixia/docker-openldap)\n- [osixia/keepalived](https://github.com/osixia/docker-keepalived)\n- [osixia/tinc](https://github.com/osixia/docker-tinc)\n- [osixia/registry-ldap-auth](https://github.com/osixia/docker-registry-ldap-auth)\n- [osixia/cfssl-multirootca](https://github.com/osixia/docker-cfssl-multirootca)\n- [osixia/backup](https://github.com/osixia/docker-backup)\n- [osixia/backup-manager](https://github.com/osixia/docker-backup-manager)\n- [osixia/mmc-agent](https://github.com/osixia/docker-mmc-agent)\n\nMultiple process images:\n- [osixia/openldap-backup](https://github.com/osixia/docker-openldap-backup)\n- [osixia/mariadb](https://github.com/osixia/docker-mariadb)\n- [osixia/wordpress](https://github.com/osixia/docker-wordpress)\n- [osixia/roundcube](https://github.com/osixia/docker-roundcube)\n- [osixia/piwik](https://github.com/osixia/docker-piwik)\n- [osixia/phpMyAdmin](https://github.com/osixia/docker-phpMyAdmin)\n- [osixia/phpLDAPadmin](https://github.com/osixia/docker-phpLDAPadmin)\n- [osixia/keepalived-confd](https://github.com/osixia/docker-keepalived-confd)\n- [osixia/tinc-etcd](https://github.com/osixia/docker-tinc-etcd)\n- [osixia/postfix-gateway-confd](https://github.com/osixia/docker-postfix-gateway-confd)\n- [osixia/mmc-mail](https://github.com/osixia/docker-mmc-mail)\n- [osixia/mmc-web](https://github.com/osixia/docker-mmc-web)\n\nImage adding light-baseimage tools to an existing image\n- [osixia/gitlab](https://github.com/osixia/docker-gitlab)\n\nSend me a message to add your image in this list.\n\n## Image Assets\n\n### Tools\n\nAll container tools are available in `/container/tool` directory and are linked in `/sbin/` so they belong to the container PATH.\n\n\n| Filename        | Description |\n| ---------------- | ------------------- |\n| run | The run tool is defined as the image ENTRYPOINT (see [Dockerfile](image/Dockerfile)). It set environment and run  startup scripts and images process. More information in the [Advanced User Guide](#run). |\n| setuser | A tool for running a command as another user. Easier to use than su, has a smaller attack vector than sudo, and unlike chpst this tool sets $HOME correctly.|\n| log-helper | A simple bash tool to print message base on the log level. |\n|  add-service-available | A tool to download and add services in service-available directory to the regular service directory. |\n| add-multiple-process-stack | A tool to add the multiple process stack: runit, cron syslog-ng-core and logrotate. |\n| install-service | A tool that execute /container/service/install.sh and /container/service/\\*/install.sh scripts. |\n|  complex-bash-env | A tool to iterate trough complex bash environment variables created by the run tool when a table or a list was set in environment files or in environment command line argument. |\n\n### Services available\n\n| Name        | Description |\n| ---------------- | ------------------- |\n| :runit | Replaces Debian's Upstart. Used for service supervision and management. Much easier to use than SysV init and supports restarting daemons when they crash. Much easier to use and more lightweight than Upstart. \u003cbr\u003e\u003cbr\u003e*This service is part of the multiple-process-stack.*|\n| :cron | Cron daemon. \u003cbr\u003e\u003cbr\u003e*This service is part of the multiple-process-stack.*|\n| :syslog-ng-core | Syslog daemon so that many services - including the kernel itself - can correctly log to /var/log/syslog. If no syslog daemon is running, a lot of important messages are silently swallowed. \u003cbr\u003e\u003cbr\u003eOnly listens locally. All syslog messages are forwarded to \"docker logs\".\u003cbr\u003e\u003cbr\u003e*This service is part of the multiple-process-stack.* |\n| :logrotate | Rotates and compresses logs on a regular basis. \u003cbr\u003e\u003cbr\u003e*This service is part of the multiple-process-stack.*|\n| :ssl-tools | Add CFSSL a CloudFlare PKI/TLS swiss army knife. It's a command line tool for signing, verifying, and bundling TLS certificates. Comes with cfssl-helper tool that make it docker friendly by taking command line parameters from environment variables. \u003cbr\u003e\u003cbr\u003eAlso add jsonssl-helper to get certificates from json files, parameters are set by environment variables. |\n\n\n## Advanced User Guide\n\n### Service available\n\nA service-available is basically a normal service expect that it is in the `service-available` directory and have a `download.sh` file.\n\nTo add a service-available to the current image use the `add-service-available` tool. It will process the download.sh file of services given in argument and move them to the regular service directory (/container/service).\n\nAfter that the service-available will be process like regular services.\n\nHere simple Dockerfile example how to add a service-available to an image:\n\n        # Use osixia/light-baseimage\n        # https://github.com/osixia/docker-light-baseimage\n        FROM osixia/light-baseimage:1.3.3\n\n        # Add cfssl and cron service-available\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/tool/add-service-available\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/download.sh\n        # https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:cron/download.sh\n        RUN apt-get -y update \\\n            \u0026\u0026 /container/tool/add-service-available :ssl-tools :cron \\\n            \u0026\u0026 LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \\\n               nginx \\\n               php7.0-fpm\n        ...\n\n\nNote: Most of predefined service available start with a `:` to make sure they are installed before regular services (so they can be used by regular services). The install-service tool process services in /container/service in alphabetical order.\n\nTo create a service-available just create a regular service, add a download.sh file to set how the needed content is downloaded and add it to /container/service-available directory. The download.sh script is not mandatory if nothing need to be downloaded.\n\nFor example a simple image example that add service-available to this baseimage: [osixia/web-baseimage](https://github.com/osixia/docker-web-baseimage)\n\n\n### Fix docker mounted file problems\n\nFor some reasons you will probably have to mount custom files to your container. For example in the *mutliple process image example* you can customise the nginx config by mounting your custom config to \"/container/service/php/config/default\" :\n\n    docker run -v /data/my-nginx-config:/container/service/php/config/default example/multiple-process\n\nIn this case every thing should work fine, but if the startup script makes some `sed` replacement or change file owner and permissions this can results in \"Device or resource busy\" error. See [Docker documentation](https://docs.docker.com/v1.4/userguide/dockervolumes/#mount-a-host-file-as-a-data-volume).\n\n    sed -i \"s|listen 80|listen 8080|g\" /container/service/php/config/default\n\nTo prevent that king of error light-baseimage provide *--copy-service* command argument :\n\n    docker run -v /data/my-nginx-config:/container/service/php/config/default example/multiple-process --copy-service\n\nOn startup this will copy all /container/service directory to /container/run/service.\n\n\nAt run time you can get the container service directory with `CONTAINER_SERVICE_DIR` environment variable.\nIf *--copy-service* is used *CONTAINER_SERVICE_DIR=/container/run/service* otherwise *CONTAINER_SERVICE_DIR=/container/service*\n\nSo to always apply sed on the correct file in the startup script the command becomes :\n\n    sed -i \"s|listen 80|listen 8080|g\" ${CONTAINER_SERVICE_DIR}/php/config/default\n\n\n### Distribution packages documentation and locales\n\nThis image has a configuration to prevent documentation and locales to be installed from base distribution packages repositories to make it more lightweight as possible. If you need the doc and locales remove the following files :\n**/etc/dpkg/dpkg.cfg.d/01_nodoc** and **/etc/dpkg/dpkg.cfg.d/01_nolocales**\n\n\n### Mastering image tools\n\n#### run\n\nThe *run tool* is defined as the image ENTRYPOINT (see [Dockerfile](image/Dockerfile)). It's the core tool of this image.\n\nWhat it does:\n- Setup the run directory\n- Set the startup files environment\n- Run startup files\n- Set process environment\n- Run process\n\n##### Run command line options\n\n*Run tool* takes several options, to list them:\n\n    docker run osixia/light-baseimage:1.3.3 --help\n    usage: run [-h] [-e] [-s] [-p] [-f] [-o {startup,process,finish}]\n               [-c COMMAND [WHEN={startup,process,finish} ...]] [-k]\n               [--wait-state FILENAME] [--wait-first-startup] [--keep-startup-env]\n               [--copy-service] [--dont-touch-etc-hosts] [--keepalive]\n               [--keepalive-force] [-l {none,error,warning,info,debug,trace}]\n               [MAIN_COMMAND [MAIN_COMMAND ...]]\n\n    Initialize the system.\n\n    positional arguments:\n      MAIN_COMMAND          The main command to run, leave empty to only run\n                            container process.\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      -e, --skip-env-files  Skip getting environment values from environment\n                            file(s).\n      -s, --skip-startup-files\n                            Skip running /container/run/startup/* and\n                            /container/run/startup.sh file(s).\n      -p, --skip-process-files\n                            Skip running container process file(s).\n      -f, --skip-finish-files\n                            Skip running container finish file(s).\n      -o {startup,process,finish}, --run-only {startup,process,finish}\n                            Run only this file type and ignore others.\n      -c COMMAND [WHEN={startup,process,finish} ...], --cmd COMMAND [WHEN={startup,process,finish} ...]\n                            Run this command before WHEN file(s). Default before\n                            startup file(s).\n      -k, --no-kill-all-on-exit\n                            Don't kill all processes on the system upon exiting.\n      --wait-state FILENAME\n                            Wait until the container state file exists in\n                            /container/run/state directory before starting.\n                            Usefull when 2 containers share /container/run\n                            directory via volume.\n      --wait-first-startup  Wait until the first startup is done before starting.\n                            Usefull when 2 containers share /container/run\n                            directory via volume.\n      --keep-startup-env    Don't remove ('.startup.yaml', '.startup.json')\n                            environment files after startup scripts.\n      --copy-service        Copy /container/service to /container/run/service.\n                            Help to fix docker mounted files problems.\n      --dont-touch-etc-hosts\n                            Don't add in /etc/hosts a line with the container ip\n                            and $HOSTNAME environment variable value.\n      --keepalive           Keep alive container if all startup files and process\n                            exited without error.\n      --keepalive-force     Keep alive container in all circonstancies.\n      -l {none,error,warning,info,debug,trace}, --loglevel {none,error,warning,info,debug,trace}\n                            Log level (default: info)\n\n    Osixia! Light Baseimage: https://github.com/osixia/docker-light-baseimage\n\n\n##### Run directory setup\n*Run tool* will create if they not exists the following directories:\n  - /container/run/state\n  - /container/run/environment\n  - /container/run/startup\n  - /container/run/process\n  - /container/run/service\n\nAt the container first start it will search in /container/service or /container/run/service (if --copy-service option is used) all image's services.\n\nIn a service directory for example /container/service/my-service:\n  - If a startup.sh file is found, the file is linked to /container/run/startup/my-service\n  - If a process.sh file is found, the file is linked to /container/run/process/my-service/run\n\n##### Startup files environment setup\n*Run tool* takes all file in /container/environment/* and import the variables values to the container environment.\nThe container environment is then exported to /container/run/environment and in /container/run/environment.sh\n\n##### Startup files execution\n*Run tool* iterate trough /container/run/startup/* directory in alphabetical order and run scripts.\nAfter each time *run tool* runs a startup script, it resets its own environment variables to the state in /container/run/environment, and re-dumps the new environment variables to /container/run/environment.sh\n\nAfter all startup script *run tool* run /container/run/startup.sh if exists.\n\n##### Process environment setup\n*Run tool* delete all .startup.yaml and .startup.json in /container/environment/* and clear the previous run environment (/container/run/environment is removed)\nThen it takes all remaining file in /container/environment/* and import the variables values to the container environment.\nThe container environment is then exported to /container/run/environment and in /container/run/environment.sh\n\n##### Process execution\n\n###### Single process image\n\n*Run tool* execute the unique /container/run/process/service-name/run file.\n\nIf a main command is set for example:\n\n    docker run -it osixia/openldap:1.4.0 bash\n\n*Run tool* will execute the single process and the main command. If the main command exits the container exits. This is useful to debug or image development purpose.\n\n###### Multiple process image\n\nIn a multiple process image *run tool* execute runit witch supervise /container/run/process directory and start all services automatically. Runit will also relaunched them if they failed.\n\nIf a main command is set for example:\n\n    docker run -it osixia/phpldapadmin:0.9.0 bash\n\n*run tool* will execute runit and the main command. If the main command exits the container exits. This is still useful to debug or image development purpose.\n\n###### No process image\nIf a main command is set *run tool* launch it otherwise bash is launched.\nExample:\n\n    docker run -it osixia/light-baseimage:1.3.3\n\n\n##### Extra environment variables\n\n*run tool* add 3 variables to the container environment:\n- **CONTAINER_STATE_DIR**: /container/run/state\n- **CONTAINER_SERVICE_DIR**: the container service directory. By default: /container/service but if the container is started with --copy-service option: /container/run/service\n- **CONTAINER_LOG_LEVEL**: log level set by --loglevel option defaults to: 3 (info)\n\n#### log-helper\nThis tool is a simple utility based on the CONTAINER_LOG_LEVEL variable to print leveled log messages.\n\nFor example if the log level is info:\n\n    log-helper info hello\n\nwill echo:\n\u003e hello\n\n    log-helper debug i'm bob\n\nwill echo nothing.\n\nlog-helper support piped input:\n\n    echo \"Heyyyyy\" | log-helper info\n\n\u003e Heyyyyy\n\nLog message functions usage: `log-helper error|warning|info|debug|trace message`\n\nYou can also test the log level with the level function:\n\n    log-helper level eq info \u0026\u0026 echo \"log level is infos\"\n\nfor example this will echo \"log level is trace\" if log level is trace.\n\nLevel `function usage: log-helper level eq|ne|gt|ge|lt|le none|error|warning|info|debug|trace`\nHelp: [http://www.tldp.org/LDP/abs/html/comparison-ops.html](http://www.tldp.org/LDP/abs/html/comparison-ops.html)\n\n#### complex-bash-env\nWith light-baseimage you can set bash environment variable from .yaml and .json files.\nBut bash environment variables can't store complex objects such as table that can be defined in yaml or json files, that's why they are converted to \"complex bash environment variables\" and complex-bash-env tool help getting those variables values easily.\n\nFor example the following yaml file:\n\n      FRUITS:\n        - orange\n        - apple\n\nwill produce this bash environment variables:\n\n      FRUITS=#COMPLEX_BASH_ENV:TABLE: FRUITS_ROW_1 FRUITS_ROW_2\n      FRUITS_ROW_1=orange\n      FRUITS_ROW_2=apple\n\n(this is done by run tool)\n\ncomplex-bash-env make it easy to iterate trough this variable:\n\n      for fruit in $(complex-bash-env iterate FRUITS)\n      do\n        echo ${!fruit}\n      done\n\nA more complete example can be found [osixia/phpLDAPadmin](https://github.com/osixia/docker-phpLDAPadmin) image.\n\nNote this yaml definition:\n\n    FRUITS:\n      - orange\n      - apple\n\nCan also be set by command line converted in python or json:\n\n    docker run -it --env FRUITS=\"#PYTHON2BASH:['orange','apple']\" osixia/light-baseimage:1.3.3 printenv\n    docker run -it --env FRUITS=\"#JSON2BASH:[\\\"orange\\\",\\\"apple\\\"]\" osixia/light-baseimage:1.3.3 printenv\n\n### Tests\n\nWe use **Bats** (Bash Automated Testing System) to test this image:\n\n\u003e [https://github.com/bats-core/bats-core](https://github.com/bats-core/bats-core)\n\nInstall Bats, and in this project directory run:\n\n\tmake test\n\n## Changelog\n\nPlease refer to: [CHANGELOG.md](CHANGELOG.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosixia%2Fcontainer-baseimage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosixia%2Fcontainer-baseimage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosixia%2Fcontainer-baseimage/lists"}