Skip to content

Prepare Your Project

How to Manage Deployed Projects

There are 3 popular ways to manage deployed projects on servers (managing means restarting apps/services after a crash or reboot, and updating/reloading after you push changes):

  1. Using containers with auto-generated config files based on your runtime (Nixpacks + Docker).
  2. Using containers with manually created config files (Dockerfile + Docker).
  3. Without containers, where your services are managed by systemd that comes with Linux.

If you’re not familiar with Dockerfiles and your repo doesn’t have one yet, the easiest way to start is by using Nixpacks (option 1) or systemd (option 3, especially if you’re deploying a binary file or a Node.js project). In this chapter, we’ll explore all three options and what you need to do to prepare your project for deployment.

Installing Docker and Nixpacks Locally

Before you start preparing for deployment, it’s a good idea to install the tools you plan to use on your server, locally. You can skip this step, but it’ll slow things down as you’d need to upload files to the server every time you want to test a configuration change.

Here are the installation guides for different operating systems:

  • Docker (if you’re using systemd, you don’t need Docker locally)
  • Nixpacks (if you’re using systemd, you don’t need Nixpacks locally)

Deploying with Nixpacks and Docker

Nixpacks is a tool that scans your source code folder and automatically creates containers based on it. You don’t need to know much about Docker or containers—Nixpacks handles the configuration. However, it doesn’t work perfectly for all projects. If it fails, you can either create a Dockerfile manually (option 2) or use systemd (option 3).

Here’s how to check if Nixpacks can create a container for your project (make sure Docker and Nixpacks are installed locally):

  • Change the directory to your project folder:
cd project_name
  • Generate a container with Nixpacks:
nixpacks build . —name some-app-name
  • Run the container:
docker run -it some-app-name
  • Open your app in a browser or send a request by visiting something like http://localhost:app_port.

If it works—great! It means Nixpacks works with your project, and you’re ready for deployment, which we’ll cover in the "Deployment from a Local Machine" and "Deployment from GitHub, Bitbucket, and GitLab" chapters.

If you get an error, don’t worry—you still have two options: 1. Create a Dockerfile manually using our examples or by searching for "Node.js Dockerfile," "PHP Dockerfile," etc. 2. Use systemd instead.

Pro Tip: Nixpacks can also generate a Dockerfile without creating a container. Just run the following command in your project folder:

nixpacks build . -o . The Dockerfile will be saved in project_folder/.nixpacks.

Deploying with Docker and Dockerfile/Docker Compose

This method assumes you already have a Dockerfile or Docker Compose file for your project (many open-source projects include these files). A Dockerfile is basically a list of instructions for building a container. If you don’t have one yet, you can easily find examples for your runtime (e.g., "Node.js Dockerfile," "Golang Dockerfile") and adapt them to your project. It’s simpler than it seems—just check a few examples to get started.

Before deploying, place your Dockerfile in your project folder and update any file paths inside it if needed.

Deploying with systemd

If don't want to use containers, all you need to do is create a bash script that starts your app/service—just like you would manually in the terminal. This option is resource-efficient and great for smaller setups, but keep in mind that your projects will share a non-isolated environment. This poses a security risk because if one project gets compromised, the attacker could potentially access all other projects on the server. Docker containers reduce this risk by isolating apps/services but require more resources and technical knowledge.

For most projects, your systemd startup script will only need one command. For example, for a simple Go project:

#!/bin/sh
go run .

Or if you’re deploying a binary file:

#!/bin/sh
chmod +x my_service
./my_service

Avoid putting any long-running commands (like tool installations) in this script because it’ll be executed during every deployment, which could slow things down. Once your script is ready, save it in the project folder or wherever your executable file is located. Your app/service is now ready for deployment, and you can move on to the next chapter.