When automating Docker container management, you often need to programmatically set the root password. While Docker best practices suggest baking credentials into images, sometimes you need runtime password changes - especially for SSH containers.
The
sshpass
method you tried faces multiple issues:
- SSH servers often block password changes over SSH for security
- The
passwd
command expects interactive terminal input- Container networking might not be ready when your script runs
1. Using Docker Exec with chpasswd
The most robust solution using
docker exec
:# Single command version docker exec -i container_name bash -c \ "echo 'root:NEWPASSWORD' | chpasswd" # Alternative with password confirmation docker exec -i container_name bash -c \ "echo -e 'NEWPASSWORD\\nNEWPASSWORD' | passwd root"2. During Container Startup
Modify your docker run command:
docker run -d --name my_container \ -e ROOT_PASSWORD=mysecurepass \ my_image /bin/bash -c \ "echo root:\$ROOT_PASSWORD | chpasswd && /usr/sbin/sshd -D"3. Using Dockerfile (For Build-Time)
Though you prefer runtime changes, here's the Dockerfile approach for completeness:
FROM ubuntu:latest RUN apt-get update && apt-get install -y openssh-server RUN echo 'root:INITIALPASS' | chpasswd COPY setpassword.sh / RUN chmod +x /setpassword.sh ENTRYPOINT ["/setpassword.sh"]
- Always verify container is running before executing commands
- Use
docker logs
to check for errors- Consider adding sleep before commands if containers boot slowly
- For production, use SSH keys instead of password authentication
When implementing this:
- Never hardcode passwords in scripts
- Use environment variables or secrets management
- Rotate passwords regularly
- Consider disabling root SSH access entirely
When automating Docker container management, you might need to change the root password programmatically. While the Docker way suggests baking credentials into the image, sometimes you need runtime password changes - especially when dealing with SSH-enabled containers.
The common SSH approach:
sshpass -p 'OLDPASS' ssh root@container-IP 'echo -e "NEWPASS\\nNEWPASS" | passwd root'
often fails because:
- passwd expects interactive terminal input
- SSH might not be fully configured when the command runs
- Password complexity requirements may block non-interactive changes
Here are more reliable Docker-native methods:
Method 1: Using docker exec
docker exec -i container_id bash -c "echo -e 'NEWPASS\\nNEWPASS' | passwd root"
Method 2: Using chpasswd
docker exec -i container_id bash -c "echo 'root:NEWPASS' | chpasswd"
Method 3: During Container Creation
docker run -d --name my_container \
-e ROOT_PASS="NEWPASS" \
my_image /bin/bash -c "echo 'root:$ROOT_PASS' | chpasswd && /usr/sbin/sshd -D"
When you must handle interactive prompts:
docker exec -i container_id bash -c "expect -c 'spawn passwd root; expect \"New password:\"; send \"NEWPASS\\r\"; expect \"Retype new password:\"; send \"NEWPASS\\r\"; interact'"
- Never store plaintext passwords in scripts
- Use Docker secrets for production environments
- Consider SSH key authentication instead of password login
- Implement password rotation policies
For production, consider building images with pre-configured credentials:
FROM ubuntu
RUN echo 'root:$6$salt$hashedpass' > /etc/shadow
Use openssl to generate proper shadow entries:
openssl passwd -6 -salt xyz yourpassword