Use the platform your team can maintain
A good pipeline runs the same checks for every change and produces a release you can identify and roll back. For a bot, deployment also needs to manage a long-lived Discord connection.
GitHub Actions
GitLab CI/CD
Jenkins
Start with checks that need no live bot token
Install from a lockfile, run the project’s checks, and compile the code. Test permission checks, database changes, and duplicate event handling with fixtures. Pull requests should not need production credentials.
This example assumes those scripts exist in your package file. Match the Node version to production. For deployment workflows, pin third-party actions to reviewed commit SHAs and review updates deliberately.
Keep building and deploying separate
Build one release artifact
Use an image tag or artifact tied to the commit. Deploy that same artifact after checks pass, instead of rebuilding an unknown version on the host.Allow one deployment at a time
Use a deployment lock or CI concurrency control. A second release should not interrupt the first halfway through a restart or database migration.Hand over the bot process
Stop or drain the old worker before its replacement takes ownership of the same shard. Give the old process time to close connections and finish safe work.Verify and keep a rollback
Check the release identifier, Gateway readiness, and a test command. Keep the previous artifact, and ensure any database changes allow the older code to run.
Protect the deployment path
- Keep the Discord token in the host or platform secret store.
- Give CI only the access needed to publish or deploy the artifact.
- Do not expose production secrets to untrusted pull request code.
- Avoid printing environment variables or token-bearing URLs in logs.
- Use a separate test application and server for integration checks.
If you need a repeatable package first, use Docker. As your bot grows, the scaling guide covers separating Gateway workers from slower jobs.