Use Docker to deploy your application

Architecture schema


Configure your project

Edit the <package>.mk file and add those lines:

DOCKER_BASE = camptocamp/<project_name>

After that, a make --makefile=<> build will create Docker images named like that:

  • camptocamp/<project_name>_wsgi:latest
  • camptocamp/<project_name>_mapserver:latest
  • camptocamp/<project_name>_print:latest

The tag is by default latest, but you can change it by setting the DOCKER_TAG Makefile variable.

Edit vars.yaml and add:

dbhost: db
dbhost_slave: db

Database container

You can add scripts to populate the DB container by adding .sql or .sh files in the testdb directory. They must start with 2 digits, followed by an underscore. Please start at number 20.

Developer composition

A docker-compose.yml.mako file is created as a starting point.

If you want to host the database on your local machine, you must add a dbhost and dbhost_slave entry pointing to (your host address for Docker container) in your vars.yaml file. Then you need to make sure Postgres is configured to listen on that interface and accepts authentication.

If you want to use an external server for the database, just put its address in the dbhost and dbhost_slave entry.

Run the developer composition

make --makefile=<> build && docker-compose up

You can then access your application with http://localhost:8480/

Run with a local c2cgeoportal

If you need to fix bugs in c2cgeoportal or test new features, you need to alter the Docker image creation to use your version of c2cgeoportal.

First, you need to move/copy your c2cgeoportal clone into your project root directory. That is needed to allow Docker to see those files.

Then, add this line to your <package>.mk file (before the include ...):

TEMPLATE_EXCLUDE = c2cgeoportal

Edit your .dockerignore file and add those lines at the end:


Finally, edit your Dockerfile and add those lines just before the step #2:

COPY c2cgeoportal /app/c2cgeoportal
RUN pip install --editable=c2cgeoportal

Make your Docker images configurable from the composition


To make the DB connection used by your WSGI configurable from the composition, you can add this in your vars.yaml file:

  after_setup: {{package}}.after_setup_hook

Then, in your <package>/ file, add this function:

def after_settings_hook(settings):
    DB_KEY = "sqlalchemy.url"
    orig = settings[DB_KEY]
    new = os.environ.get("SQLALCHEMY_URL", orig)
    settings[DB_KEY] = new

By setting the SQLALCHEMY_URL environment variable in your composition for the WSGI image, you will be able to change the DB connection used.

You can change your production.ini and development.ini files to use environment variables for configuring the loggers. Here is an example for the part about the logging:

keys = root, sqlalchemy, c2cgeoportal

keys = console, logstash

keys = generic

level = %(OTHER_LOG_LEVEL)s
handlers = %(LOG_TYPE)s

level = %(C2C_LOG_LEVEL)s
handlers =
qualname = c2cgeoportal

level = %(SQL_LOG_LEVEL)s
handlers =
qualname = sqlalchemy.engine

class = StreamHandler
args = (sys.stdout,)
level = NOTSET
formatter = generic

format = %(levelname)-5.5s %(message)s

class = cee_syslog_handler.CeeSysLogHandler
args = [("%(LOG_HOST)s", %(LOG_PORT)s)]
level = NOTSET

Please note that to use CeeSysLogHandler, you need to add cee_syslog_handler>=0.3.3 to your dependencies.

Define default values for all the environment variables in your Dockerfile and then you can change them in your composition. For example add the following at the end of your Dockerfile:

ENV LOG_TYPE console
ENV LOG_HOST localhost


The created mapserver/Dockerfile file installs a hook to make the setup of the DB possible. Just set the DB_CONNECTION environment variable to something like:

  DB_CONNECTION: user=www-data password=toto dbname=geoacordaDev host=db

To have the right URL in the GetCapabilities:

  • In the Admin interface configure an OGC server with the URL: “http://mapserver/mapserv_proxy”.

  • In the project vars file add this:

        - mapserver

Keep your DB schema up to date

The WSGI image contains Alembic. You can use it as a start once container and add something like that in your composition:

    io.rancher.container.start_once: 'true'
  image: company/prefix_wsgi:tag
    SQLALCHEMY_URL: postgresql://postgres:${DB_PASSWORD}@db:5432/${DB_NAME}
    - db
  command: ./

When you do an upgrade, backup your DB and upgrade this container first. It will update your DB schema, if needed.


Docker does not clean anything automatically, in particular it does not clean any images, therefore disk space may become problematic after a certain number of builds. You can use the following commands to manually remove Docker files.

docker ps --all --quiet --filter status=exited | xargs --no-run-if-empty docker rm
docker images | grep "<none>" | awk '{print $3}' | xargs --no-run-if-empty docker rmi || true
docker volume ls --quiet --filter dangling=true | grep '[0-9a-f]\{64\}' | xargs --no-run-if-empty docker volume rm

This will remove:

* Container with exit status
* Images with version on name as `<none>`
* Unnamed dangling volumes