Watch inYaml file using www-data user/group?

Hi,

I use the command watch in my YAML file in order to sync my code on local computer to docker container.

However, every time a sync occurs, the docker container has the parent folder owner rewritten to root:root instead of www-data:www-data

Is there a command / switch to change, in order to make each sync from my local computer to container to use the user “www-data” (group “www-data” instead of root:root ?

thx.

It will use whatever is declared as last USER instruction.

Can you share your exact use case? Does this prevent the www-data user to be able to read the file? It shouldn’t hurt in an ephemeral container, unless something inside the container tries to modify the files you synched into the container.

To extend @meyay’s answer: Based on your previous posts and the “www-data” user, I assume you are syncing files into a PHP-FPM container. PHP containers by default run as root and PHP forks processes to run as www-data. So the USER will be root, even if the PHP process runs as non-root. As far as I remember, you can also run the main PHP process as non-root and you will just see a warning that PHP could not change the original user if the container user is not the same as configured in PHP.-FPM.

You could try changing the USER directive if you have a Dockerfile or add user: in compose

basically I have the following YAML to create a containers stack to locally develop a wordpress extension. In Visual Studio Code, everytime I change my local Wordpress Extension code, it sync the changes with docker container content, but the parent folder where the changed/synced file has its owner:ownergroup changed to root:root, instad of www-data:www-data

Here it is my YAM: file:

services:
  nginx:
    container_name: nginx
    build:
      context: .
      dockerfile: dockerfile-nginx
    restart: unless-stopped
    ports:
      - "80:80"
      # - "9000:9000"
    volumes:
      - wordpress:/var/www/html
      - nginx:/etc/nginx/conf.d
    # - certbot-etc:/etc/letsencrypt
    depends_on:
      - wp
    networks:
      - app-network

  wp:
    container_name: wordpress
    depends_on:
      - db
    build:
      context: .
      dockerfile: dockerfile-wp
    restart: unless-stopped
    env_file: .env
    environment:
      # PHP_MEMORY_LIMIT: 512M
      WORDPRESS_DB_HOST: db:${MARIADB_PORT}
      WORDPRESS_DB_USER: ${WORDPRESS_DB_USER}
      WORDPRESS_DB_NAME: ${WORDPRESS_DB_NAME}
      WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
      WORDPRESS_TABLE_PREFIX: ${WORDPRESS_DB_TABLE_PREFIX}
    volumes:
      - wordpress:/var/www/html
    develop:
      watch:
        - action: sync
          path: ./wordpress
          target: /var/www/html
    networks:
      - app-network


  ftp:
    image: stilliard/pure-ftpd:hardened
    restart: always
    depends_on:
      - wp
    environment:
      PUBLICHOST: ${PUBLICHOST}
      FTP_USER_NAME: ${FTP_USER_NAME}
      FTP_USER_PASS: ${FTP_USER_PASS}
      FTP_USER_UID: ${FTP_USER_UID}
      FTP_USER_GID: ${FTP_USER_GID}
      FTP_USER_HOME: ${FTP_USER_HOME}
      FTP_MAX_CLIENTS: ${FTP_MAX_CLIENTS}
      FTP_MAX_CONNECTIONS: ${FTP_MAX_CONNECTIONS}
      PURE_FTPD_PASSIVE_PORTS: "30000:30009"
    ports:
      - "21:21"
      - "30000-30009:30000-30009"
    volumes:
      - wordpress:/var/www/html

  mailpit:
    container_name: mailpit
    image: axllent/mailpit:latest
    restart: unless-stopped
    env_file: .env
    ports:
      - 8025:8025
      - 1025:1025
    volumes:
      - maildb:/data/mailpit.db
    networks:
      - app-network

  db:
    container_name: mariadb
    image: mariadb:latest
    restart: unless-stopped
    env_file: .env
    ports:
      - 3306:3306
    environment:
      MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD}
      MARIADB_DATABASE: ${WORDPRESS_DB_NAME}
      MARIADB_USER: ${WORDPRESS_DB_USER}
      MARIADB_PASSWORD: ${WORDPRESS_DB_PASSWORD}
    volumes:
      - mariadb:/var/lib/mysql
    networks:
      - app-network


  adminer:
    container_name: admirer
    image: adminer
    restart: always
    ports:
      - 8080:8080
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  wordpress:
  mariadb:
  nginx:
  maildb:
  ssl:

