Overlaying Files in Docker Containers
Overlaying a file in a Docker container allows you to replace a file inside the container with your own custom version. This is useful when you need to customize configuration files, such as settings.yml, without modifying the Docker image itself.
Overview
File overlaying uses Docker bind mounts to replace files in the container with files from your host system. This technique is particularly useful for:
- Custom configuration files - Override default
settings.ymlwith your own settings - Custom themes - Replace theme files or assets
- Custom scripts - Override application scripts with custom versions
- Testing configurations - Test different configurations without rebuilding images
Important: When you overlay a file, the host file completely replaces the container file. Changes to the host file are immediately reflected in the container (and vice versa). The original container file is no longer accessible.
Common Use Case: Overlaying settings.yml
The most common use case is overlaying the settings.yml configuration file to customize Password Pusher settings.
Download Default Configuration
Before creating your custom configuration, download the default settings.yml file:
Modify it to your needs, then mount it into the container.
File Location in Container
Inside the Password Pusher Docker container:
- Configuration file:
/opt/PasswordPusher/config/settings.yml - Application root:
/opt/PasswordPusher/
Using Docker Compose (Recommended)
If you’re using docker-compose.yml, add a bind mount to the volumes section:
services:
pwpush:
image: docker.io/pglombardo/pwpush:stable
volumes:
# Overlay settings.yml with custom configuration
- type: bind
source: /path/to/your/settings.yml
target: /opt/PasswordPusher/config/settings.yml
# Other volumes (database, storage, etc.)
- pwpush-storage:/opt/PasswordPusher/storage
ports:
- "80:80"
- "443:443"
Using relative paths:
If your settings.yml is in the same directory as docker-compose.yml:
services:
pwpush:
image: docker.io/pglombardo/pwpush:stable
volumes:
- type: bind
source: ./settings.yml
target: /opt/PasswordPusher/config/settings.yml
read_only: true # Optional: prevent container from modifying the file
Note: The read_only: true option prevents the container from modifying the file, which is recommended for configuration files.
Using Docker Run
If you’re using docker run directly, use the --mount option:
docker run -d \
--name pwpush \
--mount type=bind,source=/path/to/your/settings.yml,target=/opt/PasswordPusher/config/settings.yml,readonly \
-p "80:80" \
-p "443:443" \
-v pwpush-storage:/opt/PasswordPusher/storage \
pglombardo/pwpush:stable
Command Breakdown
docker run -d: Runs the container in detached mode (background)--mount type=bind,source=...,target=...,readonly: Creates a bind mounttype=bind: Specifies a bind mount (host file/directory)source=/path/to/your/settings.yml: Path to your file on the hosttarget=/opt/PasswordPusher/config/settings.yml: Path inside the containerreadonly: Optional - prevents container from modifying the file
-p "80:80" -p "443:443": Maps container ports to host portspglombardo/pwpush:stable: The Docker image to use
How It Works
When you use a bind mount to overlay a file:
- File Replacement: The host file completely replaces the container file at the target path
- Bidirectional Sync: Changes to the host file are immediately visible in the container
- Persistence: The overlay persists across container restarts (as long as the host file exists)
- Original File: The original container file is no longer accessible
Example Flow:
Host: /home/user/custom-settings.yml
↓ (bind mount)
Container: /opt/PasswordPusher/config/settings.yml
Any changes to /home/user/custom-settings.yml on the host are immediately reflected in the container at /opt/PasswordPusher/config/settings.yml.
Other Files You Can Overlay
While settings.yml is the most common, you can overlay other files as well:
Custom Themes
volumes:
- type: bind
source: ./custom-theme.css
target: /opt/PasswordPusher/app/assets/stylesheets/custom.css
Custom Scripts
volumes:
- type: bind
source: ./custom-script.sh
target: /opt/PasswordPusher/bin/custom-script.sh
Custom Locale Files
volumes:
- type: bind
source: ./config/locales/custom.yml
target: /opt/PasswordPusher/config/locales/custom.yml
Warning: Overlaying application code files may break functionality or cause issues during upgrades. Only overlay files you understand and have tested.
Best Practices
File Paths
- Use absolute paths for clarity and reliability
- Use relative paths (relative to
docker-compose.yml) for portability - Verify paths exist before starting the container
File Permissions
- Ensure the host file has appropriate read permissions
- Use
read_only: truefor configuration files to prevent accidental modifications - Check that the container user can read the file
Version Control
- Keep your custom configuration files in version control (Git)
- Document why you’re overlaying specific files
- Test changes in a development environment first
Configuration Priority
Remember: Environment variables always take precedence over settings.yml. If you set both, environment variables will override the YAML file values.
For more information, see Configuration Strategies.
Backup Original Files
Before overlaying, you may want to extract the original file from the container:
# Extract original settings.yml
docker create --name temp-container pglombardo/pwpush:stable
docker cp temp-container:/opt/PasswordPusher/config/settings.yml ./original-settings.yml
docker rm temp-container
Troubleshooting
File Not Found
Symptoms: Container fails to start or file doesn’t appear in container.
Solutions:
- Verify source path exists:
ls -la /path/to/your/settings.yml - Check path is absolute (for Docker Run):
# Use absolute path docker run ... --mount type=bind,source=$(pwd)/settings.yml,... - Verify file permissions:
chmod 644 /path/to/your/settings.yml
Container Won’t Start
Symptoms: Container exits immediately after starting.
Solutions:
- Check container logs:
docker compose logs pwpush # or docker logs <container_id> - Verify YAML syntax (for settings.yml):
# Test YAML syntax python3 -c "import yaml; yaml.safe_load(open('settings.yml'))" - Check file encoding: Ensure the file uses UTF-8 encoding
Changes Not Reflecting
Symptoms: Changes to host file don’t appear in container.
Solutions:
- Restart the container:
docker compose restart pwpush - Check mount is active:
docker compose exec pwpush ls -la /opt/PasswordPusher/config/settings.yml - Verify file is actually mounted:
docker compose exec pwpush cat /opt/PasswordPusher/config/settings.yml | head -5
Permission Denied
Symptoms: Container can’t read the overlaid file.
Solutions:
- Check file permissions:
ls -la /path/to/your/settings.yml - Make file readable:
chmod 644 /path/to/your/settings.yml - Check SELinux/AppArmor (if applicable):
# For SELinux chcon -Rt svirt_sandbox_file_t /path/to/your/settings.yml
Complete Example
Here’s a complete docker-compose.yml example with a custom settings.yml overlay:
services:
pwpush:
image: docker.io/pglombardo/pwpush:stable
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
# Overlay custom settings.yml
- type: bind
source: ./config/settings.yml
target: /opt/PasswordPusher/config/settings.yml
read_only: true
# Persistent storage
- pwpush-storage:/opt/PasswordPusher/storage
environment:
PWPUSH_MASTER_KEY: 'your-encryption-key-here'
TLS_DOMAIN: 'pwpush.example.com'
volumes:
pwpush-storage:
Directory structure:
.
├── docker-compose.yml
├── config/
│ └── settings.yml (your custom configuration)
└── ...
See Also
- Configuration Strategies - Comprehensive guide to configuring Password Pusher
- Docker Compose Setup - Docker Compose installation guide
- Environment Variables - Alternative configuration method
- settings.yml Reference - Complete settings file with all options