6.4 KiB
Okay, you want both Nginx and SSHD running in a single container using your provided Dockerfile as a base. The best and most robust way to achieve this is by using a process manager like Supervisord.
Here's how to modify your Dockerfile and add the necessary configuration files to make that happen.
Reasoning for Supervisord:
- PID 1 Management: Docker expects the
CMDorENTRYPOINTprocess to be PID 1. If that process exits, the container exits. Supervisord runs as PID 1 and then manages Nginx and SSHD as its child processes, ensuring the container stays alive even if one of the managed services briefly stops (Supervisord will restart it). - Foreground Execution: Both Nginx and SSHD need to be told to run in the foreground when managed by Supervisord.
Step 1: Create supervisord.conf
Create a file named supervisord.conf in the same directory as your Dockerfile. This file tells Supervisord which processes to run and how to manage them.
supervisord.conf content:
[supervisord]
nodaemon=true ; Prevents supervisord from detaching, keeping it in the foreground for Docker
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;" ; Command to start Nginx in the foreground
autostart=true ; Start Nginx when supervisord starts
autorestart=true ; Restart Nginx if it crashes
stdout_logfile=/var/log/supervisor/%(program_name)s.log ; Log Nginx's stdout
stderr_logfile=/var/log/supervisor/%(program_name)s.log ; Log Nginx's stderr
[program:sshd]
command=/usr/sbin/sshd -D ; Command to start SSHD in the foreground
autostart=true
autorestart=true
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
Step 2: Modify Your Dockerfile
Now, update your Dockerfile to install Supervisord, Nginx, and OpenSSH Server, and then configure them.
Your Dockerfile content:
FROM ubuntu:questing
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /
COPY /provision /
# Run your provisioning script.
# ENSURE THIS SCRIPT DOES NOT TRY TO START NGINX or SSHD as SERVICES.
# It should only handle installation and configuration.
RUN bash provision.bash
## Install necessary packages: Nginx, OpenSSH Server, and Supervisord
## Also, ensure the SSH run directory exists and set up basic SSH config for key auth.
RUN apt-get update && \
apt-get install -y nginx openssh-server supervisor && \
rm -rf /var/lib/apt/lists/* && \
mkdir -p /var/run/sshd && \
sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config && \
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config && \
sed -i 's/UsePAM yes/UsePAM no/' /etc/ssh/sshd_config
# If you want to allow root login via SSH (not recommended for production but common in dev containers)
# RUN sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
# --- IMPORTANT: SSH Key Setup ---
# This is crucial for key-based login. Add your public key to authorized_keys for the user you intend to log in as.
# For 'root' user (common in simple containers for convenience, but be aware of security implications):
# For a non-root user, replace /root with /home/youruser
RUN mkdir -p /root/.ssh && \
chmod 700 /root/.ssh && \
# Replace 'ssh-rsa AAAA...' with your actual public key content
# It's better to COPY the key from your build context if it's dynamic
echo "ssh-rsa YOUR_PUBLIC_KEY_CONTENT_HERE your_username@your_machine" >> /root/.ssh/authorized_keys && \
chmod 600 /root/.ssh/authorized_keys
# Copy the Supervisord configuration file into the container
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
# Expose the ports for SSH (22) and Nginx (80)
EXPOSE 22
EXPOSE 80
# The CMD instruction now runs Supervisord, which will manage Nginx and SSHD
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
Important Considerations for your provision.bash:
- Your
provision.bashscript should install Nginx andopenssh-server, but it must not attempt to start them usingserviceorsystemctlor any other method that leaves them running in the background. Their startup will be handled by Supervisord. - If your
provision.bashalready handles SSH key setup (creating.sshandauthorized_keys), make sure it sets the correct permissions (700for.sshand600forauthorized_keys). If not, theRUNcommands in the Dockerfile above will do it for therootuser. Remember to replace"ssh-rsa YOUR_PUBLIC_KEY_CONTENT_HERE your_username@your_machine"with your actual public key!
Step 3: Build and Run Your Docker Container
- Save the files: Ensure
Dockerfileandsupervisord.confare in the same directory. - Build the image:
docker build -t my-nginx-ssh-box . - Run the container:
docker run -d \ -p 80:80 \ -p 2222:22 \ --name my-nginx-ssh \ my-nginx-ssh-box-d: Runs the container in detached (background) mode.-p 80:80: Maps host port 80 to container port 80 (for Nginx).-p 2222:22: Maps host port 2222 to container port 22 (for SSH). Using2222on the host avoids conflicts if your host machine is already using port 22 for its own SSH server. You can change2222to22if host port 22 is free.--name my-nginx-ssh: Gives your container a memorable name.
Step 4: Verify
-
Check if the container is running:
docker psYou should see
my-nginx-sshlisted with status "Up". -
Check Nginx: Open your web browser and navigate to
http://localhost/(orhttp://your_docker_host_ip/). You should see the Nginx welcome page or whatever your Nginx configuration serves. -
Check SSH: From your local machine's terminal (where your private key is located):
ssh -i ~/.ssh/id_rsa root@localhost -p 2222(Replace
id_rsaif your private key has a different name, androotif you set up SSH for a different user. Uselocalhostif running Docker locally, otherwise your Docker host's IP.)You should be able to log in without a password (if the key setup is correct and you used a key without a passphrase, or after entering your passphrase).
This setup will ensure both Nginx and SSHD are running concurrently within your single Docker container, managed by Supervisord.