diff --git a/packages/envd/debug.Dockerfile b/packages/envd/debug.Dockerfile
index 54386c1f3..3b79abfe2 100644
--- a/packages/envd/debug.Dockerfile
+++ b/packages/envd/debug.Dockerfile
@@ -3,11 +3,22 @@ FROM golang:1.23
 ARG DEBIAN_FRONTEND=noninteractive
 
 RUN apt-get update
-RUN apt-get install systemd ca-certificates make python-is-python3 python3 nodejs chrony sudo -y
+RUN apt-get install systemd ca-certificates make python-is-python3 python3 nodejs npm chrony sudo -y
 
 RUN update-ca-certificates
 
+# Remove password for root.
+RUN passwd -d root
+
+# Create default user.
 RUN useradd -ms /bin/bash user
+RUN usermod -aG sudo user
+RUN passwd -d user
+RUN echo "user ALL=(ALL:ALL) NOPASSWD: ALL" >>/etc/sudoers
+
+RUN mkdir -p /home/user
+RUN chmod 777 -R /home/user
+RUN chmod 777 -R /usr/local
 
 RUN go install github.com/go-delve/delve/cmd/dlv@latest
 
diff --git a/packages/envd/internal/services/process/handler/handler.go b/packages/envd/internal/services/process/handler/handler.go
index e520aa2f4..fb7d070f7 100644
--- a/packages/envd/internal/services/process/handler/handler.go
+++ b/packages/envd/internal/services/process/handler/handler.go
@@ -44,7 +44,9 @@ type Handler struct {
 	cmd *exec.Cmd
 	tty *os.File
 
-	outWg *sync.WaitGroup
+	ctx    context.Context
+	cancel context.CancelFunc
+
 	stdin io.WriteCloser
 
 	DataEvent *MultiplexedChannel[rpc.ProcessEvent_Data]
@@ -56,7 +58,14 @@ func (p *Handler) Pid() uint32 {
 	return uint32(p.cmd.Process.Pid)
 }
 
-func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *zerolog.Logger, envVars *utils.Map[string, string]) (*Handler, error) {
+func New(
+	ctx context.Context,
+	user *user.User,
+	req *rpc.StartRequest,
+	logger *zerolog.Logger,
+	envVars *utils.Map[string, string],
+	cancel context.CancelFunc,
+) (*Handler, error) {
 	cmd := exec.CommandContext(ctx, req.GetProcess().GetCmd(), req.GetProcess().GetArgs()...)
 
 	uid, gid, err := permissions.GetUserIds(user)
@@ -104,6 +113,7 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 	cmd.Env = formattedVars
 
 	outMultiplex := NewMultiplexedChannel[rpc.ProcessEvent_Data](outputBufferSize)
+
 	var outWg sync.WaitGroup
 
 	if req.GetPty() != nil {
@@ -118,7 +128,6 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 		}
 
 		outWg.Add(1)
-
 		go func() {
 			defer outWg.Done()
 
@@ -155,7 +164,8 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 			tty:       tty,
 			Tag:       req.Tag,
 			DataEvent: outMultiplex,
-			outWg:     &outWg,
+			ctx:       ctx,
+			cancel:    cancel,
 			EndEvent:  NewMultiplexedChannel[rpc.ProcessEvent_End](0),
 			logger:    logger,
 		}, nil
@@ -174,7 +184,6 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 	outWg.Add(1)
 	go func() {
 		defer outWg.Done()
-
 		stdoutLogs := make(chan []byte, outputBufferSize)
 		defer close(stdoutLogs)
 
@@ -219,7 +228,6 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 	outWg.Add(1)
 	go func() {
 		defer outWg.Done()
-
 		stderrLogs := make(chan []byte, outputBufferSize)
 		defer close(stderrLogs)
 
@@ -256,13 +264,20 @@ func New(ctx context.Context, user *user.User, req *rpc.StartRequest, logger *ze
 		}
 	}()
 
+	go func() {
+		outWg.Wait()
+		close(outMultiplex.Source)
+		cancel()
+	}()
+
 	return &Handler{
 		Config:    req.GetProcess(),
 		cmd:       cmd,
 		stdin:     stdin,
 		Tag:       req.Tag,
 		DataEvent: outMultiplex,
-		outWg:     &outWg,
+		ctx:       ctx,
+		cancel:    cancel,
 		EndEvent:  NewMultiplexedChannel[rpc.ProcessEvent_End](0),
 		logger:    logger,
 	}, nil
@@ -273,6 +288,10 @@ func (p *Handler) SendSignal(signal syscall.Signal) error {
 		return fmt.Errorf("process not started")
 	}
 
+	if signal == syscall.SIGKILL || signal == syscall.SIGTERM {
+		p.cancel()
+	}
+
 	return p.cmd.Process.Signal(signal)
 }
 
@@ -335,14 +354,12 @@ func (p *Handler) Start() (uint32, error) {
 }
 
 func (p *Handler) Wait() {
-	p.outWg.Wait()
+	<-p.ctx.Done()
 
-	close(p.DataEvent.Source)
+	err := p.cmd.Wait()
 
 	p.tty.Close()
 
-	err := p.cmd.Wait()
-
 	var errMsg *string
 
 	if err != nil {
diff --git a/packages/envd/internal/services/process/signal.go b/packages/envd/internal/services/process/signal.go
index 9a89733ea..25994f8ac 100644
--- a/packages/envd/internal/services/process/signal.go
+++ b/packages/envd/internal/services/process/signal.go
@@ -11,7 +11,7 @@ import (
 )
 
 func (s *Service) SendSignal(ctx context.Context, req *connect.Request[rpc.SendSignalRequest]) (*connect.Response[rpc.SendSignalResponse], error) {
-	proc, err := s.getProcess(req.Msg.Process)
+	handler, err := s.getProcess(req.Msg.Process)
 	if err != nil {
 		return nil, err
 	}
@@ -26,7 +26,7 @@ func (s *Service) SendSignal(ctx context.Context, req *connect.Request[rpc.SendS
 		return nil, connect.NewError(connect.CodeUnimplemented, fmt.Errorf("invalid signal: %s", req.Msg.GetSignal()))
 	}
 
-	err = proc.SendSignal(signal)
+	err = handler.SendSignal(signal)
 	if err != nil {
 		return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("error sending signal: %w", err))
 	}
diff --git a/packages/envd/internal/services/process/start.go b/packages/envd/internal/services/process/start.go
index 5b7f06a95..0d24e9b5c 100644
--- a/packages/envd/internal/services/process/start.go
+++ b/packages/envd/internal/services/process/start.go
@@ -30,7 +30,8 @@ func (s *Service) InitializeStartProcess(ctx context.Context, user *user.User, r
 
 	handlerL := s.logger.With().Str(string(logs.OperationIDKey), ctx.Value(logs.OperationIDKey).(string)).Logger()
 
-	proc, err := handler.New(ctx, user, req, &handlerL, nil)
+	startProcCtx, startProcCancel := context.WithCancel(ctx)
+	proc, err := handler.New(startProcCtx, user, req, &handlerL, nil, startProcCancel)
 	if err != nil {
 		return err
 	}
@@ -77,11 +78,12 @@ func (s *Service) handleStart(ctx context.Context, req *connect.Request[rpc.Star
 
 	// Create a new context with a timeout if provided.
 	// We do not want the command to  be killed if the request context is cancelled
-	procCtx := context.Background()
+	procCtx, cancelProc := context.WithCancel(context.Background())
 	if timeout > 0 { // zero timeout means no timeout
-		procCtx, _ = context.WithTimeout(procCtx, timeout)
+		procCtx, cancelProc = context.WithTimeout(procCtx, timeout)
 	}
-	proc, err := handler.New(procCtx, u, req.Msg, &handlerL, s.envs)
+
+	proc, err := handler.New(procCtx, u, req.Msg, &handlerL, s.envs, cancelProc)
 	if err != nil {
 		return err
 	}