here it is my dockerfile-wp:

FROM wordpress:6.8.3-fpm-alpine

# Install dependencies for WP-CLI and database health checks
RUN apk add --no-cache bash less mariadb-client

# Install WP-CLI
RUN curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar \
    && chmod +x wp-cli.phar \
    && mv wp-cli.phar /usr/local/bin/wp

# Copy our automation script
COPY setup-wp.sh /usr/local/bin/setup-wp.sh
#COPY /var/www/html/wp-config.php wordpress/wp-config.php
RUN chmod +x /usr/local/bin/setup-wp.sh

# This allow to download and install wordpress
RUN echo 'memory_limit = 512M' >> /usr/local/etc/php/conf.d/docker-php-memlimit.ini

ENTRYPOINT ["setup-wp.sh"]
CMD ["php-fpm"]

and setup-wp.sh file:

#!/bin/bash
set -e

# 1. Wait for the Database
echo "Checking database connection..."
# to use the container name of the database, so "db"
until /usr/bin/mariadb-admin ping -h"db" -u"$WORDPRESS_DB_USER" -p"$WORDPRESS_DB_PASSWORD" --silent; do
    echo "Database not ready. Retrying in 2 seconds..."
    sleep 2
done



# 2. Run the WordPress Installation
# We use --allow-root because the container runs as root by default
if ! wp core is-installed --allow-root; then
    echo "Installing WordPress with provided configuration..."

    # 1. Download WordPress core files if they don't exist
    if [ ! -f wp-config-sample.php ]; then
        echo "Downloading WordPress core..."
        wp core download --allow-root
    fi
    
    # 2. Create wp-config.php (Crucial step)
    # This connects the files to the database variables
    if [ ! -f wp-config.php ]; then
        echo "Creating wp-config.php..."
        wp config create --allow-root \
            --dbname="${WORDPRESS_DB_NAME}" \
            --dbuser="${WORDPRESS_DB_USER}" \
            --dbpass="${WORDPRESS_DB_PASSWORD}" \
            --dbhost="${WORDPRESS_DB_HOST}"
    fi

    # chmod 644 -R /var/www/html

    # 3. Run the Installation
    wp core install --allow-root \
        --url="${WP_URL}" \
        --title="${WP_TITLE}" \
        --admin_user="${WP_ADMIN_USER}" \
        --admin_password="${WP_ADMIN_PASSWORD}" \
        --admin_email="${WP_ADMIN_EMAIL}" \
        --skip-email

    # 4. Optional: Automatically install a theme or plugins
    wp theme install generatepress --activate --allow-root
    wp plugin install query-monitor --activate --allow-root
    wp plugin install woocommerce --activate --allow-root

    # configuration WooCommerce
    # wp option list --search="woo*" > woocommerceoptions.txt --allow-root
    wp option set woocommerce_default_country "SK" --allow-root
    wp option set woocommerce_currency "EUR" --allow-root

    mkdir /var/www/html/wp-content/uploads/wc-logs --
    chown -R www-data:www-data /var/www/html 
    # this allows wc-logs to be writable
    chmod -R 744 /var/www/html/wp-content/uploads
    

    echo "WordPress setup complete!"
else
    echo "WordPress already configured. Skipping setup."
fi



# 3. Start PHP-FPM
exec php-fpm

Try adding user: www-data:www-data to your wp service in the compose file. But if the entrypoint tries to run anything that requires root, it won’t work.

If that is the case, you could add a new service that just runs only for syncing the data to a common volume with the wp service. So both would mount the “wordpress” volume.

  wpsync:
    user: www-data:www-data
    image: bash
    volumes:
      - wordpress:/var/www/html
    command:
      - tail
      - -f
      - /dev/null
    develop:
      watch:
        - action: sync
          path: ./wordpress
          target: /var/www/html

I haven’t tested it, but I hope you get the idea. And then you could remove the develop section from the “wp” service.

I tried and till now it seems to work adding:

user: www-data:www-data

in my wp: service/container