Code Monkey home page Code Monkey logo

entrykit's Introduction

Entrykit

Entrypoint tools for elegant containers.

Entrykit takes common tasks you might put in an entrypoint start script and lets you quickly set them up in your Dockerfile. It's sort of like an init process, but we don't believe in heavyweight init systems inside containers. Instead, Entrykit takes care of practical tasks for building minimal containers.

Getting Entrykit

In your Dockerfile download a release of Entrykit and extract it into your PATH, such as /bin for simplicity. For best experience, run entrykit --symlink to set up the subcommands as regular commands.

See the example directory for a demo Nginx container using Entrykit.

Using Entrykit

Once set up, you use Entrykit commands in your entrypoint. You can use just one or chain them together. They all have the same usage structure:

<command> [[name=]task...] [-- exec]

Commands are documented below. Commands take one or more optionally named "tasks", which is often a shell command, but is sometimes a file to operate on. Then -- is used to define the next operation. This is similar to && except it's built in to all commands so you don't need to run these commands in a subshell.

Commands

codep - Codependent tasks

codep runs multiple processes in parallel, proxying signals, but unlike nearly every init system, it kills all processes if one process terminates. This allows the container to exit so Docker or another init system can cleanly restart it if appropriate.

This is ideal for runtime configuration rendering tools, such as conf.d and consul-template, or anything else that makes sense to run as a co-process in the container. Don't go overboard!

ENTRYPOINT ["codep", \
    "/bin/config-reloader", \
    "/usr/sbin/nginx" ]

You can run more tasks after your tasks exit using --, but this is not terribly common.

render - Template rendering

render takes one or more paths to files that will be rendered using Sigil templating. The template is loaded from a file with the same path but with .tmpl added extension. For example, if you want to render a template at /etc/nginx.conf, then you would copy a template file to /etc/nginx.conf.tmpl and use render /etc/nginx.conf.

This is particularly useful to use environment variables in configuration, which is our preferred way to configure containers at boot time. But it also comes with the rest of Sigil's configuration oriented templating functions.

COPY ./nginx.conf.tmpl /etc/nginx.conf.tmpl
ENTRYPOINT ["render", "/etc/nginx.conf", "--", "/usr/sbin/nginx"]

Since you usually have more to do after the render command, it's typical to chain with --. Anything after -- is exec'd into.

switch - Command switching

switch allows you to exec into alternative processes than your normal entrypoint based on the command provided when the container is run. We typically like containers that need no command and just do their thing immediately, but sometimes there are alternative modes of operation such as getting into the shell or displaying version or help information.

This is the first command to really take advantage of named tasks. The name of the task is the command string it will switch on, and the value is the full command it will run. For example, you can expose the shell when users run with the command shell with switch shell=/bin/sh. And as usual you can provide multiple tasks for more than one command.

ENTRYPOINT ["switch", "shell=/bin/sh", "version=nginx -v", "--", "/usr/sbin/nginx"]

If none of the commands are provided, it goes on to exec the next task after --.

prehook - Run pre-commands on start

If there are other set up tasks to perform, you can add them with prehook. You can specify multiple tasks and they'll be run in order. If they fail, the chained tasks will not be run. This is particularly interesting when you use an undocumented flag that allows users to specify their own prehook commands. This is an example of how Entrykit can be used to make your containers more customizable by the user. But for now, it's just a way to run serial tasks before your final entrypoint command.

Here we display the Nginx version before starting Nginx:

ENTRYPOINT ["prehook", "nginx -V", "--", "/usr/sbin/nginx"]

Chaining

All these commands can be used together. Here is an example of all of them being used together as demonstrated in the example directory:

ENTRYPOINT [ \
  "switch", \
    "shell=/bin/sh", \
    "version=nginx -v", "--", \
  "render", "/demo/nginx.conf", "--", \
  "prehook", "nginx -V", "--", \
  "codep", \
    "/bin/reloader 3", \
    "/usr/sbin/nginx -c /demo/nginx.conf" ]

Other ways to define your entrypoint

Although not documented or properly tested, there are other ways you can set up these entrypoint commands. One way is with environment variables defined previously in your Dockerfile. It would look something like this:

ENV SWITCH_SHELL=/bin/sh
ENV RENDER_CONFIG=/etc/nginx.conf
ENV CODEP_NGINX=nginx -g
ENV CODEP_CONFD=confd
ENV PREHOOK_HTPASSWD=htpasswd -bc /etc/nginx/htpasswd $HTPASSWD

ENTRYPOINT ["entrykit -e"]

There is potentially another flag implemented to read config like that from a file. However, and this might be desired, this opens up the ability for users to mess with your entrypoint! But it's only possible if explicitly enabled.

License

MIT

entrykit's People

Contributors

hoel-zr-o avatar joemcmahon avatar progrium avatar ssoriche avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

entrykit's Issues

alpine package

Entrykit works great with Alpine and it's a bit cumbersome to set up Entrykit. curl .. | tar .. and then entrykit --symlink. If made an Alpine package it could be as simple as apk-install entrykit.

`prehook` cannot find executable

[Originally posted by @Brescia717]
Any chance you've tried using prehook? Running this in the Dockerfile:

ENTRYPOINT [ \
  "prehook", "ruby -v", "--", \
  "prehook", "/myapp/backend/prehook", "--"]

