Deploying Cro services in Docker containers
To aid deployment of Cro services using Docker, a number of base images are provided. These all include a recent MoarVM and Rakudo release, which Cro has been tested on. The
zef installer is also included, to aid installation of further dependencies during the container build. The images are Debian-based, making it easy to install packages with
Generation with cro stub§
Dockerfile is generated automatically when stubbing a service using the
cro stub command. The
Dockerfile will use a base image tied to the Cro version that you had installed when running
Using the image looks something like:
$ docker build -t my-service . ...lots of Docker output... $ docker run --rm -p 10000:10000 my-service Listening at http://0.0.0.0:10000
The service exposes itself and runs on port 10000 inside the container; to expose it as a different port on the host use something like:
$ docker run --rm -p 20000:10000 my-service Listening at http://0.0.0.0:10000
Which makes it accessible as port 20000 on the host. Cro does not attempt to maintain or update this Docker file, so feel free to change it according to your needs.
The following base images are available for application deployment:
cro-core** - includes the Cro::Core distribution; ideal when no other base image is applicable, but at least saves installing the
cro-http** - includes the
Cro::HTTPdistribution, which in turn depends on Cro::TLS and
Cro::Core. Includes libraries required for TLS to work. Ideal for web services.
cro-http-websocket** - as for
cro-core-http, but also includes the
Cro::WebSocketdistribution. Ideal for web servies that also use web sockets.
There is also a
cro base image which includes the development tools. This is not a good choice for deployment, since it includes a lot of modules that are only depended on by the
cro command line tool. However, it may be convenient for trying out Cro without needing a local install.
This is an annotated example of what would be generated by
cro stub. If you created your service without that tool, then you can take some inspiration from this example to write a
# Depend on the cro-http-websocket base image; pick a version FROM croservices/cro-http-websocket:0.7.3 # Copy the application so it lives under /app RUN mkdir /app COPY . /app WORKDIR /app # Install additional dependencies from META6.json. Then do a syntax check on # the entrypoint. This in turn loads and pre-compiles the application, making # sure any compilation errors will make the container build fail, and allowing # for faster container startup. RUN zef install --deps-only . && perl6 -c -Ilib service.p6 # Be sure to update the environment variable names to match those in the # entrypoint script! ENV MY_SERVICE_PORT="10000" MY_SERVICE_HOST="0.0.0.0" # Expose the port above EXPOSE 10000 # Run the service when the container is run CMD perl6 -Ilib service.p6
Also consider having a
.dockerignore file containing:
Tips for deploying Cro services with Docker§
These aren't specific to Cro, but are worth a mention.
Always use a versioned base image rather than
Make sure logging has been added to services, and preferably set up some kind of log aggregation. Unless you have an arrangement in place to send logs to a centralized logging solution, prefer logging to STDOUT/STDERR, as then the logs can be introspected by
kubectl log, etc.
Prefer using a tool like Kubernetes rather than managing containers and configuration by hand
Docker containers can be deployed on various cloud providers, some of which provide hosted Kubernetes.