All posts

Deploy your project, with or without GitHub

· Marina

Two things used to stop a project deploying here. It had to be on GitHub, and if it was PHP it needed a Dockerfile first. Both are gone.

Two ways in

Create a vessel and pick your source. Connect GitHub and choose the repository, or drop the project folder straight in.

Everything after that point is identical. Same detection, same build, same address at the end. Uploading is not a lesser path, it is the same path fed from a folder instead of a checkout.

That matters more than it sounds. A lot of working software is not on GitHub: a folder a client sent you, a site that has been running on shared hosting for years, work you have not pushed anywhere yet. None of that should need a git lesson before it can go live.

It works out what to build

Marina reads your project the way you would expect. composer.json or index.php is PHP. An artisan file means Laravel, so it serves from public/ where Laravel expects. package.json means Node, and your assets get built. Go, Python and the rest are recognised the same way.

A Dockerfile beats all of it. If your project has one, you own the runtime, which is the point of shipping one.

If you would rather declare than be detected, add a marina.toml with your start command. It works the same in an uploaded folder as in a repo.

Laravel, specifically

Most of what makes a Laravel deploy fail on a generic host is small and specific, so Marina handles it.

The app key. Laravel refuses to boot without one. Marina generates it when the app is created and then never touches it again. Rotating an app key makes every encrypted column, signed URL and session your app has already written unreadable, so it is generated once and left alone. If your project already sets its own, that one is kept.

Migrations. They run on every deploy by default, which is what makes the first deploy of a fresh app work without you configuring anything. There is a switch on the deploy tab when you would rather run them yourself.

The database connection. Laravel does not read DATABASE_URL. It reads DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME and DB_PASSWORD, and if it cannot find them it quietly tries 127.0.0.1 and fails. So attaching Postgres or MySQL injects that whole set, with the driver name Laravel wants. Attach Redis and you get REDIS_HOST and REDIS_PORT for cache and queues.

Managed SQLite is the exception. Ours is reached over HTTPS with a token, and Laravel’s SQLite driver wants a file on disk, so pair Laravel with Postgres or MySQL.

Running a command

There is a console on the deploy tab. Type php artisan migrate --force, or a cache clear, or composer show to see what actually got installed, and the output comes back to you. It runs inside your own app, as your app, so it can do nothing you could not already do by deploying code.

A command that runs and fails still shows you its output and its exit code. That output is the entire reason you ran it.

Updating it

A connected repo redeploys when you push to your default branch. An uploaded project redeploys when you upload it again. Either way the address stays the same.