yields this error:

Error response from daemon: failed to create shim task: 
OCI runtime create failed: runc create failed: 
unable to start container process: 
exec: "prehook": executable file not found in $PATH: unknown

NOTE: /myapp/backend is the directory the application is in, in the docker container.

Don't render if file exists

Idea...render should only render the template if the desired file does not exist. For example, say the end user of a Docker image wants to provide a config file through a volume mount and not care about rendering a template at all.

codep argument parsing

I do this:

ENTRYPOINT [ \
  "codep", \
    "/usr/sbin/ucarp --interface=eth0", \
    "/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg" ]

And get this:

!! exec: "eth0": executable file not found in $PATH

I don't really understand what's happening, I think codep parses argv[1] wrongly.

render only last file having same base filename

If render files having same base filename like test.01.txt test.02.txt, only last file are rendered.

My Dockerfile is like below.

FROM ubuntu:latest
ENV ENTRYKIT_VERSION   0.4.0
ADD https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz /tmp/entrykit.tgz
RUN tar -xf /tmp/entrykit.tgz -C /bin entrykit && \
    entrykit --symlink && \
    true
COPY test.01.txt.tmpl /tmp/
COPY test.02.txt.tmpl /tmp/
ENTRYPOINT [ \
    "render", \
        "/tmp/test.01.txt", \
        "/tmp/test.02.txt", \
    "--", \
    "codep", \
        "tail -f /dev/null" \
]

I run this image and exec ls /tmp/. Only test.02.txt exist.

entrykit.tgz  test.01.txt.tmpl  test.02.txt  test.02.txt.tmpl

But if divide render task into two like below, both files are renderd.

ENTRYPOINT [ \
    "render", \
        "/tmp/test.01.txt", \
    "--", \
    "render", \
        "/tmp/test.02.txt", \
    "--", \
    "codep", \
        "tail -f /dev/null" \
]

releases and Dockerfile

Would it be possible that the releases are binaries instead of tgz ?
This would allow us to do this in Dockerfiles:
ADD https://github.com/progrium/entrykit/releases/download/v0.4.0/entrykit_0.4.0_Linux_x86_64 /bin/entrykit

Trouble quoting arguments to codep commands

With a command like codep <script with flags> <other script> I could not figure out how to get things to behave correctly when the flags required quoting.

For instance, with codep "consul-template -template '/etc/nginx/conf.d/services.conf.ctmpl:/etc/nginx/conf.d/services.conf:nginx -s reload'" I could not for the life of me figure out the quoting that would work correctly. Part of the issue might be that the ENTRYPOINT from Dockerfile makes this even more complicated, but I haven't tried codep directly yet.

I ended up just using an HCL file so I wouldn't need to quote the spaces around "nginx -s reload".

Documentation

These tools look like they could be very useful. Some documentation to help explain them, what they do, and maybe an example use case would be awesome.

Race condition near `t.Process.Signal(sig)`?

Sometimes running these commands panics a Go program, sometimes it doesn't seem to do anything:

$ sudo docker run -it progrium/envy sh
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x451d12]

goroutine 9 [running]:
os.(*Process).signal(0x0, 0x7f206b2c77a8, 0xc2080325a8, 0x0, 0x0)
        /usr/local/go/src/os/exec_unix.go:40 +0x42
os.(*Process).Signal(0x0, 0x7f206b2c77a8, 0xc2080325a8, 0x0, 0x0)
        /usr/local/go/src/os/doc.go:51 +0x4e
github.com/progrium/entrykit.func·001()
        /home/ubuntu/.go_workspace/src/github.com/progrium/entrykit/entrykit.go:51 +0xf8
created by github.com/progrium/entrykit.ProxySignals
        /home/ubuntu/.go_workspace/src/github.com/progrium/entrykit/entrykit.go:54 +0x12e

...

Same thing with /bin/bash:

$ sudo docker run -it progrium/envy /bin/bash
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x451d12]

goroutine 9 [running]:
os.(*Process).signal(0x0, 0x7fe1542ca7a8, 0xc2080325e8, 0x0, 0x0)
        /usr/local/go/src/os/exec_unix.go:40 +0x42
os.(*Process).Signal(0x0, 0x7fe1542ca7a8, 0xc2080325e8, 0x0, 0x0)
        /usr/local/go/src/os/doc.go:51 +0x4e
github.com/progrium/entrykit.func·001()
        /home/ubuntu/.go_workspace/src/github.com/progrium/entrykit/entrykit.go:51 +0xf8
created by github.com/progrium/entrykit.ProxySignals
        /home/ubuntu/.go_workspace/src/github.com/progrium/entrykit/entrykit.go:54 +0x12e

...

Support on Mac M1

Hi, do you have any plan on supporting the Macbook M1? I'm getting this error on my machine:

image

Here's how we used entrykit in our Docker


RUN wget https://github.com/progrium/entrykit/releases/download/v${ENTRYKIT_VERSION}/entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && tar -xvzf entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && rm entrykit_${ENTRYKIT_VERSION}_Linux_x86_64.tgz \
  && mv entrykit /bin/entrykit \
  && chmod +x /bin/entrykit \
  && entrykit --symlink

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.