Skip to content

Service Templates

Service templates are predefined normal docker-compose files + a bit of magic.

The bit of Magic

To be able to predefine values, like usernames, passwords, fqdns, predefined values for bind (file) mounts etc, the docker-compose files are extended with a few keywords.

More magic coming soon 🪄


In the enviroment option, you can do the following.

Let's use APPWRITE as an example with a generate UUID of vgsco4o and with a wildcard domain of http://example.com.


FQDN

This will generate a FQDN for appwrite service.

yaml
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE

If you use the same variable on another service, it will generate the same FQDN for you.

yaml
# This does not make sense, just here to show you how it works.
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE 
    not-appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE
# This does not make sense, just here to show you how it works.
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE 
    not-appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE

You sometimes need the same domain, but with different paths.

yaml
# This make sense, not like the previous.
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE
    not-appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/v1/realtime
        - SERVICE_FQDN_APPWRITE=/v1/realtime 
    definitely-not-appwrite:
      environment:
        # As SERVICE_FQDN_API is not the same as SERVICE_FQDN_APPWRITE
        # Coolify will generate a new FQDN 
        # http://definitely-not-appwrite-vgsco4o.example.com/api
        - SERVICE_FQDN_API=/api
# This make sense, not like the previous.
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE
    not-appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/v1/realtime
        - SERVICE_FQDN_APPWRITE=/v1/realtime 
    definitely-not-appwrite:
      environment:
        # As SERVICE_FQDN_API is not the same as SERVICE_FQDN_APPWRITE
        # Coolify will generate a new FQDN 
        # http://definitely-not-appwrite-vgsco4o.example.com/api
        - SERVICE_FQDN_API=/api

You can reuse this generated FQDN anywhere.

yaml
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE 
        - _APP_URL=$SERVICE_FQDN_APPWRITE # _APP_URL will have the FQDN because SERVICE_FQDN_APPWRITE is just a simple environment variable
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/
        - SERVICE_FQDN_APPWRITE 
        - _APP_URL=$SERVICE_FQDN_APPWRITE # _APP_URL will have the FQDN because SERVICE_FQDN_APPWRITE is just a simple environment variable

You sometimes need the same domain, but with different ports. This will tell the proxy which port to proxy to which domain. In the example, we combine paths and ports.

yaml
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/ will be proxied to port 3000
        - SERVICE_FQDN_APPWRITE_3000
        # http://api-vgsco4o.example.com/api will be proxied to port 2000
        - SERVICE_FQDN_API_2000=/api
services:
    appwrite:
      environment:
        # http://appwrite-vgsco4o.example.com/ will be proxied to port 3000
        - SERVICE_FQDN_APPWRITE_3000
        # http://api-vgsco4o.example.com/api will be proxied to port 2000
        - SERVICE_FQDN_API_2000=/api

This could be used as a value as well. No default value allowed.

yaml
services:
    appwrite:
      environment:
        # http://api-vgsco4o.example.com/api defined here
        - SERVICE_FQDN_API_2000=/api
        # http://appwrite-vgsco4o.example.com/ will be proxied to port 3000
        - APPWRITE_URL=$SERVICE_FQDN_APPWRITE_3000
        # http://api-vgsco4o.example.com/api will be proxied to port 2000
        - APPWRITE_API_URL=$SERVICE_FQDN_API_2000
services:
    appwrite:
      environment:
        # http://api-vgsco4o.example.com/api defined here
        - SERVICE_FQDN_API_2000=/api
        # http://appwrite-vgsco4o.example.com/ will be proxied to port 3000
        - APPWRITE_URL=$SERVICE_FQDN_APPWRITE_3000
        # http://api-vgsco4o.example.com/api will be proxied to port 2000
        - APPWRITE_API_URL=$SERVICE_FQDN_API_2000

URL

This will generate an URL based on the FQDN you have defined.

yaml
services:
    appwrite:
      environment:
        # appwrite-vgsco4o.example.com
        - SERVICE_URL_APPWRITE
services:
    appwrite:
      environment:
        # appwrite-vgsco4o.example.com
        - SERVICE_URL_APPWRITE

Username

Example: $SERVICE_USER_APPWRITE

Generator: Str::random(16)

yaml
services:
    appwrite:
      environment:
        # qwhraJlpdkyKYSQ1 (generated by Laravel's )
        - APPWRITE_USERNAME=$SERVICE_USER_APPWRITE
services:
    appwrite:
      environment:
        # qwhraJlpdkyKYSQ1 (generated by Laravel's )
        - APPWRITE_USERNAME=$SERVICE_USER_APPWRITE

Password

Example: $SERVICE_PASSWORD_APPWRITE

Generator: Str::password(symbols: false)

yaml
services:
    appwrite:
      environment:
        # m5XOD0uY4k1hXgISYoJyLdPHG7oAbNYw 
        - APPWRITE_PASSWORD=$SERVICE_PASSWORD_APPWRITE
services:
    appwrite:
      environment:
        # m5XOD0uY4k1hXgISYoJyLdPHG7oAbNYw 
        - APPWRITE_PASSWORD=$SERVICE_PASSWORD_APPWRITE

You can also generate 64 bit long password.

Example: $SERVICE_PASSWORD_64_APPWRITE

Generator: Str::password(length: 64, symbols: false)

yaml
services:
    appwrite:
      environment:
        # J0QT0Cqr2ArmIT4RgTwK5F5lcXShgnJ53XTiHjqBbPntWVVG8DRHKnrsIjXBZJ8e 
        - APPWRITE_PASSWORD=$SERVICE_PASSWORD_64_APPWRITE
services:
    appwrite:
      environment:
        # J0QT0Cqr2ArmIT4RgTwK5F5lcXShgnJ53XTiHjqBbPntWVVG8DRHKnrsIjXBZJ8e 
        - APPWRITE_PASSWORD=$SERVICE_PASSWORD_64_APPWRITE

Metadata

You need to add extra metadata to the top of the docker-compose file, like:

  • documentation link
  • a slogan
  • additional tags (for better searching)

Example:

# documentation: https://docs.n8n.io/hosting/
# slogan: n8n is an extendable workflow automation tool which enables you to connect anything to everything via its open, fair-code model.
# tags: n8n,workflow,automation,open,source,low,code

... rest of the compose file ...
# documentation: https://docs.n8n.io/hosting/
# slogan: n8n is an extendable workflow automation tool which enables you to connect anything to everything via its open, fair-code model.
# tags: n8n,workflow,automation,open,source,low,code

... rest of the compose file ...

Add a new service

Official templates stored here. They are just normal docker-compose files with a bit of magic.

To add a new service, your can easily test your templates with Docker Compose deployments inside Coolify. It uses the same process to parse, generate and deploy as the one-click services.

If you are done with tests and everything works, open a PR, that have the new <service>.yaml compose file under /templates/compose.

TIP

Coolify will use a parsed version.