A clean, isolated Ubuntu 24.04 development environment with SSH access, Docker CLI, and Docker Compose v2 integration for Synology NAS.
- Ubuntu 24.04 LTS base image
- SSH-only authentication (no passwords)
- Docker CLI + Compose v2 with host socket passthrough
- User identity mirroring (UID/GID matching Synology user)
- GitHub Actions CI/CD for automated builds
- GHCR image distribution (no local builds needed)
The devshell runs on your Synology NAS but is built externally via GitHub Actions to avoid CPU/resource constraints on the DS220+.
GitHub Push → Actions Build → GHCR Push → NAS Pull → Container Start
- Fork or create this repository
- Enable GitHub Actions
- GitHub Container Registry is automatically available with
GITHUB_TOKEN
-
Get Docker socket GID:
stat -c %g /var/run/docker.sock
-
Create SSH keys directory:
mkdir -p /volume1/docker/stacks/devshell/ssh
-
Add your public SSH key:
cat ~/.ssh/id_ed25519.pub >> /volume1/docker/stacks/devshell/ssh/authorized_keys chmod 600 /volume1/docker/stacks/devshell/ssh/authorized_keys
ssh msn0624c@ngaged.synology.me -p 54321
cd /volume1/docker/stacks
mkdir -p devshell/ssh
cd devshellUse the provided docker-compose.yml file from this repository.
nano .envAdd:
USERNAME=msn0624c
USER_UID=1026
USER_GID=100
ADMIN_GID=101
DOCKER_GID=999 # Use the value from stat command above
GITHUB_USERNAME=YOUR_GITHUB_USERNAME# Pull latest image from GHCR
docker compose pull
# Start container
docker compose up -d
# Check logs
docker compose logs -fSet up DNS record for external access:
- Type: A record
- Name:
devshell.nsystems.live - Value: Your WAN IP
- Proxy: OFF (DNS only)
Forward external port 22 to NAS internal port 2222:
- External: Port 22
- Internal: Port 2222 → 192.168.0.164
ssh msn0624c@devshell.nsystems.livessh -p 2222 msn0624c@192.168.0.164Add to ~/.ssh/config:
Host devshell
HostName devshell.nsystems.live
User msn0624c
Port 22
Host devshell-lan
HostName 192.168.0.164
User msn0624c
Port 2222
When you push changes to the GitHub repository:
- GitHub Actions automatically builds new image
- Image is pushed to GHCR with
:latestand:sha-xxxxxtags - On NAS, pull and restart:
cd /volume1/docker/stacks/devshell
docker compose pull
docker compose up -ddocker compose logs devshelldocker exec devshell docker psdocker exec devshell cat /etc/ssh/sshd_configdocker exec devshell id msn0624c
docker exec devshell groups msn0624cdocker exec devshell ls -la /home/msn0624c/.ssh/- No password authentication - SSH keys only
- No root login - Root SSH access disabled
- Passwordless sudo - User has sudo without password (trust-based)
- Docker socket access - User can control host Docker (intentional for dev environment)
devshell/
├── .github/
│ └── workflows/
│ └── build-and-push.yml # CI/CD workflow
├── Dockerfile # Container image definition
├── entrypoint.sh # Runtime configuration script
├── docker-compose.yml # NAS deployment configuration
├── .env.example # Environment variables template
└── README.md # This file
# On NAS:
/volume1/docker/stacks/devshell/
├── docker-compose.yml
├── .env
└── ssh/
└── authorized_keys # Your SSH public keys
MIT