An open API service indexing awesome lists of open source software.

https://github.com/nazdridoy/nazdocker-lab

NazDocker Lab - Containerized dev environment with SSH & multi-user support
https://github.com/nazdridoy/nazdocker-lab

docker docker-compose lab linux playit-gg ssh ubuntu

Last synced: about 2 months ago
JSON representation

NazDocker Lab - Containerized dev environment with SSH & multi-user support

Awesome Lists containing this project

README

          

# NazDocker Lab

[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Docker](https://img.shields.io/badge/Docker-Required-blue.svg)](https://www.docker.com/)
[![Ubuntu](https://img.shields.io/badge/Ubuntu-24.04-orange.svg)](https://ubuntu.com/)
[![Alpine](https://img.shields.io/badge/Alpine-3.22-lightblue.svg)](https://alpinelinux.org/)
[![Documentation](https://img.shields.io/badge/Documentation-Complete-brightgreen.svg)](https://nazdridoy.github.io/nazdocker-lab/)

A secure, containerized development environment for educational and development purposes. This project provides a Docker-based lab environment with SSH access, multiple user accounts, and development tools, designed for learning, testing, and development workflows.

## ๐Ÿš€ Features

- **๐Ÿ” Multi-User Environment**: 6 pre-configured user accounts (admin + 5 regular users)
- **๐ŸŒ Public SSH Access**: Secure remote access via playit.gg tunneling
- **๐Ÿ› ๏ธ Development Tools**: Python 3.x, Node.js, Git, and essential utilities
- **๐Ÿ’พ Persistent Storage**: User data persists across container restarts with separate volumes for Alpine and Ubuntu
- **โš™๏ธ Runtime Configuration**: Environment-based configuration management
- **๐Ÿ”’ Security Focused**: Proper user isolation and SSH key support
- **๐Ÿ”‘ SSH Key Synchronization**: Shared SSH host keys between Alpine and Ubuntu containers
- **๐Ÿฅ Health Monitoring**: Built-in health checks for SSH service availability
- **๐Ÿ”๏ธ Alpine & Ubuntu Support**: Choose between lightweight Alpine (173MB) or full Ubuntu (968MB)

## ๐Ÿ“‹ Prerequisites

- [Docker](https://docs.docker.com/get-docker/) (version 20.10 or higher)
- [Docker Compose](https://docs.docker.com/compose/install/) (version 2.0 or higher)
- [Git](https://git-scm.com/downloads) for cloning the repository

## ๐Ÿƒโ€โ™‚๏ธ Quick Start

### 1. Clone the Repository
```bash
git clone https://github.com/nazdridoy/nazdocker-lab.git
cd nazdocker-lab
```

### 2. Set Up Environment
```bash
# Create separate data directories for Alpine and Ubuntu
mkdir -p data/{alpine,ubuntu}/{admin,user1,user2,user3,user4,user5}
mkdir -p logs/{alpine,ubuntu}

# Generate SSH host keys (optional - will be auto-generated if missing)
./scripts/manage-ssh-keys.sh generate

# Configure environment variables
cp .env.example .env
# Edit .env with your configuration
```

### 3. Start the Environment

Choose your preferred version:

**Ubuntu Version (Recommended for Development):**
```bash
docker-compose -f docker-compose.ubuntu.yml up -d
```

**Alpine Version (Recommended for Production - 82% smaller):**
```bash
docker-compose -f docker-compose.alpine.yml up -d
```

### 4. Access the Lab
```bash
# Local SSH access
ssh admin@localhost -p 2222
# Password: admin123
```

## ๐Ÿ‘ฅ User Accounts

| Username | Default Password | Sudo Access | Purpose |
|----------|------------------|-------------|---------|
| `admin` | `admin123` | โœ… Yes | Administrative tasks |
| `user1` | `user123` | โŒ No | Regular development |
| `user2` | `user123` | โŒ No | Regular development |
| `user3` | `user123` | โŒ No | Regular development |
| `user4` | `user123` | โŒ No | Regular development |
| `user5` | `user123` | โŒ No | Regular development |
| `root` | `root123` | โœ… Yes | System administration |

## ๐Ÿ”ง Configuration

### SSH Key Management

The lab environment uses shared SSH host keys between Alpine and Ubuntu containers to ensure consistent SSH connections:

```bash
# Generate new SSH host keys
./scripts/manage-ssh-keys.sh generate

# Check SSH key fingerprints
./scripts/manage-ssh-keys.sh check

# Backup SSH keys
./scripts/manage-ssh-keys.sh backup

# Restore SSH keys from backup
./scripts/manage-ssh-keys.sh restore backup/ssh-20231201-143022
```

**Benefits:**
- โœ… Same SSH host keys across both containers
- โœ… No SSH host key warnings when switching containers
- โœ… Centralized key management
- โœ… Easy key rotation and backup

### Environment Variables

The lab uses environment variables for secure configuration. Copy `.env.example` to `.env` and customize:

```bash
# Required: Playit.gg secret key for public access
PLAYIT_SECRET_KEY=your_playit_secret_key_here

# User passwords (change these!)
ADMIN_PASSWORD=your_admin_password_here
USER_PASSWORD=your_user_password_here
ROOT_PASSWORD=your_root_password_here

# Optional: SSH port mapping
SSH_PORT=2222
```

### Security Best Practices

- **Change default passwords** immediately after first login
- **Use SSH keys** instead of password authentication when possible
- **Never commit** your `.env` file to version control
- **SSH host keys are automatically ignored** by `.gitignore` for security
- **Regular updates** of the base image and installed packages

## ๐ŸŒ Remote Access

### Local Access
```bash
# SSH to any user
ssh admin@localhost -p 2222
ssh user1@localhost -p 2222
# ... etc
```

### Public Access via Playit.gg

The environment includes playit.gg tunneling for public SSH access:

1. **Configure playit.gg**: Set your secret key in `.env`
2. **Check tunnel status**: Monitor container logs for tunnel URL
3. **Connect remotely**: Use the provided public URL

```bash
# Check tunnel status
docker-compose -f docker-compose.ubuntu.yml logs lab-environment-ubuntu | grep -i "playit\|tunnel"

# Connect via public URL (example)
ssh admin@your-tunnel-url.playit.gg -p 12345
```

## ๐Ÿ› ๏ธ Available Tools

### Development Tools
- **Python 3.x** with pip package manager
- **uv** - Fast Python package manager (replaces pip, pip-tools, pipx, poetry, pyenv, virtualenv)
- **uvx** - Run Python tools in ephemeral environments
- **Node.js** with npm package manager
- **Git** for version control
- **SSH** server for remote access

### System Utilities
- **curl** for HTTP requests
- **jq** for JSON processing
- **ping** for network testing
- **ifconfig** for network configuration
- **apt** package manager (Ubuntu) / **apk** package manager (Alpine)

## ๐Ÿ“ Project Structure

```
nazdocker-lab/
โ”œโ”€โ”€ Dockerfile.ubuntu # Ubuntu container definition with health checks
โ”œโ”€โ”€ Dockerfile.alpine # Alpine container definition (189MB)
โ”œโ”€โ”€ start.sh # Cross-platform startup script
โ”œโ”€โ”€ docker-compose.ubuntu.yml # Ubuntu Docker Compose orchestration
โ”œโ”€โ”€ docker-compose.alpine.yml # Alpine Docker Compose orchestration
โ”œโ”€โ”€ .env.example # Environment variables template
โ”œโ”€โ”€ README.md # This file
โ”œโ”€โ”€ docs/ # Modular documentation
โ”œโ”€โ”€ LICENSE # GPL v3 license
โ”œโ”€โ”€ config/ # Configuration files
โ”‚ โ””โ”€โ”€ ssh/ # Shared SSH host keys (gitignored)
โ”‚ โ”œโ”€โ”€ ssh_host_rsa_key
โ”‚ โ”œโ”€โ”€ ssh_host_rsa_key.pub
โ”‚ โ”œโ”€โ”€ ssh_host_ecdsa_key
โ”‚ โ”œโ”€โ”€ ssh_host_ecdsa_key.pub
โ”‚ โ”œโ”€โ”€ ssh_host_ed25519_key
โ”‚ โ””โ”€โ”€ ssh_host_ed25519_key.pub
โ”œโ”€โ”€ scripts/ # Utility scripts
โ”‚ โ””โ”€โ”€ manage-ssh-keys.sh # SSH key management script
โ”œโ”€โ”€ data/ # Persistent user data (separated by container type)
โ”‚ โ”œโ”€โ”€ alpine/ # Alpine container data
โ”‚ โ”‚ โ”œโ”€โ”€ admin/ # Admin home directory (Alpine)
โ”‚ โ”‚ โ”œโ”€โ”€ user1/ # User1 home directory (Alpine)
โ”‚ โ”‚ โ”œโ”€โ”€ user2/ # User2 home directory (Alpine)
โ”‚ โ”‚ โ”œโ”€โ”€ user3/ # User3 home directory (Alpine)
โ”‚ โ”‚ โ”œโ”€โ”€ user4/ # User4 home directory (Alpine)
โ”‚ โ”‚ โ””โ”€โ”€ user5/ # User5 home directory (Alpine)
โ”‚ โ””โ”€โ”€ ubuntu/ # Ubuntu container data
โ”‚ โ”œโ”€โ”€ admin/ # Admin home directory (Ubuntu)
โ”‚ โ”œโ”€โ”€ user1/ # User1 home directory (Ubuntu)
โ”‚ โ”œโ”€โ”€ user2/ # User2 home directory (Ubuntu)
โ”‚ โ”œโ”€โ”€ user3/ # User3 home directory (Ubuntu)
โ”‚ โ”œโ”€โ”€ user4/ # User4 home directory (Ubuntu)
โ”‚ โ””โ”€โ”€ user5/ # User5 home directory (Ubuntu)
โ””โ”€โ”€ logs/ # Application logs (separated by container type)
โ”œโ”€โ”€ alpine/ # Alpine container logs
โ””โ”€โ”€ ubuntu/ # Ubuntu container logs
```

## ๐Ÿ”„ Development Workflow

### Ubuntu Version (Recommended for Development)
```bash
# Start Ubuntu environment
docker-compose -f docker-compose.ubuntu.yml up -d

# SSH into lab
ssh admin@localhost -p 2222

# Develop in your persistent home directory
# Install packages: sudo apt-get install (admin only)

# Use uv for Python development
uv init myproject # Create new Python project
uv add requests # Add dependency
uv run myproject/main.py # Run Python script
uvx ruff check # Run linter in ephemeral environment

# Stop when done
docker-compose -f docker-compose.ubuntu.yml down
```

### Alpine Version (Recommended for Production)
```bash
# Start Alpine environment (82% smaller)
docker-compose -f docker-compose.alpine.yml up -d

# SSH into lab (same commands)
ssh admin@localhost -p 2222

# Develop in your persistent home directory
# Install packages: sudo apk add (admin only)

# Use uv for Python development
uv init myproject # Create new Python project
uv add requests # Add dependency
uv run myproject/main.py # Run Python script
uvx ruff check # Run linter in ephemeral environment

# Stop when done
docker-compose -f docker-compose.alpine.yml down
```

### Building Images
```bash
# Build Ubuntu image
docker-compose -f docker-compose.ubuntu.yml build

# Build Alpine image
docker-compose -f docker-compose.alpine.yml build

# Build both images
docker-compose -f docker-compose.ubuntu.yml build && docker-compose -f docker-compose.alpine.yml build
```

### Running Both Containers Simultaneously

With separate volumes, you can run both Alpine and Ubuntu containers at the same time:

```bash
# Start both environments
docker-compose -f docker-compose.ubuntu.yml up -d
docker-compose -f docker-compose.alpine.yml up -d

# Access Ubuntu lab (port 2222)
ssh admin@localhost -p 2222

# Access Alpine lab (port 2223 - you'll need to modify SSH_PORT in .env)
ssh admin@localhost -p 2223

# Both containers use the same SSH host keys, so no key warnings when switching
# Stop both environments
docker-compose -f docker-compose.ubuntu.yml down
docker-compose -f docker-compose.alpine.yml down
```

## ๐Ÿ›ก๏ธ Security Considerations

### Default Configuration
- All users have password authentication enabled
- SSH keys are not configured by default
- Default passwords should be changed immediately

### Recommended Security Measures
1. **Change all default passwords** after first login
2. **Configure SSH key authentication** for better security
3. **Use strong, unique passwords** for each user
4. **Regular security updates** of the base image
5. **Monitor access logs** for suspicious activity

## ๐Ÿฅ Health Monitoring

Both Ubuntu and Alpine versions include built-in health checks that monitor SSH service availability:

- **Health Check Interval**: 30 seconds
- **Timeout**: 10 seconds per check
- **Start Period**: 40 seconds grace period after container startup
- **Retries**: 3 consecutive failures before marking as unhealthy

### Health Status
- **Healthy**: SSH service is running and accepting connections
- **Unhealthy**: SSH service is stopped or not responding
- **Starting**: Container is in the grace period after startup

### Monitoring Health Status
```bash
# Check container health status
docker ps

# View detailed health information
docker inspect student-lab-ubuntu | grep -A 20 "Health"

# Monitor health check logs
docker inspect student-lab-ubuntu | grep -A 10 "Healthcheck"
```

## ๐Ÿ’พ Volume Management

### Separate Volume Structure

The lab environment uses separate volumes for Alpine and Ubuntu containers to ensure complete isolation and prevent data conflicts:

```
data/
โ”œโ”€โ”€ alpine/ # Alpine container data
โ”‚ โ”œโ”€โ”€ admin/ # Admin user data (Alpine)
โ”‚ โ”œโ”€โ”€ user1/ # User1 data (Alpine)
โ”‚ โ”œโ”€โ”€ user2/ # User2 data (Alpine)
โ”‚ โ”œโ”€โ”€ user3/ # User3 data (Alpine)
โ”‚ โ”œโ”€โ”€ user4/ # User4 data (Alpine)
โ”‚ โ””โ”€โ”€ user5/ # User5 data (Alpine)
โ””โ”€โ”€ ubuntu/ # Ubuntu container data
โ”œโ”€โ”€ admin/ # Admin user data (Ubuntu)
โ”œโ”€โ”€ user1/ # User1 data (Ubuntu)
โ”œโ”€โ”€ user2/ # User2 data (Ubuntu)
โ”œโ”€โ”€ user3/ # User3 data (Ubuntu)
โ”œโ”€โ”€ user4/ # User4 data (Ubuntu)
โ””โ”€โ”€ user5/ # User5 data (Ubuntu)

logs/
โ”œโ”€โ”€ alpine/ # Alpine container logs
โ””โ”€โ”€ ubuntu/ # Ubuntu container logs
```

### Benefits of Separate Volumes

- **๐Ÿ”’ Complete Isolation**: Alpine and Ubuntu containers have completely separate data storage
- **๐Ÿš€ Concurrent Operation**: Both container types can run simultaneously without conflicts
- **๐Ÿ“ฆ Easy Management**: Backup, restore, or manage data for each container type separately
- **๐Ÿงน Clean Organization**: Clear separation makes it obvious which data belongs to which container
- **๐Ÿ”„ Independent Scaling**: Scale Alpine and Ubuntu environments independently

### Volume Usage

- **Alpine Container**: Stores data in `./data/alpine/` and logs in `./logs/alpine/`
- **Ubuntu Container**: Stores data in `./data/ubuntu/` and logs in `./logs/ubuntu/`

## ๐Ÿ”๏ธ Alpine vs Ubuntu Comparison

### Image Size Comparison
| Version | Base Image | Final Size | Size Reduction |
|---------|------------|------------|----------------|
| **Ubuntu** | `ubuntu:24.04` | 1.05GB | - |
| **Alpine** | `alpine:3.22` | 189MB | **82% smaller** |

### When to Use Each Version

**Use Alpine When:**
- Resource constraints are a concern
- Fast deployments are needed
- Security is a priority
- Production environments where size matters

**Use Ubuntu When:**
- Maximum compatibility is needed
- Familiar environment is preferred
- Specific Ubuntu packages are required
- Development/testing environments

### Key Differences
- **Package Management**: `apt` (Ubuntu) vs `apk` (Alpine)
- **Service Management**: `service` (Ubuntu) vs direct commands (Alpine)
- **User Groups**: `sudo` (Ubuntu) vs `wheel` (Alpine)
- **Build Time**: Alpine builds ~50% faster
- **Startup Time**: Alpine starts ~30% faster
- **SSH Keys**: Both containers use identical SSH host keys for consistency

### Resource Limits
Both versions are configured with optimized resource limits:
- **CPU**: Maximum 2 cores, minimum 1 core reserved
- **Memory**: Maximum 2GB, minimum 1GB reserved
- **Network**: Standard bridge networking
- **Storage**: Persistent volumes for user data

## ๐Ÿ“š Documentation

- **[Documentation Index](docs/index.md)**: Complete modular documentation
- **[Quick Start Guide](docs/getting-started/quick-start.md)**: Get up and running in minutes
- **[Project Structure](docs/getting-started/project-structure.md)**: Complete project overview
- **[Container Management](docs/administration/container-management.md)**: Docker container operations
- **[User Management](docs/user-management/user-accounts.md)**: User account management
- **[Remote Access](docs/remote-access/ssh-access.md)**: SSH access and tunneling
- **[Troubleshooting](docs/troubleshooting/common-issues.md)**: Common issues and solutions
- **[Docker Documentation](https://docs.docker.com/)**: Docker basics
- **[SSH Documentation](https://www.openssh.com/manual.html)**: SSH configuration

## ๐Ÿค Contributing

We welcome contributions! Please see our contributing guidelines:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Setup
```bash
# Clone your fork
git clone https://github.com/your-username/nazdocker-lab.git
cd nazdocker-lab

# Add upstream remote
git remote add upstream https://github.com/nazdridoy/nazdocker-lab.git

# Create feature branch
git checkout -b feature/your-feature-name
```

## ๐Ÿ› Troubleshooting

### Common Issues

**Container won't start:**
```bash
# Check logs
docker-compose logs

# Validate configuration
docker-compose config
```

**SSH connection refused:**
```bash
# Check container status
docker-compose ps

# Check SSH service
docker-compose -f docker-compose.ubuntu.yml exec lab-environment-ubuntu service ssh status
```

**Environment variables not loading:**
```bash
# Verify .env file exists
ls -la .env

# Check variable resolution
docker-compose config | grep -E "(PLAYIT_SECRET_KEY|ADMIN_PASSWORD)"
```

For more detailed troubleshooting, see [Troubleshooting Guide](docs/troubleshooting/common-issues.md).

## ๐Ÿ“„ License

This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.

## ๐Ÿ™ Acknowledgments

- [Docker](https://www.docker.com/) for containerization technology
- [Ubuntu](https://ubuntu.com/) for the base operating system
- [Playit.gg](https://playit.gg/) for tunneling services
- [OpenSSH](https://www.openssh.com/) for secure shell access

## ๐Ÿ“ž Support

- **Issues**: [GitHub Issues](https://github.com/nazdridoy/nazdocker-lab/issues)
- **Discussions**: [GitHub Discussions](https://github.com/nazdridoy/nazdocker-lab/discussions)
- **Documentation**: [Documentation Index](docs/index.md)

---

**Note**: This is a development and educational tool. Always follow security best practices and change default credentials before use in production environments.