Skip to main content
Wecode uses Docker containers to safely execute and test submitted code. This ensures isolation between submissions and protects the host system.

Prerequisites

Docker Installation

Install Docker on your system:
sudo apt-get update
sudo apt-get install docker.io
sudo systemctl start docker
sudo systemctl enable docker
Verify Docker installation:
docker --version

User Permissions

Adding www-data to Docker Group

The web server user (typically www-data) needs permission to run Docker containers.
sudo usermod -aG docker www-data
Adding a user to the docker group grants significant privileges. This user can effectively gain root access to the host system. Only do this on systems dedicated to running Wecode.

Verify Group Membership

Check that the user was added successfully:
groups www-data
You should see docker listed in the output.

Restart Services

After adding the user to the docker group, restart the web server:
sudo systemctl restart apache2

Docker Container Configuration

Required Images

Wecode needs Docker images for different programming languages. Pull the necessary images:
# Example: Pull common language images
docker pull gcc:latest          # For C/C++
docker pull python:3.11         # For Python
docker pull openjdk:17          # For Java
docker pull node:18             # For JavaScript

Custom Images

You may need to create custom Docker images with specific compilers or libraries:
Dockerfile
FROM gcc:latest

# Install additional tools
RUN apt-get update && apt-get install -y \
    valgrind \
    gdb \
    && rm -rf /var/lib/apt/lists/*

# Set working directory
WORKDIR /app

# Set resource limits
USER nobody
Build the custom image:
docker build -t wecode-cpp:latest .

Testing Docker Setup

Basic Connectivity Test

Test that Docker is accessible:
docker ps

Run Test Container

Test running a simple container:
docker run --rm hello-world

Test as Web Server User

Switch to the web server user and test Docker access:
sudo -u www-data docker ps
If this fails with a permission error, the user group changes haven’t taken effect. Restart the web server or reboot the system.

Test Code Execution

Test executing code in a container:
echo 'print("Hello, World!")' > test.py
docker run --rm -v $(pwd):/app -w /app python:3.11 python test.py
You should see Hello, World! in the output.

Security Considerations

Docker container security is critical when running untrusted code. Follow these guidelines:

Resource Limits

Always set resource limits when running containers:
docker run \
  --rm \
  --memory="256m" \
  --memory-swap="256m" \
  --cpus="1.0" \
  --pids-limit=50 \
  --network=none \
  -v /path/to/code:/app:ro \
  -w /app \
  python:3.11 python script.py
Resource limit options:
  • --memory - Maximum memory usage
  • --memory-swap - Maximum swap usage (set equal to memory to disable swap)
  • --cpus - Number of CPU cores
  • --pids-limit - Maximum number of processes
  • --network=none - Disable network access

Read-Only Mounts

Mount source code as read-only:
-v /path/to/code:/app:ro

Non-Root User

Run containers as a non-root user:
docker run --user nobody ...

Timeout Enforcement

Always enforce timeouts for code execution:
timeout 30s docker run ...

No Privileged Containers

Never use --privileged flag when running untrusted code:
# NEVER do this:
docker run --privileged ...  # DANGEROUS!

Disable Capabilities

Drop unnecessary Linux capabilities:
docker run --cap-drop=ALL ...

Storage Management

Clean Up Old Containers

Regularly clean up stopped containers:
docker container prune -f

Clean Up Old Images

Remove unused images:
docker image prune -a -f

Automated Cleanup

Set up a cron job for regular cleanup:
# Add to crontab
0 2 * * * docker system prune -a -f

Monitoring

Check Running Containers

docker ps

View Container Logs

docker logs <container_id>

Monitor Resource Usage

docker stats

Troubleshooting

Permission Denied

Problem: permission denied while trying to connect to the Docker daemon socket Solution:
  1. Verify the user is in the docker group: groups www-data
  2. Restart the web server: sudo systemctl restart apache2
  3. If still failing, reboot the system

Docker Daemon Not Running

Problem: Cannot connect to the Docker daemon Solution:
sudo systemctl start docker
sudo systemctl enable docker

Container Timeout

Problem: Containers hang or don’t stop Solution:
  • Force kill hung containers: docker kill <container_id>
  • Set explicit timeouts: timeout 30s docker run ...

Disk Space Issues

Problem: No space left on device Solution:
# Check Docker disk usage
docker system df

# Clean up unused resources
docker system prune -a -f --volumes

Installation Script Reference

From install.sh, the Docker setup is handled during the installation process:
# Composer installation (line 50-53)
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"

# Install dependencies (line 57)
php composer.phar install
The setup.sh script clones the repository and runs the installation:
# Clone Wecode repository (line 94)
git clone 'https://github.com/truongan/wecode' .

Best Practices

  1. Isolation: Always run code in isolated containers with no network access
  2. Resource Limits: Set strict CPU, memory, and process limits
  3. Timeouts: Enforce maximum execution time for all submissions
  4. Monitoring: Regularly monitor Docker resource usage
  5. Updates: Keep Docker and images up to date with security patches
  6. Cleanup: Implement automated cleanup of old containers and images
  7. Testing: Regularly test the Docker setup with sample submissions
  8. Logs: Monitor Docker logs for suspicious activity

Build docs developers (and LLMs) love