서버에서 디렉터리를 만들었는데 애플리케이션이 파일을 저장하지 못하거나, 분명 만들었다고 생각한 폴더가 원하는 위치에 없는 경우가 있습니다. 이 글은 mkdir로 폴더 만드는 방법 자체뿐 아니라, 실제 운영 환경에서 자주 함께 터지는 경로 착각, 부모 디렉터리 누락, 권한 거부, 소유자 불일치 문제를 순서대로 확인하는 방법을 다룹니다.
이 글에서 해결할 문제
mkdir 명령어는 간단합니다. 하지만 VPS나 Debian/Ubuntu 서버에서 웹 서비스, Node.js 앱, 로그 저장 경로, 업로드 경로를 만들 때는 명령어 한 줄보다 어디에 만들었는지, 누가 만들었는지, 서비스가 그 폴더를 읽고 쓸 수 있는지가 더 중요합니다.
리눅스를 오래 다루다 보면 처음에는 명령어를 잘못 입력한 문제처럼 보였지만, 실제로는 현재 위치를 착각했거나 root가 만든 폴더를 일반 서비스 계정이 쓰지 못하는 경우가 많습니다. 그래서 폴더를 만들기 전에는 현재 위치와 사용자, 대상 경로의 상태부터 확인하는 편이 안전합니다.
먼저 확인할 핵심 요약
| 확인 항목 | 명령어 | 보는 기준 |
|---|---|---|
| 현재 위치 | pwd |
상대경로로 만들 위치가 맞는지 확인 |
| 현재 사용자 | whoami, id |
폴더를 만들 권한이 있는 계정인지 확인 |
| 대상 경로 상태 | ls -ld 경로 |
이미 디렉터리인지, 파일인지, 없는 경로인지 확인 |
| 상위 경로 권한 | ls -ld 상위경로 |
현재 사용자가 쓰기 권한을 가졌는지 확인 |
| 경로 전체 권한 흐름 | namei -l 경로 |
중간 디렉터리 중 접근이 막히는 곳이 있는지 확인 |
기본 사용법: 현재 위치에 폴더 만들기
가장 기본적인 형태는 현재 디렉터리에 새 폴더를 만드는 것입니다. 다만 운영 서버에서는 상대경로를 쓰기 전에 pwd로 현재 위치를 먼저 확인하는 습관이 필요합니다.
pwd
whoami
mkdir uploads
ls -ld uploads
정상적으로 생성되었다면 출력의 첫 글자가 d로 시작합니다. d는 디렉터리라는 뜻입니다.
drwxr-xr-x 2 deploy deploy 4096 May 12 10:20 uploads
현재 위치를 기준으로 만드는 방식은 빠르지만, SSH로 접속한 뒤 디렉터리를 이동한 사실을 잊으면 엉뚱한 위치에 폴더를 만들 수 있습니다. 운영 서버에서는 가능하면 절대경로를 쓰는 편이 실수를 줄이기 쉽습니다.
절대경로로 폴더 만들기
웹 서비스나 애플리케이션에서 사용할 경로라면 아래처럼 절대경로를 명확히 지정하는 것이 좋습니다.
mkdir /var/www/example.com/uploads
ls -ld /var/www/example.com/uploads
다만 /var/www 아래는 일반 사용자에게 쓰기 권한이 없을 수 있습니다. 이 경우 바로 sudo를 붙이기 전에 상위 경로의 소유자와 권한을 확인합니다.
ls -ld /var/www
ls -ld /var/www/example.com
whoami
id
sudo mkdir를 사용하면 폴더가 만들어지더라도 소유자가 root가 될 가능성이 큽니다. 이 자체가 틀린 것은 아니지만, Node.js 앱이나 웹 서버 프로세스가 파일을 써야 하는 폴더라면 이후 권한 문제가 생길 수 있습니다.
부모 디렉터리까지 함께 만들기: mkdir -p
상위 폴더가 아직 없다면 일반 mkdir는 실패합니다.
mkdir /var/www/example.com/shared/uploads
mkdir: cannot create directory '/var/www/example.com/shared/uploads': No such file or directory
이때는 -p 옵션을 사용하면 중간 경로를 함께 만들 수 있습니다.
mkdir -p /var/www/example.com/shared/uploads
ls -ld /var/www/example.com/shared
ls -ld /var/www/example.com/shared/uploads
mkdir -p는 이미 존재하는 디렉터리에 대해서는 보통 오류 없이 넘어갑니다. 그래서 배포 스크립트나 초기 설정 스크립트에서 자주 사용합니다. 다만 경로를 잘못 적어도 중간 폴더를 그대로 만들어버릴 수 있으므로, 중요한 서버에서는 실행 전에 경로를 한 번 더 확인해야 합니다.
실제 서버 운영 중 헷갈리기 쉬운 지점
1. 만든 사람과 사용하는 사람이 다를 수 있음
터미널에서는 mkdir가 성공했는데 서비스에서는 업로드나 로그 생성이 실패하는 경우가 있습니다. 처음에는 애플리케이션 코드 문제처럼 보이지만, 실제 원인은 폴더 소유자와 실행 사용자가 다른 경우가 많습니다.
예를 들어 SSH에서는 deploy 계정으로 작업했지만, Nginx나 PHP-FPM은 Debian/Ubuntu에서 보통 www-data 계정으로 실행될 수 있습니다. Node.js 앱은 PM2를 실행한 사용자 계정으로 동작하는 경우가 많습니다. 환경에 따라 다르므로 먼저 실제 실행 사용자를 확인해야 합니다.
whoami
ps -eo user,comm,args | grep -E 'nginx|node|php-fpm' | grep -v grep
이 명령은 프로세스 목록을 확인하는 용도입니다. 서비스 이름과 실행 방식은 서버마다 다를 수 있으므로, 보이는 사용자명이 실제로 해당 폴더에 접근해야 하는 계정인지 함께 판단해야 합니다.
2. 상대경로는 현재 위치에 따라 결과가 달라짐
아래 명령은 간단해 보이지만, 현재 위치가 어디냐에 따라 전혀 다른 곳에 폴더가 만들어집니다.
mkdir logs
/home/deploy에서 실행하면 /home/deploy/logs가 만들어지고, /var/www/example.com에서 실행하면 /var/www/example.com/logs가 만들어집니다. 서버 운영 중에는 이 차이 때문에 설정 파일의 경로와 실제 폴더 위치가 어긋나는 일이 자주 생깁니다.
3. sudo로 만들면 root 소유가 될 수 있음
권한 오류가 나면 습관적으로 sudo mkdir를 실행하기 쉽습니다. 하지만 업로드 폴더나 로그 폴더처럼 애플리케이션이 계속 써야 하는 경로라면 root 소유로 만들어진 것이 나중에 문제가 될 수 있습니다.
sudo mkdir -p /var/www/example.com/uploads
ls -ld /var/www/example.com/uploads
drwxr-xr-x 2 root root 4096 May 12 10:30 /var/www/example.com/uploads
이 상태에서 일반 서비스 계정이 파일을 쓰려고 하면 실패할 수 있습니다. 소유자 변경은 서비스에 영향을 줄 수 있으므로, 적용 전에 실제로 어떤 계정이 써야 하는지 확인한 뒤 필요한 범위에만 적용해야 합니다.
처음 의심하기 쉬운 원인과 실제 원인의 차이
| 겉으로 보이는 증상 | 처음 의심하기 쉬운 원인 | 실제로 자주 나오는 원인 |
|---|---|---|
| 폴더를 만들었는데 안 보임 | mkdir 실패 |
다른 현재 위치에서 상대경로로 생성함 |
| 업로드가 실패함 | 애플리케이션 코드 오류 | 폴더 소유자 또는 쓰기 권한 불일치 |
| No such file or directory | 폴더명이 틀림 | 중간 부모 디렉터리가 없음 |
| Permission denied | 명령어 문법 오류 | 현재 사용자에게 상위 경로 쓰기 권한이 없음 |
| File exists | 이미 폴더가 있음 | 같은 이름의 일반 파일이 있거나 기존 디렉터리와 충돌 |
실제로 자주 막히는 상황
상황 1. 웹 업로드 폴더를 만들었지만 저장이 안 됨
예를 들어 웹 애플리케이션에서 /var/www/example.com/uploads에 파일을 저장해야 한다고 가정합니다. 먼저 폴더가 있는지와 소유자를 확인합니다.
ls -ld /var/www/example.com/uploads
namei -l /var/www/example.com/uploads
namei -l는 경로의 각 단계별 권한을 보여주기 때문에, 마지막 폴더만 보는 것보다 원인을 좁히기 쉽습니다. 마지막 폴더 권한은 맞아도 중간의 /var/www/example.com 접근 권한이 막혀 있으면 서비스가 들어가지 못할 수 있습니다.
상황 2. 로그 폴더를 만들었는데 앱이 로그를 못 씀
Node.js 앱이나 백엔드 서비스에서 로그 경로를 따로 둘 때 자주 생깁니다. 폴더는 존재하지만 앱이 실행되는 사용자와 폴더 소유자가 다르면 쓰기 실패가 발생할 수 있습니다.
mkdir -p /var/www/example.com/storage/logs
ls -ld /var/www/example.com/storage/logs
ps -eo user,comm,args | grep node | grep -v grep
PM2로 Node.js 앱을 실행했다면 대개 PM2를 실행한 사용자 권한으로 앱이 동작합니다. 이 경우 root가 만든 로그 폴더에 일반 사용자 앱이 쓰지 못할 수 있습니다. 이 오류를 본 뒤에는 폴더 생성 여부보다 실행 사용자와 소유자를 먼저 확인하는 편이 빠릅니다.
원인 분리 순서
폴더 생성이나 접근 문제가 생기면 아래 순서대로 보면 원인을 빠르게 좁힐 수 있습니다.
pwd로 현재 위치를 확인합니다.whoami,id로 현재 사용자를 확인합니다.ls -ld 대상경로로 이미 존재하는지 확인합니다.ls -ld 상위경로로 부모 디렉터리에 쓰기 권한이 있는지 확인합니다.- 부모 디렉터리가 없다면
mkdir -p사용 여부를 판단합니다. - 서비스가 사용할 폴더라면 실제 실행 사용자와 폴더 소유자를 비교합니다.
- 권한을 바꾸기 전에는 변경 범위가 필요한 경로에만 해당하는지 확인합니다.
잘못된 예시
예시 1. 위치 확인 없이 상대경로로 생성
cd /home/deploy
mkdir uploads
애플리케이션 설정은 /var/www/example.com/uploads를 바라보는데 실제 폴더는 /home/deploy/uploads에 생길 수 있습니다. 이 경우 폴더가 없는 것이 아니라 다른 위치에 만든 것입니다.
예시 2. 권한 문제를 sudo로만 넘김
sudo mkdir -p /var/www/example.com/uploads
ls -ld /var/www/example.com/uploads
drwxr-xr-x 2 root root 4096 May 12 10:40 /var/www/example.com/uploads
생성은 성공했지만, 업로드를 수행하는 서비스 계정이 root가 아니라면 쓰기 실패가 날 수 있습니다. sudo는 생성 권한 문제를 해결할 수 있지만, 서비스 권한 문제까지 자동으로 해결해주지는 않습니다.
예시 3. 이미 같은 이름의 파일이 있음
ls -l /var/www/example.com/uploads
-rw-r--r-- 1 deploy deploy 0 May 12 10:45 /var/www/example.com/uploads
첫 글자가 -이면 디렉터리가 아니라 일반 파일입니다. 이 상태에서는 같은 이름의 폴더를 만들 수 없습니다.
mkdir /var/www/example.com/uploads
mkdir: cannot create directory '/var/www/example.com/uploads': File exists
이 경우에는 파일이 왜 그 이름으로 존재하는지 먼저 확인해야 합니다. 운영 서버에서는 파일을 바로 삭제하거나 덮어쓰기보다, 해당 파일이 서비스에서 사용 중인지 확인한 뒤 이름 변경이나 경로 수정 여부를 판단해야 합니다.
수정 예시
예시 1. 업로드 폴더를 안전하게 만들기
아래 예시는 Debian/Ubuntu 계열 서버에서 웹 애플리케이션의 업로드 폴더를 준비하는 흐름입니다. 실제 경로와 서비스 사용자는 환경에 맞게 바꿔야 합니다.
pwd
whoami
ls -ld /var/www/example.com
ls -ld /var/www/example.com/uploads
대상 폴더가 없고, 상위 경로가 맞는 것을 확인했다면 폴더를 만듭니다.
sudo mkdir -p /var/www/example.com/uploads
ls -ld /var/www/example.com/uploads
만약 해당 폴더를 www-data가 써야 하는 구조라면, 먼저 실제 웹 서버 또는 애플리케이션 실행 사용자가 www-data인지 확인합니다.
ps -eo user,comm,args | grep -E 'nginx|php-fpm' | grep -v grep
확인 결과 해당 서비스가 www-data로 동작하고, 이 폴더를 쓰는 것이 맞다면 소유자를 필요한 경로에만 변경할 수 있습니다.
sudo chown www-data:www-data /var/www/example.com/uploads
sudo chmod 750 /var/www/example.com/uploads
ls -ld /var/www/example.com/uploads
chown과 chmod는 서비스 접근에 영향을 줄 수 있습니다. 특히 기존 파일이 많은 경로에 재귀 옵션을 적용하면 의도하지 않은 권한 변경이 생길 수 있으므로, 처음에는 새로 만든 폴더처럼 범위가 명확한 곳에만 적용하는 편이 안전합니다.
예시 2. Node.js 앱 로그 폴더 만들기
Node.js 앱을 일반 사용자 deploy로 실행한다면 로그 폴더도 같은 사용자가 쓸 수 있어야 합니다. 먼저 실행 중인 사용자와 경로를 확인합니다.
whoami
ps -eo user,comm,args | grep node | grep -v grep
ls -ld /var/www/example.com/storage
상위 경로가 맞고 새 로그 폴더가 필요하다면 생성합니다.
sudo mkdir -p /var/www/example.com/storage/logs
sudo chown deploy:deploy /var/www/example.com/storage/logs
ls -ld /var/www/example.com/storage/logs
이 예시의 deploy는 예시 사용자입니다. 실제 서버에서는 앱을 실행하는 계정이 다를 수 있으므로, ps, PM2 상태, 서비스 설정 등을 확인한 뒤 적용해야 합니다.
수정 후 확인 방법
폴더를 만든 뒤에는 생성 여부만 보지 말고, 타입, 소유자, 권한, 실제 쓰기 가능 여부를 확인합니다.
ls -ld /var/www/example.com/uploads
stat /var/www/example.com/uploads
namei -l /var/www/example.com/uploads
stat는 권한과 소유자 정보를 자세히 보여줍니다. namei -l는 경로의 중간 디렉터리 권한까지 확인할 수 있어, 웹 서버 403 오류나 업로드 실패 원인을 찾을 때 도움이 됩니다.
서비스가 실제로 파일을 쓸 수 있는지 확인해야 한다면, 임의로 운영 데이터를 건드리지 말고 테스트용 파일을 만드는 방식으로 확인합니다. 다만 아래 명령은 파일을 생성하므로, 테스트가 가능한 경로에서만 실행해야 합니다.
sudo -u www-data touch /var/www/example.com/uploads/.write-test
ls -l /var/www/example.com/uploads/.write-test
확인이 끝난 테스트 파일은 삭제해도 되지만, 운영 서버에서 파일 삭제 명령을 사용할 때는 경로를 반드시 확인해야 합니다. 삭제가 부담스럽다면 테스트 파일을 남겨두지 않는 별도 임시 경로에서 점검하는 방법도 있습니다.
mkdir 관련 오류 메시지별 판단 기준
| 오류 메시지 | 의미 | 확인할 것 |
|---|---|---|
No such file or directory |
중간 부모 경로가 없음 | ls -ld 상위경로, 필요 시 mkdir -p |
Permission denied |
현재 사용자에게 생성 권한이 없음 | whoami, id, 상위 경로 권한 |
File exists |
같은 이름이 이미 존재함 | ls -ld 경로로 파일인지 디렉터리인지 확인 |
Not a directory |
경로 중간에 디렉터리가 아닌 파일이 있음 | namei -l 경로로 어느 단계가 파일인지 확인 |
재발 방지 체크리스트
- 상대경로로 만들기 전에
pwd를 확인했다. - 운영 경로는 가능하면 절대경로로 입력했다.
mkdir -p를 쓰기 전에 경로 오타가 없는지 확인했다.- 대상 경로가 이미 파일로 존재하지 않는지
ls -ld로 확인했다. - 현재 사용자와 서비스 실행 사용자가 같은지 확인했다.
sudo mkdir후 소유자가root로 남아도 되는 경로인지 판단했다.- 권한 변경은 필요한 폴더에만 제한해서 적용했다.
- 업로드나 로그 경로는 실제 서비스가 읽고 쓸 수 있는지 테스트했다.
- Nginx, PHP-FPM, Node.js, PM2 등 서비스 계정은 서버 환경마다 다를 수 있음을 고려했다.
마무리
mkdir로 폴더 만드는 방법은 명령어만 보면 어렵지 않습니다. 그러나 서버 운영에서는 폴더 생성보다 경로 확인, 사용자 확인, 소유자와 권한 확인이 더 중요할 때가 많습니다. 특히 웹 업로드 경로와 로그 경로는 만들고 끝나는 작업이 아니라, 실제 서비스가 접근할 수 있는지까지 확인해야 문제가 반복되지 않습니다.
FAQ
Q1. mkdir과 mkdir -p는 언제 구분해서 써야 하나요?
부모 디렉터리가 이미 있고 마지막 폴더만 만들면 될 때는 mkdir 폴더명을 사용하면 됩니다. 중간 경로가 없을 수 있거나 배포 스크립트처럼 여러 단계 경로를 한 번에 준비해야 한다면 mkdir -p 경로를 사용할 수 있습니다. 다만 -p는 경로 오타가 있어도 중간 폴더를 만들어버릴 수 있으므로 운영 서버에서는 실행 전 경로를 확인하는 것이 좋습니다.
Q2. Permission denied가 나오면 sudo를 붙이면 되나요?
폴더 생성 자체는 sudo로 해결될 수 있습니다. 하지만 sudo로 만든 폴더는 소유자가 root가 될 수 있어, 웹 서버나 애플리케이션이 나중에 파일을 쓰지 못할 수 있습니다. 먼저 whoami, id, ls -ld 상위경로로 현재 사용자와 권한을 확인한 뒤, 정말 관리자 권한이 필요한 위치인지 판단해야 합니다.
Q3. 폴더는 있는데 애플리케이션이 파일을 저장하지 못하는 이유는 무엇인가요?
폴더 존재 여부와 쓰기 가능 여부는 별개입니다. 애플리케이션이 실행되는 사용자와 폴더 소유자가 다르거나, 중간 디렉터리 접근 권한이 막혀 있으면 저장이 실패할 수 있습니다. ls -ld 경로, namei -l 경로, ps -eo user,comm,args로 폴더 권한과 서비스 실행 사용자를 함께 확인하는 것이 좋습니다.