Posts tagged with “docker”

Docker Volumes in Production: A Practical Guide to Named Volumes vs Bind Mounts

When working with Docker containers in production, understanding volume management is crucial. This guide will help you make informed decisions about when to use named volumes versus bind mounts (directory mapping).

TL;DR

  • Use named volumes for persistent data (databases, application state)
  • Use bind mounts for config files and development
  • Combine both in production for optimal setup

Understanding the Basics

Named Volumes

volumes:
  - postgres_data:/var/lib/postgresql/data

Docker manages these volumes internally. Think of them as "black boxes" that Docker handles for you.

Bind Mounts (Directory Mapping)

volumes:
  - ./config:/etc/app/config

You manage these directories directly on your host machine.

When to Use What?

Use Named Volumes For:

  1. Database storage
  2. Application state
  3. Generated assets
  4. Any data that needs persistence but not direct access

Benefits:

  • Managed by Docker
  • Better performance
  • Automatic permissions handling
  • Easier backups
  • Portable across environments
  • Built-in volume management commands

Use Bind Mounts For:

  1. Configuration files
  2. Static files during development
  3. Source code in development
  4. Any files you need to edit from host

Benefits:

  • Direct access from host
  • Easy to edit
  • Version control friendly
  • Quick updates without container restart
  • Shareable across environments

Real-World Example

Here's a typical production setup combining both approaches:

version: '3'
services:
  db:
    image: postgres:15
    volumes:
      # Data persistence with named volume
      - postgres_data:/var/lib/postgresql/data
      # Configuration with bind mounts
      - ./config/postgres.conf:/etc/postgresql/postgresql.conf:ro

  nginx:
    image: nginx
    volumes:
      # Config files with bind mounts
      - ./config/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./config/nginx/conf.d:/etc/nginx/conf.d:ro
      # Static files with bind mount
      - ./static:/usr/share/nginx/html:ro

  app:
    image: node:18
    volumes:
      # Application data with named volume
      - app_data:/app/data
      # Config with bind mount
      - ./config/app.json:/app/config/app.json:ro

volumes:
  postgres_data:
  app_data:

Migration Tips

Moving from Bind Mounts to Named Volumes

If you're currently using bind mounts for data and want to switch to named volumes:

# Create new volume
docker volume create myapp_data

# Copy data
docker run --rm \
  -v /old/path:/source:ro \
  -v myapp_data:/destination \
  ubuntu \
  bash -c "cp -av /source/. /destination/"

Best Practices

  1. Named Volumes

    • Always use for persistent data
    • Name them descriptively
    • Regular backups
    • Don't manipulate directly on host
  2. Bind Mounts

    • Use read-only (:ro) when possible
    • Keep configs in version control
    • Use relative paths for portability
    • Store in a config/ directory
  3. General

    • Document your volume strategy
    • Regular backups for both types
    • Monitor disk usage
    • Use clear naming conventions

Common Pitfalls to Avoid

  1. Using bind mounts for database storage
  2. Hardcoding absolute paths
  3. Not setting proper permissions
  4. Forgetting to backup named volumes
  5. Direct manipulation of named volume directories

Conclusion

The key to successful Docker volume management is using the right tool for the job:

  • Named volumes for data that needs persistence
  • Bind mounts for configs and development
  • Combine both for a robust production setup

Remember: When in doubt, prefer named volumes for data and bind mounts for configuration.

[solution] mcr.microsoft.com/dotnet/aspnet:8.0-alpine couldn't recognize windows time zone ID

ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT false
RUN apk add --no-cache icu-libs tzdata

Reference

By the way, my devops colleague told me if you can, changing the windows time zone id with its standard equivalent is the more preferred way. He said "its not good to set that environment variable to false"

clean up docker networks/interfaces

docker network ls
then 
docker network rm networkname

My New Productivity Hacks

Muscle Memory Makeover

Docker just streamlined Docker Compose by integrating it as a plugin. Great news, but it means us old hats need to retrain our fingers. Here's a quick fix for your .bashrc to keep things smooth:

alias docker-compose='docker compose'

MySQL in a Flash

As a programmer and Linux admin, I juggle multiple MySQL servers with different group suffixes. Typing --defaults-group-suffix every time was a drag. This handy bash function saves the day:

m() {
  mysql --defaults-group-suffix=$1
}

Now, connecting to a database is as easy as:

m specific-suffix

This keeps your workflow concise and saves you precious keystrokes. Put them into you .bashrc or .zshrc now and let our life easier!

Seafile server configuration on CentOS 8

I am using the docker-compose version. The first problem I met was none of Seafile's concerns, it is actually a bug of docker. All of the containers cannot reach the internet (cannot resolve any DNS). The solution is at here.

After fixed the issue above, the Seafile server runs well on centos. However, there are still two issues that need to be addressed.

The first one is about the head icon of a user. It simply cannot display. You can easily found that the host part of the head icon is wrong. You need to edit "shared/seafile/conf/ccnet.conf" and change the SERVICE_URL to your real hostname in the [General] section.

The second one is similar, if you don't fix it, you cannot download any of the file you uploaded. This time, you need to edit "shared/seafile/conf/seahub_settings.py" and change the last line to "https://your.domain.name/seafhttp".