0

I am trying to enable cron for arangodb image:

https://github.com/arangodb/arangodb-docker/blob/a33b50b8a5c9a60f8c812016899485cc9cd78de3/alpine/3.10.3/Dockerfile

What is the correct way to pass 2 commands, but only one of them (arangod) requires ENTRYPOINT?

I am trying something like:

FROM arangodb:3.10.3
ENTRYPOINT ["/entrypoint.sh"]

# standard port
EXPOSE 8529
CMD ["arangod", "/usr/sbin/crond -f"]

but this setup fails (If I am using it without "/usr/sbin/crond -f" - everything is fine).

Bogdan Timofeev
  • 1,062
  • 3
  • 11
  • 33

2 Answers2

1

What is the correct way to pass 2 commands

Almost always in two separate containers. With this particular image, you can't use CMD on its own to run both the database and a cron daemon in the same container, but this isn't usually a best practice.

For to this question in particular, databases are generally designed to be called via a network connection, and so it's generally possible to run administrative tools from another container. For example, you could give an arangodump --server.endpoint option to take a database dump from another container; it does not need to run from inside the same container.

This means that you probably need the unmodified ArangoDB container, plus a second container that separately runs the cron daemon. Extending the ArangoDB image for this is reasonable, since it will already contain the tools you need; it's helpful to look at its Dockerfile to observe that (a) it is build FROM alpine (which affects the crond syntax; see the BusyBox command reference) and (b) as you note it has an embedded ENTRYPOINT you might need to reset.

FROM arangodb:3.10.3
COPY crontab /
RUN crontab -u root /crontab \
 && rm -f /crontab
ENTRYPOINT []
CMD ["crond", "-f"]

(Another option is to use an Alpine, Ubuntu, or Debian base image and then go through ArangoDB's installation instructions from there. This will have an advantage of not leaking anonymous volumes, but a disadvantage of being a little harder to construct.)

A sample Docker Compose setup that could run both containers:

version: '3.8'
services:
  db:
    image: arangodb:3.10.3
    environment:
      ARANGO_ROOT_PASSWORD: passw0rd
    volumes:
      - db:/var/lib/arangodb3
  cron:
    build: ./cron
    environment:
      ARANGO_HOST: db
      ARANGO_ROOT_PASSWORD: passw0rd
volumes:
  db: # intentionally empty

It's also helpful to glance through the actual entrypoint script. This is implemented as a typical entrypoint wrapper script: it does its first-time setup and then uses exec "$@" to run whatever the CMD was. So you don't actually have to reset the ENTRYPOINT here.

Of note, the interesting first-time setup only happens if the first word of CMD is exactly arangod. There are some tricks you can try to use to break Docker's standard pattern and run multiple processes in a container (How to run a cron job inside a docker container? will find you several of these); but if you try to use a shell for anything, the first word of CMD will not be arangod and the database initialization will not happen.

You can find some of the referenced scripts by going to the Docker Hub arangodb image page; clicking on one of the "supported tags and respective Dockerfile links" will take you to the Dockerfile in GitHub; and from there you can generally explore the same directory to find things like entrypoint scripts.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • yes, arangodump was exactly the reason why I needed cron. Created another container which looks into database with --server.endpoint and ran cron there. – Bogdan Timofeev May 28 '23 at 22:41
0

CMD can be used in three forms, using "shell form" you can execute multiple commands in sequence.

FROM arangodb:3.10.3
ENTRYPOINT ["/entrypoint.sh"]

# standard port
EXPOSE 8529
CMD /usr/sbin/crond -f && arangod

Another option would be to make a start.sh script and place your commands in there and execute it from CMD.

Asplund
  • 2,254
  • 1
  • 8
  • 19