How to Install Statamic on Ubuntu

A full walk-through for installing, configuring and running Statamic on an Ubuntu server, perfect for production use.


To install Statamic on an Ubuntu instance you will need the following:

  • An Ubuntu 22.04 or 20.04 VPS with root access enabled or a user with Sudo privileges (you can follow our Digital Ocean or Linode guides to get yours set up)
  • A server with at least 1GB memory
  • A valid domain name pointed to your server and SSL certificate in place
  • PHP 8.1+

Update Packages

If this is the first time using apt in this session, you should sure package lists and installed packages are up to date.

sudo apt-get update
sudo apt-get upgrade

Install PHP & Required Modules

sudo apt install php-common php-fpm php-json php-mbstring zip unzip php-zip php-cli php-xml php-tokenizer php-curl -y

Install Composer

Install Composer with the following command:

curl -sS | php

Next, you need to move the composer.phar file to a globally accessible directory and update its permissions.

sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer

Now you can check to make sure Composer is installed and configured correctly by running this command:


Create a new Statamic Application

Now we'll create a new Statamic application using the composer create-project command.

First, navigate to the /var/www directory:

cd /var/www

Next, run the following install command:

composer create-project --prefer-dist statamic/statamic
Hot Tip!

Alternatively, you could git clone an existing project instead of installing a new empty site.

Set Permissions

Once Statamic is installed, you'll need to grant appropriate permissions to the non-root user so Statamic and Laravel can write to the necessary system directories.

sudo chmod -R 755 /var/www/
sudo chown -R www-data:www-data /var/www/
sudo chown -R www-data:www-data /var/www/
sudo chown -R www-data:www-data /var/www/
sudo chown -R www-data:www-data /var/www/

Install & Configure Nginx

Next, install Nginx with the following command:

sudo apt install nginx -y

After the install completes, Nginx will start automatically. You can verify the service by running the following the command:

sudo systemctl status nginx

Next, let's set up the minimum recommended config file to serve your site. Create a new file with vim (or your command line editor of choice) at /etc/nginx/sites-available/, making sure to replace everywhere with your desired domain.

server {
listen 80;
root /var/www/;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
index index.html index.htm index.php;
charset utf-8;
set $try_location @static;
if ($request_method != GET) {
set $try_location @not_static;
if ($args ~* "live-preview=(.*)") {
set $try_location @not_static;
location / {
try_files $uri $try_location;
location @static {
try_files /static${uri}_$args.html $uri $uri/ /index.php?$args;
location @not_static {
try_files $uri /index.php?$args;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
location ~ /\.(?!well-known).* {
deny all;

You can confirm that the configuration doesn’t contain any syntax errors with the following command:

sudo nginx -t

You should see output similar to this:

# Output
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Time to reload Nginx and apply these changes:

sudo systemctl reload nginx

Now visit your IP Address or (but like the actual domain) if you've pointed your domain's A Record and you should see the Statamic landing page.

The Statamic Welcome Page
If you see this, you have just won.


That's pretty much it. Time for you to take it from here.

If this is your production server, you'll probably want to add cache expiry headers and so on, but those rules and what you cache to the browser are all up to you.

Docs feedback

Submit improvements, related content, or suggestions through Github.

Betterify this page →