Docker
Note very loudly that additional Docker options should be set in the .env
file, and they can require a full container rebuild!
NOTICE:
The ONLY docker image we support is
snipe/snipe-it
. If you grabbed a docker image from any other repo, you're kinda on your own, since we cannot be responsible for images we do not manage directly.
About this article
Docker is a very popular software containerization platform. While it's not difficult to use, it can be a little confusing for folks who are less familiar with containerization.
We'll attempt to walk you through the Docker Compose setup here, but please see the Docker documentation for a more in-depth understanding of Docker fundamentals. If you don't know the implications of the steps you're taking here, you could potentially lose access to your data.
No hand-holding for installing Docker
This guide will not go into details about how to install Docker and Docker Compose. Make sure you have both before moving forward.
Prep work
The easiest way to get started with Snipe-IT on Docker is to use the Docker Compose file we provide on our GitHub repository it uses the official docker image we push to Docker Hub.
Follow the steps below to get started.
Create work environment
Go to a desired location on your system, where you want to run Snipe-IT and create an empty folder, called snipeit
and go inside. The folder name is used by Docker Compose as a prefix for the container names. (ex. "snipeit-SERVICENAME-1") So no one is stopping you from naming it differently, but it is for your own sanity.
mkdir snipeit
cd snipeit
Download files
Download the docker-compose.yml
and .env
files. In some instances it might be easier to just copy and paste the content to where you want it.
curl https://raw.githubusercontent.com/snipe/snipe-it/master/docker-compose.yml --output docker-compose.yml
curl https://raw.githubusercontent.com/snipe/snipe-it/master/.env.docker --output .env
Adjust deployment settings
Pulling back the curtain
It is recommended to leave the
docker-compose.yml
alone, if you are unsure what you are doing. Go ham if you know your stuff or have been told so, to add additional features. (ex. reverse proxy)
For the applications to know where their stuff is, we have to do set some settings in .env
. So go ahead and open it up with your favorite text editor. (Nano, Vi, VSCode, ...)
Don't get overwhelmed by the amount of settings, most are optional and are not needed to get the ball rolling. All sections have been labeled accordingly what they do. The important ones start with REQUIERED:
. Most of them already have values set, but please make sure you at least change your passwords!
Some Environment Variables Explained
Some of these might be confusing from just the name alone, so we will go into detail about them here. If you still have questions, feel free to reach out to our community on Discord or GitHub.
APP_VERSION
Doesn't exist yet
This article was written prior to changes the
.env
. Please adjust the version manually indocker-compose.yml
.
Example:image: snipe/snipe-it:v6.3.4
For a list of all available Docker version tags, check out the tags page on Dockerhub. This has to be manually changed, when a new version releases.
Footgun "latest" - tag
It is never recommended to use any "latest" tag for any app.
Latest tags can cause issues, when you are trying to restore your application. You will not know what version you have been running all this time and might cause issues as your volume-data was not made for that version, or you have to read up on all breaking changed until the new version.
Docker will default to latest if you leave this empty!
APP_KEY
You can get an app-key by running the following command.
docker compose run --rm app php artisan key:generate --show
APP_URL
The URL which the users later use to access your Snipe-IT installation. By default, port 8000 is getting exposed.
APP_TRUSTED_PROXIES
This is needed, when you are running Snipe-IT behind a (reverse) proxy. Because this requires an IP and containers getting IPs by the DHCP, it is recommended to use an entire /8 network (ex. "172.0.0.0/8"), as individual IPs can change.
Deploy!
Once you have set everything in your.env
, it is time to launch it.
docker compose up -d
If you don't get any errors. That's it... What? Did you expect more work? But in the case you run into startup issues, head over to the Troubleshooting section further down this article.
Made Changes?
If you changed your
docker-compose.yml
and/or.env
, make sure to run the command again, so Docker Compose can recreate the containers. Your data should be safe, if the volumes have not been tinkered with.
Maintenance
All commands have to be run inside the snipeit
-folder, which has the docker-compose.yml
.
Get folder
In case you forgor where you left your configuration files, you can get a list of the compose-files by running the ls
command:
docker compose ls
Container status
Checkup on the different parts of the deployment to see if everything is running fine.
docker compose ps -a
-a
additionally shows stopped containers.
Show logs
Show the chitchat of your apps.
docker compose logs -f
You can also add the service name (ex. "app") to the command, so it only displays for that one container.
Stop Snipe
Stopping the containers will not remove them. Generally it is recommended to use the down
command instead.
docker compose stop
To start it back up run the deployment command above again.
Delete Deployment
There are two types of deletion. In most cases you need the first one.
Remove deployment
docker compose down
This will delete everything except the volumes, which hold your application data.
Delete EVERYTHING
There is no afterlife. It just goes black.
The command will not ask! Once you run this, it will snap your snipe-it deployment - including your volume data - out of existence!
docker compose down -v
Legacy Articles Below
We are currently rewriting this article. The below information could be outdated.
Docker's Environment Variables
Snipe-IT's Docker configuration requires many different environment variables in order to function correctly. To keep things simple, we try to centralize all of those settings in an environment file. If you are using a method other than the standard docker CLI to integrate Snipe-IT into your docker environment, then you will need to make sure to pass all of the below mentioned variables into your Snipe-IT environment.
You can call this file anything you want, and put it wherever you like, just remember what you called it and where you put it, since you'll need to reference this file when you run your Docker containers, using the --env-file=<your_docker_env_file_name>
argument. You'll see examples of this in the commands further down the page as you initialize your Docker container.
For the purposes of this documentation, we'll call our file my_env_file
.
The data for your MySQL container will live in the named volume snipesql-vol
. Docker will create this volume for you if it does not exist already.
WARNING:
Newer MySQL containers (5.7 and later, or MariaDB) may run in strict-mode by default, and the initial migrations and application setup will fail in strict mode. If you want to use one of those versions, you need to disable strict mode first!
That should set you up with your database to use. (You can also specify environment variables on the command-line instead of the env-file, but that can get very clunky very quickly; see docker run --help
for details)
Using a Standalone Database (not a container)
If you're using a separate, standalone database, you can specify the hostname as MYSQL_PORT_3306_TCP_ADDR
. If your database runs on a different port, you can specify that with MYSQL_PORT_3306_TCP_PORT
. You don't need to specify the MYSQL_ROOT_PASSWORD
.
Thus, your config should look as follows:
# Mysql Parameters
MYSQL_PORT_3306_TCP_ADDR=XXX.XXX.XXX.XXX
MYSQL_PORT_3306_TCP_PORT=3306
MYSQL_DATABASE=snipe_it
MYSQL_USER=snipe_it_db_user
MYSQL_PASSWORD=snipe_it_db_user_password
NOTE:
If your Email solution requires its own container, start that container or service. Make sure to expose port 587 for mail submission, and use
--link mail:...
.
Finally, decide whether or not you want to have your Snipe-IT container manage SSL for you, or not.
As a side-note, if you're running boot2docker or docker-machine, you may need to prefix the port declarations below with an IP address - $(docker-machine ip default):
or 123.45.78.89:
SSL disabled
Start your Snipe-IT container:
If you pulled the image with exact version number tag than you need to apply here as well of course.
Start with the latest version:
docker run -d -p YOUR_PORT_NUMBER:80 --name="snipeit" --link snipe-mysql:mysql --env-file=my_env_file --mount source=snipe-vol,dst=/var/lib/snipeit snipe/snipe-it
The 'named volume' snipe-vol
will be created if it does not already exist.
Version specific start:
docker run -d -p YOUR_PORT_NUMBER:80 --name="snipeit" --link snipe-mysql:mysql --env-file=my_env_file --mount source=snipe-vol,dst=/var/lib/snipeit snipe/snipe-it:v.4.1.13
SSL enabled
Start your Snipe-IT container - but be prepared to copy your SSL key and certificate to your storage volume. When you first launch the Snipe-IT container, the named volume snipe-vol
will be created and initialized. You can use the docker cp
command to copy your certificate data to the storage volume, at /var/lib/snipeit/ssl/snipeit-ssl.crt
and /var/lib/snipeit/ssl/snipeit-ssl.key
.
docker run -d -p YOUR_PORT_NUMBER:80 -p YOUR_SSL_PORT:443 --name="snipeit" --link snipe-mysql:mysql --mount source=snipe-vol,dst=/var/lib/snipeit --env-file=my_env_file snipe/snipe-it
Version specific start with SSL
docker run -d -p YOUR_PORT_NUMBER:80 -p YOUR_SSL_PORT:443 --name="snipeit" --link snipe-mysql:mysql --mount source=snipe-vol,dst=/var/lib/snipeit --env-file=my_env_file snipe/snipe-it:v4.1.13
Email, Management, Access
If you have a separate container running for email, you will also want a --link
setting for email as well.
That's It!
You can now initialize the application and database by pointing your web browser to: http://your_ip:YOUR_PORT
, which will automatically redirect you to the setup screen.
Updating Snipe-IT or MySQL
To upgrade your Snipe-IT installation, you should stop your old container, re-pull the latest Snipe-IT version, then launch the new container as before, but connecting to the same storage volume - named snipe-vol
in our examples. You will have to rename your old container to be able to reuse the 'snipeit' name.
After that, you may need to run migrations using docker run snipeit php artisan migrate
.
Once you're completely sure that everything on your new installation is working, you may delete the old Snipe-IT container.
To upgrade MySQL, stop your old container, pull whatever new version you want to switch to, and make sure to run your new container with the same named volume - we called it snipesql-vol
in our examples.
Hosting Snipe-IT and MySQL on Azure
Azure Web Apps can host Docker containers, using Azure Storage for their instance data, and MySQL is available as managed service on Azure. So Azure can be used to host a private instance of Snipe-IT.
A Terraform module to provision the entire infrastructure in Azure is available here: https://registry.terraform.io/modules/rodchristiansen/snipeit/azurerm/latest
Create an Azure MySQL PaaS instance
- In the Azure Portal, create a new 'Azure Database for MySQL flexible server' resource in a new resource group
- Provide a name for the instance
- Set your region
- Workload Type - can use the lowest 'for development or hobby projects'
- Set the MySQL username and password
- For networking pick 'allow public access' and 'allow public access for any Azure service'
You can add your Client IP address to the firewall rules if you want to be able to connect to the DB from your local machine, but this is not essential. I had enabled this to do some testing with a locally hosted Docker instance.
- When the instance is created open it in the Azure Portal
- Go to the Networking tab and download the SSL certificate
DigiCertGlobalRootCA.crt.pem
(you need it later) - Go to the Database tab and create a new empty DB
snipe-it
with default settings.
- Go to the Networking tab and download the SSL certificate
Create an Azure Storage Account
- Open the Azure Portal, create a new 'Storage Account' in same resource group as used for the MySQL
- Provide a name for the instance
- Set your region
- For networking pick 'allow public access'
- When the resource is created open it in the Azure Portal
- In storage explorer create a new
File Share
calledsnipeit
- Upload the SSL Cert
DigiCertGlobalRootCA.crt.pem
to this share - In storage explorer create a new
File Share
calledsnipeit-logs
Create an Azure Web App
-
Open the Azure Portal, create a new 'Web App' in same resource group as used for the MySQL
- Provide a name for the instance
- Pick the publish type to be
Docker Container
- Set your region
- Create a pricing tier, Linux
Basic B1
can be used - For Docker settings picked the follow (though we override these later with a compose file)
- Single Container
- Docker Hub
- With the image name
snipe/snipe-it:latest
(or can pick a specific version)
-
When the resource is created open it in the Azure Portal
-
In the configuration
Path Mappings
add a new Azure Storage Mount for the cert and other local storage- Name -
snipeit
- Mount Path -
/var/lib/snipeit
- Type -
Azure Files
using the previously created file share
- Name -
-
In the configuration
Path Mappings
add a new Azure Storage Mount for the logs- Name -
snipeit-logs
- Mount Path -
/var/www/html/storage/logs
- Type -
Azure Files
using the previously created file share
- Name -
-
In the configuration
Application Settings
I added the following newApplication Settings
MYSQL_DATABASE
-snipeit
matching the MySQL DB nameMYSQL_USER
to the username for the MySQL instanceMYSQL_PASSWORD
to the password for the MySQL instanceDB_CONNECTION
tomysql
MYSQL_PORT_3306_TCP_ADDR
to the name of the MySQL instance<my-instance>.mysql.database.azure.com
MYSQL_PORT_3306_TCP_PORT
to3306
DB_SSL_IS_PAAS
totrue
DB_SSL
totrue
DB_SSL_CA_PATH
to/var/lib/snipeit/DigiCertGlobalRootCA.crt.pem
matching the path to the SSL certAPP_URL
to the URL of the Web Apphttps://<my-instance>.azurewebsites.net
APP_KEY
to a unique ID in the formbase64:6M3RwWh4re1FQGMTent3hON9D7ZJJDHxW1123456789=
. If you don't set this and start the container, whilst watching the log stream, you will see the new key generated which you can useMAIL_DRIVER
tosmtp
MAIL_ENV_ENCRYPTION
totcp
MAIL_PORT_587_TCP_ADDR
tosmtp.sendgrid.net
MAIL_PORT_587_TCP_PORT
to587
MAIL_ENV_USERNAME
toapikey
MAIL_ENV_PASSWORD
your SendGrid API KeyMAIL_ENV_FROM_ADDR
to the email SNipe IT notifications should come fromMAIL_ENV_FROM_NAME
toSnipe IT
or whatever you want the email to be from- You can also set the
APP_DEBUG
totrue
orfalse
. Iftrue
this means more detailed error messages are shown in the Snipe-IT UI that do not appear in the log stream
-
In the deployment center pick
Docker Compose
and provided the follow config to mount the storageversion: "3" services: snipe-it: image: snipe/snipe-it:latest volumes: - snipeit:/var/lib/snipeit - snipeit-logs:/var/www/html/storage/logs volumes: snipeit: external: true snipeit-logs: external: true
-
Restart your Web App
-
And that should be it, the container should start and you should be able to access the Snipe-IT UI based setup Wizard via the URL of the Web App, as per the standard configuration process for Snipe-IT
Comments & Tips
MySQL SSL Certificate not found
If the MySQL SLL Certificate cannot be found for any reason, such as an incorrect path or missing volume mount, you get the same error message in the Snipe-IT UI
SQLSTATE[HY000] [2002] (trying to connect via (null)) (SQL: select * from information_schema.tables where table_schema = snipeit and table_name = migrations and table_type = 'BASE TABLE')
There was nothing more useful in the Web App Log Stream (the container output). The best option is to set the ENV setting APP_DEBUG
to true
. After which more useful error messages can be seen in the UI logs
MySQL Initial Migration Failing
If you get the following error in the UI when the container is trying to create the DB Tables
SQLSTATE[42000] Syntax error or access violation 1068 Multiple primary key defined
It is because the MySQL instance has incorrect server parameters set. The fix was to set the following three MySQL Server Parameters, in MySQL instance via the Azure Portal, to OFF
innodb_buffer_pool_load_at_startup
innodb_buffer_pool_dump_at_shutdown
sql_generate_invisible_primary_key
I have no idea why my first Azure MySQL instance had these values set to OFF
and my other instances had them set to on ON
. I guess I am lucky at least one was set to OFF
so I could work out what was wrong.
ADVANCED docker usage
WARNING! Advanced users ONLY!
These are all advanced features of Docker. Please only use them if you are already extremely knowledgeable about how to use Docker.
Bind Mounts
Instead of using named volumes, as above, you may instead use a 'bind mount' to point to a local directory. This was an older method that Snipe-IT's docker integration used, but Docker no longer recommends it.
If you need that feature for whatever reason, you should pass the fully-qualified path (absolute path) instead of the named volume in the various above commands.
Specifically, the mount
parameter in your command-lines should look something like this:
--mount source=/full/path/to/your/snipe-directory/,dst=/var/lib/snipeit
You may need to create various folders in that directory. See the Dockerfile and the /entrypoint.sh files for specific details.
Behind a SSL / HSTS reverse proxy
If your container is setup behind a trusted reverse proxy (such as nginx) and HSTS is active, you'll need to pass a few more parameters for Snipe-It to work. Add to your .env
file at least the following lines:
APP_TRUSTED_PROXIES=REMOTE_ADDR
SECURE_COOKIES=true
For Development
You can build the snipe-it image using the Dockerfile
at the root directory of Snipe-IT by doing this:
docker build -t snipe-it .
Then you can use your newly built image as snipe-it
When you call docker run
- make sure to mount your own snipe-it directory over the /var/www/html
directory. Something like:
docker run -d -v /Path/To/My/snipe-it/checkout:/var/www/html -P --name="snipeit" --link mysql:mysql snipeit
Then your local changes to the code will be reflected. You will have to re-run composer install
-
docker exec -i -t snipeit composer install
And you may still need to generate the key with -
docker exec -i -t snipeit php artisan key:generate --env=production
While you're developing, you may need to occasionally run:
docker exec snipeit composer dump
To fix the autoloading cache (if, for example, your class names change, or you add new ones...)
Updated about 1 month ago