2

I'm relatively new to Docker and trying to learn self-hosting to host some small projects. I use a reasonably new PaaS tool called Dokploy to manage my containers.

I have been trying to run Directus (v10.13.1) using docker-compose, and everything works perfectly, except that my uploads folder empties after each deployment. I am missing some essential information here since I have tried to set persistent volumes for the data according to the documentation, but they empty themselves after each deployment.


Here is my docker-compose.yml:

version: "3"
services:
# Init permission: This service is used to set the correct
# permissions on the Directus directories during the build.
# Otherwise, the Directus application will not be able to
# write to the directories.
init-permissions:
    image: busybox
    command: ["sh", "-c", "/scripts/set-permissions.sh"]
    volumes:
        - ./database:/directus/database
        - ./uploads:/directus/uploads
        - ./extensions:/directus/extensions
        - ./templates:/directus/templates
    networks:
        - dokploy-network

# Database: This service is used to store the Directus data 
# in a PostgreSQL database.
database:
    image: postgres:16
    volumes:
        - postgres_data:/var/lib/postgresql/data
    networks:
        - dokploy-network
    environment:
        POSTGRES_USER:      "directus"
        POSTGRES_PASSWORD:  "${DB_PASSWORD}"
        POSTGRES_DB:        "directus"

# Cache: This service is used to store the Directus cache.
# It is used to speed up the Directus application.
cache:
    image: redis:6
    networks:
        - dokploy-network

# Clear cache: This service clears the Directus application’s 
# cache when updated.
clear-cache:
    image: redis:6
    command: ["redis-cli", "FLUSHALL"]
    networks:
        - dokploy-network
    depends_on:
        - cache

# Directus: This service is used to run the Directus application.
directus:
    image: directus/directus:${DIRECTUS_VERSION}
    networks:
        - dokploy-network
    ports:
        - 8055:8055
    environment:
        SECRET:             "${DIRECTUS_KEY}"
        ADMIN_EMAIL:        "${ADMIN_EMAIL}"
        ADMIN_PASSWORD:     "${ADMIN_PASSWORD}"
        DB_CLIENT:          "pg"
        DB_HOST:            "database"
        DB_PORT:            "5432"
        DB_DATABASE:        "directus"
        DB_USER:            "directus"
        DB_PASSWORD:        "${DB_PASSWORD}"
        CACHE_ENABLED:      "true"
        CACHE_AUTO_PURGE:   "true"
        CACHE_STORE:        "redis"
        REDIS:              "redis://cache:6379"
        WEBSOCKETS_ENABLED: "true"
        PUBLIC_URL:         "https://${TRAFFIC_DOMAIN}"
    volumes:
        - ./database:/directus/database
        - ./uploads:/directus/uploads
        - ./extensions:/directus/extensions
        - ./templates:/directus/templates
    labels:
        - "traefik.enable=true"
        - "traefik.http.routers.directus-${TRAFFIC_HASH}.rule=Host(`${TRAFFIC_DOMAIN}`)"
        - "traefik.http.routers.directus-${TRAFFIC_HASH}.entrypoints=websecure"
        - "traefik.http.routers.directus-${TRAFFIC_HASH}.tls.certresolver=letsencrypt"
        - "traefik.http.services.directus-${TRAFFIC_HASH}.loadbalancer.server.port=${TRAFFIC_PORT}"
        - "traefik.http.routers.directus-${TRAFFIC_HASH}-http.middlewares=redirect-to-https"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
    depends_on:
        - init-permissions
        - cache
        - database
        - clear-cache

Networks: This section is used to define the network that the

services will use to communicate with each other.

networks: dokploy-network: external: true

Volumes: This section is used to define the volumes that the

services will use to store their data persistently.

volumes: directus: postgres_data:

Here is also my /scripts/set-permissions.sh used by busybox to give the correct permissions:

chown -R 1000:1000 /directus/uploads /directus/extensions /directus/database /directus/templates
chmod -R 755 /directus/uploads /directus/extensions /directus/database /directus/templates

Here is the default run command used by Dokploy:

(docker compose -p directus-e2be29 -f ./docker-compose.yml up -d --build --remove-orphans)

Can any more knowledgeable person guide me on the right track? I will try to answer all the questions the best I can. Thank you all in advance! Also please let me know if this question doesn't belong to this StackExchange community.

1 Answers1

3

You may need to change these lines in your docker-compose.yml:

        volumes:
            - ./database:/directus/database
            - ./uploads:/directus/uploads
            - ./extensions:/directus/extensions
            - ./templates:/directus/templates

to

        volumes:
            - ../files/database:/directus/database
            - ../files/uploads:/directus/uploads
            - ../files/extensions:/directus/extensions
            - ../files/templates:/directus/templates

I ran into a similar issue when setting up volumes with Dokploy and docker-compose and missed the section where they show the preferred way to set up persistent volumes in their documentation

https://docs.dokploy.com/en/docs/core/docker-compose/overview#advanced

If you scroll down to the bottom of this page they say this:

Docker volumes are a way to persist data generated and used by Docker containers. They are particularly useful for maintaining data between container restarts or for sharing data among different containers.

To bind a volume to the host machine, you can use the following syntax in your docker-compose.yml file, but this way will clean up the volumes when a new deployment is made:

volumes:
  - "/folder:/path/in/container" ❌

It's recommended to use the ../files folder to ensure your data persists between deployments. For example:

volumes:
  - "../files/my-database:/var/lib/mysql" ✅
  - "../files/my-configs:/etc/my-app/config" ✅
Blake
  • 46